home *** CD-ROM | disk | FTP | other *** search
- /*
-
- The following is my version of a tape backup program for windows nt
-
- It was written because ntbackup fails on my gigatrend 1200 data drive, but
- the driver I wrote for it passes the hardware compat. test fine.
-
- The software allows you to backup/restore savesets to tape (50 savesets max).
- It also allows you to list the tape/and or saveset contents and backup/restore
- by wildcard ie *dirname* etc. I have implemented compression utilizing a
- modified version of gnu zip but on my dat even with a 100K threshold for
- zip it takes long and more tape so the compression by default is
- disabled unless you specify the -c option. for a list of options run lkbackup -h
-
- The tape drive used by the backup program must have an nt driver and
- support the following functions:
-
- 1. Writefile/readfile for reading writing to tape
-
- 2. it must be device tape0 (ie the first tape device in the system although
- this can be changed in the source code)
-
- 3. it must support either filemarks or setmarks (default is filemarks
- use -s option for setmarks).
-
- 4. it must support spacing to end of data and filemark/setmark +/-
- spacing
-
- 5. it must support scsi data block aka relative blocking/spacing (it
- doesn't use absolute or logical blocking).
-
- 6. it must support the load/unload/rewind tape apis in win32.
-
- 7. You must have your temp variable set since this is where the
- zipped/unzipped files are temporarily kept, and there must be enouge space for the
- largest of your files (and about 30 of them if using compression).
-
-
- The program is multi-threaded in that one thread tries to compress ahead of
- the thread writting to tape up to 30 files. This improved performance but
- uncompressed still works better on my drive. Try it and let me know your
- results. Anyway I have left the multi-threading in since with faster machines
- or multi-processor machines in the future it will improve perforamce.
-
- The source code is also provided and can be used and modified provided
- you send me the modified code with a note about what you are doing.
- Also the code cannot be used in a for sale produce without first contacting
- me for permission.
-
- Good luck
-
- Larry Kahn 10/27/93
- [71534.600] on compuserve
- Kahn@drcvax.af.mil on internet
- 919-630-0412 by phone
- 919-630-0722 by fax when nt finally gets fax support
-
- */
-
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <io.h>
- #include <time.h>
- #include <process.h>
- #include <string.h>
- #include <direct.h>
- #include <errno.h>
-
- /* these are the tape functions for my dat drive */
- /* lgk use the modified gnu zip compression routines were modifed to provide c level interface
- so that we dont need to overhead of a system call */
-
- struct _TAPE_SET_MEDIA_PARAMETERS tparms;
-
-
- #define max_save_sets 50
- #define save_sets_per_block 10
- #define blocks_per_header 5
- #define bsize1 4096
- const int blocksize = bsize1;
- DWORD buffersize = bsize1;
- const int headersize = 2048;
- char saveset_buffer[2049];
- BOOLEAN debug = FALSE;
- int save_sets_on_tape = 0;
- static char backup_version[13] = "LGKBACKUP1.0\0";
- unsigned int total_original_size;
- unsigned int total_backup_size;
- int current_tape_block_number = 0;
- BOOLEAN want_compression = TRUE;
- volatile int filescompressed = 0;
- volatile int filesuncompressed = 0;
- DWORD start_time;
-
- typedef struct savesettag {
- char filename[300];
- unsigned int filesize; /* suports 4 gif */
- unsigned int starting_datablock_number;
- } SAVESET_HEADER;
-
- SAVESET_HEADER my_saveset_header;
-
-
-
- /* 11 per buffer use 4 buffers */
-
- typedef struct tapeheadertag {
- char saveset_name[18];
- unsigned int original_size;
- unsigned int compressed_size;
- char date[9];
- } TAPE_HEADER;
-
- TAPE_HEADER my_tape_header;
-
- typedef struct rawtag {
- char backupversion[13];
- TAPE_HEADER header[max_save_sets];
- } RAW_TAPE_HEADERT;
-
- /* 15 save sets means we only need the first 512 byte block
- since each reacord needs 32 bytes plus the first 12 = 502 total */
-
-
- RAW_TAPE_HEADERT raw_tape_header;
-
- typedef struct indexrectag {
- int original_size;
- int compressed_size;
- char fname[351];
- int start_block;
- char date[9];
- } INDEX_REC_TYPE;
-
-
- const int header_size = sizeof(raw_tape_header);
-
- extern int gzip_compress(char *,char *);
- extern int gzip_decompress(char *,char *);
-
- FILE *TempIndexFile;
- char TempIndexFileName[MAX_PATH];
- BOOLEAN tempindexfileopen = FALSE;
- HANDLE hTape; /* handle to tape device */
- DWORD dwBytesRead, dwBytesWritten, dwPos;
- BOOLEAN rdflag, wrflag;
- BOOLEAN tape_opened = FALSE;
- char todays_date[9];
- unsigned int total_bytes_read = 0;
- BOOLEAN quiet_mode = FALSE;
- BOOLEAN set_mark_positioning = FALSE;
- BOOLEAN reading_header = FALSE;
- volatile int filesskipped = 0;
- CRITICAL_SECTION Protected_Element;
- CRITICAL_SECTION Protected_Queue;
- BOOLEAN file_mapping = TRUE;
- const DWORD compress_threshold = 100000;
- /* turn off compression if file > than threshold size */
-
- typedef struct readqueuetag {
- char original_filename[400];
- char temp_filename[100];
- int size;
- BOOLEAN compressed;
- DWORD attrs;
- DWORD lowdate;
- DWORD highdate;
- } READ_QUEUE_TYPE;
-
- READ_QUEUE_TYPE read_queue[31];
- volatile int elements_in_queue = 0;
- volatile int current_queue_pop_item = 0;
- volatile int current_queue_push_item = 0;
- const int queue_size = 30;
- volatile BOOLEAN processed_all_files = FALSE;
- char Global_SearchString[100];
- volatile BOOLEAN global_process_subdirs = FALSE;
- BOOLEAN debug_child = FALSE;
- volatile BOOLEAN thread_active = FALSE;
- HANDLE hThread;
-
-
- #define severe 1
- #define warning 0
-
- /* ------------------------------------------------------------------------------------ */
- /* beginning of functions */
- /* ------------------------------------------------------------------------------------------- */
-
- int read_elements_in_queue()
- {
-
- int rvalue;
- EnterCriticalSection(&Protected_Element);
- rvalue = elements_in_queue;
- LeaveCriticalSection(&Protected_Element);
- return(rvalue);
- }
-
- /* ------------------------------------------------------------------------------------------- */
-
- void increment_elements_in_queue()
- {
- EnterCriticalSection(&Protected_Element);
- ++elements_in_queue;
- LeaveCriticalSection(&Protected_Element);
- }
-
- /* ------------------------------------------------------------------------------------------- */
-
- void decrement_elements_in_queue()
- {
- EnterCriticalSection(&Protected_Element);
- --elements_in_queue;
- LeaveCriticalSection(&Protected_Element);
- }
-
- /* ------------------------------------------------------------------------------------------- */
-
- void push_element(element)
- READ_QUEUE_TYPE element;
- {
- EnterCriticalSection(&Protected_Queue);
- strcpy(read_queue[current_queue_push_item].original_filename,element.original_filename);
- strcpy(read_queue[current_queue_push_item].temp_filename,element.temp_filename);
- read_queue[current_queue_push_item].size = element.size;
- read_queue[current_queue_push_item].attrs = element.attrs;
- read_queue[current_queue_push_item].lowdate = element.lowdate;
- read_queue[current_queue_push_item].highdate = element.highdate;
- read_queue[current_queue_push_item].compressed = element.compressed;
-
- ++current_queue_push_item;
- if (current_queue_push_item > 29)
- current_queue_push_item = 0;
- LeaveCriticalSection(&Protected_Queue);
- increment_elements_in_queue();
- }
-
- /* ------------------------------------------------------------------------------------------- */
-
- READ_QUEUE_TYPE pop_element()
- {
-
- READ_QUEUE_TYPE element;
-
- EnterCriticalSection(&Protected_Queue);
- strcpy(element.original_filename,read_queue[current_queue_pop_item].original_filename);
- strcpy(element.temp_filename,read_queue[current_queue_pop_item].temp_filename);
- element.size = read_queue[current_queue_pop_item].size;
- element.attrs = read_queue[current_queue_pop_item].attrs;
- element.lowdate = read_queue[current_queue_pop_item].lowdate;
- element.highdate = read_queue[current_queue_pop_item].highdate;
- element.compressed = read_queue[current_queue_pop_item].compressed;
-
- ++current_queue_pop_item;
- if (current_queue_pop_item > 29)
- current_queue_pop_item = 0;
- LeaveCriticalSection(&Protected_Queue);
- decrement_elements_in_queue();
-
- return(element);
- }
-
-
- /* ------------------------------------------------------------------------------------------- */
-
- /* recursive wild card search routine */
-
- BOOLEAN wild_match(search_string,target)
- char *search_string;
- char *target;
-
- {
-
- char *new_target;
- int lens = strlen(search_string);
- int lent = strlen(target);
- BOOLEAN rvalue = FALSE;
-
-
- /* handle terminating cases first */
- if (lens == 1) /* last char of search string */
- {
- if (strncmp(search_string,"*",1) == 0)
- {
- /* is a wild card * */
- return(TRUE);
- }
-
- else if ((strncmp(search_string,"?",1) == 0) && (lent == 1))
- {
- /* is a wild card ? */
- return(TRUE);
- }
- else /* other char only matches if lent is also 1 and they match */
- {
- if ((lent == 1) && (strncmp(search_string,target,1) == 0))
- return(TRUE);
- else return(FALSE);
- }
-
- } /* lens = 1 */
-
- else /* lens > 1 */
- {
- /* now check if chars is ? */
- if (strncmp(search_string,"?",1) == 0)
- {
- /* if ? skip a char in both strings and recurse */
- ++search_string;
- ++target;
- return(wild_match(search_string,target));
- }
- /* now check if char is * */
- if (strncmp(search_string,"*",1) == 0)
- {
- /* find next char in search string */
- do
- {
- ++search_string;
- /* here we also need to skip over ? as long as there is a char left
- in the target */
-
- } while (((strncmp(search_string,"*",1) == 0) ||
- ((strncmp(search_string,"?",1) == 0)) && (lent >= 1)));
- /* if it is a ? recurse */
-
- if ((strncmp(search_string,"?",1) == 0) && (lent == 0))
- return(FALSE);
-
- else /* other ok character no we need to find this character in the
- target and recurse to try and resolve if the recursion fails
- we need to try further on in the string do this until we either
- suceed or the target string runs out and we fail */
- {
-
- rvalue = FALSE;
- new_target = search_string;
- do
- {
- new_target = strchr(target,new_target[0]);
- if (new_target == NULL)
- {
- /* couldn't find character so we fail */
- return(FALSE);
- }
- else
- {
- /* found the char so recurse with it */
- rvalue = wild_match(search_string,new_target);
- }
- /* increment here */
- target = new_target;
- if (strlen(target) == 1)
- return(FALSE);
- else ++target;
- } while (rvalue == FALSE);
-
- /* if we get out of the inner loop without returning it means
- we found a successfull match so we can return it */
- return(rvalue);
- } /* end of not * or ? */
-
- } /* end of srch string was * */
-
- else
- {
- /* srch string is another character so find it in target */
- /* if next char in target is not the search string then we fail here
- otherwise we need to increment both and recurse */
- /* we also have a terminating case if if the length of the search string
- is greater than one and the length of the remaining target string is only
- one since the search string here is not a wildcard */
- if (lent <= 1)
- return(FALSE);
-
- else if (strncmp(search_string,target,1) != 0)
- return(FALSE);
- else
- { /* they are equal so recurse through remainder of the string */
- ++search_string;
- ++target;
- return(wild_match(search_string,target));
- }
- } /* end search string is regular character case */
-
- } /* end len of srch string > 1 */
- } /* end of routine */
-
- /* -------------------------------------------------------------------------------------- */
-
- void store_start_time()
- {
- start_time = GetTickCount();
- }
-
- /* ----------------------------------------------------------------------------------------- */
- void close_tape()
- {
- CloseHandle(hTape);
- if (debug)
- {
- printf("TapeIO:--> Closed Tape Drive\n\n");
- fflush(stdout);
- }
- tape_opened = FALSE;
- }
-
- /* ------------------------------------------------------------------------------------------- */
-
- void terminate_program()
-
- {
- if (tape_opened)
- close_tape();
- /* attempt to close the thread handle */
- if (thread_active)
- CloseHandle(hThread);
-
- exit(1);
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void mt_terminate_program()
-
- {
- if (tape_opened)
- close_tape();
-
- ExitThread(1);
- }
-
- /* ------------------------------------------------------------------------------------ */
- /* routine to report an error and terminat if severe */
-
- void report_error(text,rvalue,severity)
- char text[20];
- DWORD rvalue;
- int severity;
- {
- printf("TapeIO: --> Error %s :",text);
-
- if (rvalue > 0)
- printf(" error code returned = %ld ",rvalue);
-
- printf(" Severity = %d \n",severity);
- fflush(stdout);
-
- if (severity > 0)
- terminate_program();
-
- }
- /* --------------------------------------------------------------------------------------- */
-
- /* routine to report an error and terminat if severe */
- /* multi threaded version for correct thread cleanup called if thread fails */
-
- void mt_report_error(text,rvalue,severity)
- char text[20];
- DWORD rvalue;
- int severity;
- {
- printf("TapeIO: --> Error %s :",text);
-
- if (rvalue > 0)
- printf(" error code returned = %ld ",rvalue);
-
- printf(" Severity = %d \n",severity);
- fflush(stdout);
-
- if (severity > 0)
- mt_terminate_program();
-
- }
- /* --------------------------------------------------------------------------------------- */
-
- /*
- * After a file/link/symlink/dir creation has failed, see if
- * it's because some required directory was not present, and if
- * so, create all required dirs.
- */
- int
- make_dirs (pathname)
- char *pathname;
- {
- char *p; /* Points into path */
- int madeone = 0; /* Did we do anything yet? */
- int save_errno = errno; /* Remember caller's errno */
- int check;
-
- // if (errno != ENOENT)
- // return 0; /* Not our problem */
-
- for (p = strchr (pathname, '\\'); p != NULL; p = strchr (p + 1, '\\'))
- {
- /* Avoid mkdir of empty string, if leading or double '/' */
- if (p == pathname || p[-1] == '/')
- continue;
- /* Avoid mkdir where last part of path is '.' */
- if (p[-1] == '.' && (p == pathname + 1 || p[-2] == '/'))
- continue;
- *p = 0; /* Truncate the path there */
- check = _mkdir (pathname); /* Try to create it as a dir */
- if (check == 0)
- {
-
- if (debug)
- {
- printf("made directory %s \n",pathname);
- fflush(stdout);
- }
-
- madeone++; /* Remember if we made one */
- *p = '/';
- continue;
- }
- *p = '/';
- if (errno == EEXIST) /* Directory already exists */
- continue;
- /*
- * Some other error in the mkdir. We return to the caller.
- */
- break;
- }
-
- errno = save_errno; /* Restore caller's errno */
- return madeone; /* Tell them to retry if we made one */
- }
-
- /* --------------------------------------------------------------------------------------- */
-
- HANDLE open_file_for_write(filename)
- char filename[360];
- {
-
- HANDLE hFile;
- int dirsmade;
-
- hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,
- CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,(HANDLE)NULL);
-
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
-
- /* if we fail here assume it is because the path is not there and call our function to
- create directories along the path */
- /* if it fails after this we are out of luck */
-
- if (debug)
- {
- printf("create file %s failed calling make dirs to create any missing directories \n",
- filename);
- fflush(stdout);
- }
- dirsmade = make_dirs(filename);
- /* now try again to open it */
-
- hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,
- CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,(HANDLE)NULL);
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
- printf("TapeIO:--> Error Could not create file %s num dirs created = %d\n",
- filename,dirsmade);
- report_error(" ",0,severe); /* process error */
- }
-
- else {
- if (debug)
- {
- printf("TapeIO:-->Created file %s \n",filename);
- fflush(stdout);
- }
-
- return hFile;
- }
- } /* end of first create failed */
- else {
- if (debug)
- {
- printf("TapeIO:-->Created file %s \n",filename);
- fflush(stdout);
- }
-
- return hFile;
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
- HANDLE open_file_for_set_time(filename)
- char filename[360];
- {
-
- HANDLE hFile;
-
- hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,
- OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,(HANDLE)NULL);
-
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
-
- if (debug)
- {
- printf("TapeIO:--> Open file for set time failed error code = %d \n",GetLastError());
- fflush(stdout);
- return(NULL);
- }
- }
- else return hFile;
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- int compress_file(filename,temppath)
- char filename[];
- char *temppath;
- {
- char TempFileName[30];
- DWORD lcopied = 0;
- int rvalue = 0;
- char *nameloc;
-
- /* get the temp path */
- /* append the temp filename and call gzip to execute and write the temp file name */
- /* pass back the compressed file and we will back that up and remove it */
-
- lcopied = GetTempPath(100,temppath);
- if (lcopied <= 0)
- {
- report_error(" Cannot retrieve temporary directory path \n",0,warning);
- return(-1);
- }
- else
- {
- /* now create a temp name and concat path to name */
- rvalue = GetTempFileName(temppath, /* dir. for temp. files */
- "NEW", /* temp. filename prefix */
- 0, /* create unique name w/ sys. time */
- (LPTSTR) TempFileName); /* buffer for name */
-
- if (rvalue == 0)
- {
- report_error(" Getting temp file name for compression \n",GetLastError(),warning);
- return(-1);
- }
- else
- {
- /* concat path to name */
- /* we only need to name form the temp file as it appends \temp\ to it
- and we already have the temppath */
- nameloc = strrchr(TempFileName,'\\');
- /* skip over slash */
- ++nameloc;
-
- strcat(temppath,nameloc);
-
- if (debug)
- {
- printf("temp file for compress = %s \n",temppath);
- fflush(stdout);
- }
-
- /* now create command to run zip having output go to tempfile. */
-
- //strcpy(cmd, "gzip -c1n "); /* use "gzip -c" for zwrite */
- //strncat(cmd, filename, sizeof(cmd)-strlen(cmd));
- //strcat(cmd," > ");
- //strcat(cmd, temppath);
- //if (debug)
- // {
- // printf("command for gzip = %s \n",cmd);
- // fflush(stdout);
- // }
-
- rvalue = gzip_compress(filename,temppath);
-
- if (rvalue != 0)
- {
- mt_report_error("Call to execute compression failed ",rvalue,severe);
- return(-1);
- }
- else return(0);
-
- } /* ok temp name */
- } /* ok temp path name */
- }
-
-
- /* ------------------------------------------------------------------------------------ */
-
- int decompress_file(filename,temppath)
- char filename[];
- char temppath[];
- {
- int rvalue = 0;
- HANDLE tHandle;
-
- /* open the file to make sure it can be created or force creation of paths */
- tHandle = open_file_for_write(filename);
- CloseHandle(tHandle);
-
- /* now create command to run zip having output go from tempfile to original file */
-
-
- //strcpy(cmd, "gzip -d < "); /* use "gzip -c" for zwrite */
- //strncat(cmd, temppath, sizeof(cmd)-strlen(cmd));
- //strcat(cmd," > ");
- //strcat(cmd, filename);
- //if (debug)
- // {
- // printf("command for gzip = %s \n",cmd);
- // fflush(stdout);
- // }
-
- rvalue = gzip_decompress(temppath,filename);
- return(rvalue);
-
- }
- /* ------------------------------------------------------------------------------------ */
- void write_setmarks(no_marks)
- DWORD no_marks;
- {
- DWORD rvalue;
-
- if (debug)
- {
- printf("Attempting to Write %d setmarks \n",no_marks);
- fflush(stdout);
- }
-
- rvalue = WriteTapemark(hTape, TAPE_SETMARKS,no_marks,FALSE);
-
- if (rvalue != NO_ERROR)
- report_error(" Tape write setmarks error ",rvalue,severe);
-
- }
-
-
- /* ------------------------------------------------------------------------------------ */
- void write_filemarks(no_marks)
- DWORD no_marks;
- {
- DWORD rvalue;
-
- if (set_mark_positioning)
- {
- write_setmarks(no_marks);
- }
- else
- {
- if (debug)
- {
- printf("Attempting to Write %d filemarks \n",no_marks);
- fflush(stdout);
- }
-
- rvalue = WriteTapemark(hTape, TAPE_FILEMARKS,no_marks,FALSE);
-
- if (rvalue != NO_ERROR)
- report_error(" Tape write filemarks error ",rvalue,severe);
- }
- }
-
-
- /* ------------------------------------------------------------------------------------ */
- void fill_in_todays_date()
-
- {
-
- struct tm *newtime;
- long ltime;
-
- time( <ime );
-
- /* Obtain Universal Coordinated Time: */
- newtime = gmtime( <ime );
- /* now fill in our date string */
- sprintf(todays_date,"%2d-%2d-%2d",(newtime->tm_mon)+1,newtime->tm_mday,newtime->tm_year);
- if (debug)
- {
- printf("filled in todays date with %s \n",todays_date);
- fflush(stdout);
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- /* routine to open up the tape drive assumes only 1 tape drive for now */
-
- void open_tape()
-
- {
- if (tape_opened == FALSE)
- {
-
- hTape = CreateFile(
- "\\\\.\\TAPE0", /* name of tape device to open */
- GENERIC_READ | GENERIC_WRITE, /* read-write access */
- 0, /* not used */
- 0, /* not used */
- OPEN_EXISTING, /* required for tape devices */
- 0, /* not used */
- NULL); /* not used */
-
-
- if (hTape == NULL)
- {
- report_error("Opening tape device \n",0,1);
- }
- else
- {
- if (debug)
- { printf("TapeIO:--> Opened Tape drive.\n");
- fflush(stdout);
- }
- tape_opened = TRUE;
- }
-
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- /* function to set block size */
-
- void set_block_size(bsize)
- unsigned long bsize;
- {
-
- DWORD rvalue;
-
- tparms.BlockSize = bsize;
- rvalue = SetTapeParameters(hTape,SET_TAPE_MEDIA_INFORMATION,&tparms);
- if (rvalue != NO_ERROR)
- {
- report_error("Setting tape media information ",rvalue,severe);
- }
- else
- {
- if (debug)
- {
- printf("TapeIO:--> Set tape media parameters i.e. blocksize to %ld\n",bsize);
- fflush(stdout);
- }
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- /* rewind the tape always wait for resute no immediate mode */
-
- void rewind_tape(immediate)
- BOOLEAN immediate;
- {
- DWORD rvalue;
-
- rvalue = PrepareTape(hTape,TAPE_LOAD,immediate);
-
- if ((!immediate) && (rvalue != NO_ERROR))
- {
- report_error("rewinding tape ",rvalue,1);
- }
- else
- {
- current_tape_block_number = 0;
- if (debug)
- {
- printf("TapeIO:-->Rewound Tape mode = %d\n",immediate);
- fflush(stdout);
- }
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
- void space_setmarks(no_marks)
- DWORD no_marks;
- {
- DWORD rvalue;
- DWORD status;
- DWORD rvalue2;
-
- if (debug)
- {
- printf("Attempting to Space %d setmarks\n",no_marks);
- fflush(stdout);
- }
-
- rvalue = SetTapePosition(hTape,TAPE_SPACE_SETMARKS,0,no_marks,0,FALSE);
- if (rvalue != NO_ERROR)
- {
- rvalue2 = GetLastError();
- status = GetTapeStatus(hTape);
- printf(" Tape positioning by setmarks error rvalue = %d tape status =%d getlsterror = %d\n",
- rvalue,status,rvalue2);
- fflush(stdout);
- report_error(" ",0,severe);
- }
-
- }
-
- /* ------------------------------------------------------------------------------------ */
- void space_filemarks(no_marks)
- DWORD no_marks;
- {
- DWORD rvalue;
- DWORD status;
- DWORD rvalue2;
-
- if (set_mark_positioning)
- {
- space_setmarks(no_marks);
- }
- else {
- if (debug)
- {
- printf("Attempting to Space %d file marks\n",no_marks);
- fflush(stdout);
- }
-
- rvalue = SetTapePosition(hTape,TAPE_SPACE_FILEMARKS,0,no_marks,0,FALSE);
- if (rvalue != NO_ERROR)
- {
- rvalue2 = GetLastError();
- status = GetTapeStatus(hTape);
- printf(" Tape positioning by filemarks error rvalue = %d tape status =%d getlsterror = %d\n",
- rvalue,status,rvalue2);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- }
- }
-
- /* ---------------------------------------------------------------------------------- */
-
- void read_tape_block(buff)
- char *buff;
-
- {
- DWORD rdflag;
-
- rdflag = ReadFile(hTape, (LPSTR) buff, buffersize, &dwBytesRead, NULL);
-
- /* handle strange error case of not spacing over file mark correctly if on
- top of on assume it didn't space write and space over it */
- if (rdflag != TRUE)
- {
-
- if ((reading_header) && (GetLastError() == ERROR_NO_DATA_DETECTED))
- { /* tape is not initialized */
- printf("ERROR while trying to read the tape header information, \n");
- printf(" no data was detected. It appears that this tape \n");
- printf(" has not been initialized (LKBACKUP -i) \n");
- fflush(stdout);
- report_error("Error reading tape",rdflag,severe);
- }
- else
- {
- printf("error reading block getlasterror %d getstatus %d \n",
- GetLastError(),GetTapeStatus(hTape));
- fflush(stdout);
- report_error("Error reading tape",0,severe);
- }
- }
- else
- {
- ++current_tape_block_number;
- if (debug)
- {
- printf("TapeIO:--> Read %ld characters from the tape \n",dwBytesRead);
- fflush(stdout);
- }
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void write_tape_block(buff)
- char buff[];
-
- {
- DWORD wrflag;
- DWORD dwBytesWritten;
-
-
- wrflag = WriteFile(hTape, (LPSTR) buff, buffersize, &dwBytesWritten, NULL);
- if (wrflag != TRUE)
- {
- report_error("Error writing tape",0,warning);
- }
- else
- {
-
- if (debug)
- {
- printf("TapeIO:--> Wrote %ld characters to the tape block = %d\n",
- dwBytesWritten,current_tape_block_number);
- fflush(stdout);
- }
- ++current_tape_block_number;
- }
- }
-
- /* -------------------------------------------------------------------------------- */
-
- DWORD read_file_block(lhfile,buff)
-
- HANDLE lhfile;
- char *buff;
-
- {
- DWORD rdflag;
- DWORD dwBytesRead = 0;
-
- rdflag = ReadFile(lhfile, (LPSTR) buff, buffersize, &dwBytesRead, NULL);
- if (rdflag != TRUE)
- {
- report_error("Error reading file",0,warning);
- }
- else
- {
- if (debug)
- {
- printf("TapeIO:--> Read %ld characters from file \n",dwBytesRead);
- fflush(stdout);
- }
- }
-
- return(dwBytesRead);
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- DWORD write_file_block(lhfile,buff,bytes)
-
- HANDLE lhfile;
- char *buff;
- int bytes;
-
- {
- DWORD dwBytesWritten = 0;
- DWORD wrflag;
-
- wrflag = WriteFile(lhfile, (LPSTR) buff, (DWORD)bytes, &dwBytesWritten, NULL);
- if (wrflag != TRUE)
- {
- report_error("Error writing file",0,warning);
- }
- else
- {
- if (debug)
- {
- printf("TapeIO:--> Wrote %ld characters to file \n",dwBytesWritten);
- fflush(stdout);
- }
- }
- return(dwBytesWritten);
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void dump_header_element(element_number)
- int element_number;
- {
-
- if (strncmp(raw_tape_header.header[element_number].saveset_name,"EMPTY001_____",13) != 0)
- { /* ok not empty */
- printf("%-8d",element_number);
- printf("%16s",raw_tape_header.header[element_number].saveset_name);
- printf("%13d %15d %8s\n",
- raw_tape_header.header[element_number].original_size,
- raw_tape_header.header[element_number].compressed_size,
- raw_tape_header.header[element_number].date);
- fflush(stdout);
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void space_end_of_data()
- {
- DWORD rvalue;
-
- if (debug)
- {
- printf("Attempting to Space to end of data \n");
- fflush(stdout);
- }
-
- rvalue = SetTapePosition(hTape,TAPE_SPACE_END_OF_DATA,0,0,0,FALSE);
- if (rvalue != NO_ERROR)
- {
- printf(" Tape positioning to end of data error rvalue = %d \n",rvalue);
- fflush(stdout);
- report_error(" ",rvalue,severe);
- }
- }
-
- /* ----------------------------------------------------------------------------------------- */
-
- void read_tape_index()
-
- {
-
- char block[bsize1];
- int offset = 0;
- int element_number = 0;
- int end_element_number = 0;
- int block_number = 0;
-
-
- open_tape();
- set_block_size(blocksize);
- rewind_tape(FALSE);
- save_sets_on_tape = 0;
- reading_header = TRUE;
-
- /* retrive the tape id first */
- read_tape_block(block);
- reading_header = FALSE;
- if (strncmp(block,backup_version,12) != 0)
- {
- /* tape is foreign format */
- printf("Warning tape is foreign in format.\n");
- printf("You must initialize it first with LKBACKUP -i\n");
- fflush(stdout);
- rewind_tape(TRUE);
- close_tape();
- exit(1);
- }
-
- /* now get to the tape index */
- space_end_of_data();
- /* now go back one filemark to get to the beginning of the index */
- space_filemarks(-1);
- space_filemarks(1);
-
-
- /* retrieve all blocks of the tape index */
-
- current_tape_block_number = 0;
- for (block_number = 0; block_number < blocks_per_header; block_number++)
- {
- read_tape_block(block);
- offset = 0;
- if (debug)
- {
- printf("Retrieved block %d %4096s \n",block_number,block);
- fflush(stdout);
- }
-
- element_number = (block_number * save_sets_per_block);
- end_element_number = element_number + save_sets_per_block;
-
- do
- {
- sscanf(block + offset,"%16s",raw_tape_header.header[element_number].saveset_name);
- offset = offset + 16;
-
- sscanf(block + offset,"%10ud",&raw_tape_header.header[element_number].original_size);
- offset=offset+10;
-
- sscanf(block + offset,"%10ud",&raw_tape_header.header[element_number].compressed_size);
- offset=offset+12;
-
- sscanf(block + offset,"%8s",&raw_tape_header.header[element_number].date);
- offset=offset+8;
-
-
- if (debug)
- {
- printf("Current offset = %d \n",offset);
- dump_header_element(element_number);
- }
-
- ++element_number;
- } while (element_number < end_element_number);
-
- } /* end for all blocks */
- rewind_tape(FALSE);
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void write_tape_id()
-
- {
-
- char block[bsize1];
- int offset;
-
- open_tape();
- set_block_size(blocksize);
- rewind_tape(FALSE);
-
- /* fill in backup version and all blocks info */
-
- offset = sprintf(block,"%12s %8s\0",backup_version,todays_date);
- write_tape_block(block); /* force data to be written */
- write_filemarks(1);
- }
-
- /* ------------------------------------------------------------------------------------- */
-
- void write_tape_index(already_positioned)
- BOOLEAN already_positioned;
-
- {
-
- char block[bsize1];
- int element_number = 0;
- int end_element_number = 0;
- int offset = 0;
- int block_number = 0;
-
- if (!already_positioned)
- {
- open_tape();
- set_block_size(blocksize);
- /* space to end of tape data */
- rewind_tape(FALSE);
- space_end_of_data();
- }
-
- current_tape_block_number = 0;
- for (block_number = 0; block_number < blocks_per_header; block_number++)
- {
- offset = 0;
- for (element_number = (block_number * save_sets_per_block); element_number < (save_sets_per_block * (block_number + 1)); element_number++)
- {
- offset = offset + sprintf(block + offset,"%16s%10u %10u %8s",
- raw_tape_header.header[element_number].saveset_name,
- raw_tape_header.header[element_number].original_size,
- raw_tape_header.header[element_number].compressed_size,
- raw_tape_header.header[element_number].date);
- }
-
- if (debug)
- printf("TapeIO:--> character count in buffer = %d\n",offset);
-
- write_tape_block(block);
-
- if (debug)
- {
- printf("wrote block %d %4096s \n",block_number,block);
- fflush(stdout);
- }
-
-
- } /* end for loop */
- /* write the file mark after the index */
- rewind_tape(TRUE);
- }
-
-
- /* ----------------------------------------------------------------------------- */
-
- void fill_in_header_element(name,osize,csize,date,element_number)
- char name[18];
- unsigned int osize;
- unsigned int csize;
- char date[9];
- int element_number;
-
-
- {
- strncpy(raw_tape_header.header[element_number].saveset_name,name,16);
- raw_tape_header.header[element_number].original_size = osize;
- raw_tape_header.header[element_number].compressed_size = csize;
- strncpy(raw_tape_header.header[element_number].date,date,8);
- raw_tape_header.header[element_number].date[8] = '\0';
-
- }
-
-
- /* ----------------------------------------------------------------------------------------- */
-
- void clear_header()
- {
-
- int element_number;
-
- for (element_number = 0; element_number< max_save_sets; element_number++)
- fill_in_header_element("EMPTY001______________________",0,0,"00-00-00",element_number);
- }
-
-
- /* ------------------------------------------------------------------------------------------- */
-
- void initialize_tape()
- {
-
- if (debug)
- {
- printf("TapeIO:--> Initializing Tape.\n");
- fflush(stdout);
- }
-
- open_tape();
- rewind_tape(FALSE);
- write_tape_id();
-
- clear_header();
- write_tape_index(TRUE);
-
- }
-
-
- /* ------------------------------------------------------------------------------------------- */
-
- void catalog_tape(no_good_backups)
- char *no_good_backups;
-
- {
-
- int no_backups;
- int rvalue;
- int element_number;
- char current_name[40];
- char current_number[4];
-
- rvalue = sscanf(no_good_backups,"%d",&no_backups);
- if (rvalue == 0)
- {
- printf("Error %s is not a legal integer value for the number of good backups on the tape \n",
- no_good_backups);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- /* check for legal number */
- if ((no_backups < 1) || (no_backups > max_save_sets))
- {
- printf("Error %d is not a legal integer value for the number of good backups on the tape \n",
- no_backups);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- /* otherwise do it */
- /* fill in the correct number in the header */
- clear_header();
- for (element_number = 0; element_number < no_backups; element_number++)
- {
- strcpy(current_name,"saveset");
- sprintf(current_number,"%d",element_number+1);
- strcat(current_name,current_number);
- while (strlen(current_name) < 30)
- strcat(current_name," ");
- if (debug)
- {
- printf("Filling in header with %s for saveset name len = %d \n",current_name,
- strlen(current_name));
- fflush(stdout);
- }
- fill_in_header_element(current_name,0,0,"00-00-00",element_number);
- } /* end of loop */
- /* now space to end of data and write out the index file again */
-
- if (!quiet_mode)
- {
- printf("Attempting to restore the tape index\n");
- fflush(stdout);
- }
-
- if (debug)
- {
- printf("TapeIO:--> Initializing Tape.\n");
- fflush(stdout);
- }
-
- write_tape_index(FALSE);
-
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void erase_tape(secure)
- BOOLEAN secure;
-
- {
-
- DWORD rvalue;
-
- open_tape();
- rewind_tape(FALSE);
-
- current_tape_block_number = 0;
- if (secure)
- rvalue = EraseTape(hTape,TAPE_ERASE_LONG,FALSE);
- else rvalue = EraseTape(hTape,TAPE_ERASE_SHORT,FALSE);
-
- if (rvalue != NO_ERROR)
- {
- report_error("Erasing tape ",rvalue,severe);
- }
-
- else
-
- {
- if (debug)
- {
- printf("TapeIO:-->Erased Tape");
- if (secure)
- printf(" Secure/long \n");
- else printf(" Short \n");
- fflush(stdout);
- }
- rewind_tape(TRUE);
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- HANDLE open_file_for_read(filename,doing_backup_restore)
- char filename[200];
- BOOLEAN doing_backup_restore;
- {
-
- HANDLE hFile;
-
- hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_BACKUP_SEMANTICS,(HANDLE)NULL);
-
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
- printf("TapeIO:--> Error Could not open file %s\n",filename);
- fflush(stdout);
- if (doing_backup_restore)
- {
- return(NULL);
- }
- else
- report_error(" ",0,severe); /* process error */
- }
-
- else {
- if (debug)
- {
- printf("TapeIO:-->Opened file %s \n",filename);
- fflush(stdout);
- }
-
- return hFile;
- }
- }
-
- /* --------------------------------------------------------------------------------------- */
-
- void open_index_file()
- {
-
- DWORD lcopied = 0;
- int rvalue = 0;
- char TempName[40];
- char *nameloc;
-
- if (!tempindexfileopen)
- {
- lcopied = GetTempPath(100,TempIndexFileName);
- if (lcopied <= 0)
- report_error(" Cannot retrieve temporary directory path \n",0,severe);
- else
- {
- /* now create a temp name and concat path to name */
- rvalue = GetTempFileName(TempIndexFileName, /* dir. for temp. files */
- "NEW", /* temp. filename prefix */
- 0, /* create unique name w/ sys. time */
- (LPTSTR) TempName); /* buffer for name */
-
- if (rvalue == 0)
- report_error(" Getting temp file name for index file \n",rvalue,severe);
- else
- {
- /* concat path to name */
- /* we only need to name form the temp file as it appends \temp\ to it
- and we already have the temppath */
- nameloc = strrchr(TempName,'\\');
- /* skip over slash */
- ++nameloc;
-
- strcat(TempIndexFileName,nameloc);
-
- TempIndexFile = fopen(TempIndexFileName,"w");
-
- if (TempIndexFile == NULL)
- report_error(" Could not create temporary index file.",0,severe);
- else
- {
- if (debug)
- {
- printf("created temp index file %s \n",TempIndexFileName);
- fflush(stdout);
- }
-
- tempindexfileopen = TRUE;
- }
- } /* name ok */
- } /* path ok */
- } /* not already open */
- }
-
- /* --------------------------------------------------------------------------------------- */
- void write_index_entry(fpath,size,compressed_size,date,start_block)
-
- char fpath[512];
- unsigned int size;
- unsigned int compressed_size;
- char date[9];
- int start_block;
-
- {
- int compression_percent = (int)(100.00 * (1.000 - (float)((float)compressed_size/(float)size)));
-
- if ((compressed_size == 0) && (size > 0))
- compression_percent = 0;
-
- if (!tempindexfileopen)
- open_index_file();
-
- /* write info to command line and then to index file */
- if (!quiet_mode)
- {
- printf("%s %d %d (%d)%% %8s %d\n",
- fpath,size,compressed_size,compression_percent,date,start_block);
- }
-
- fprintf(TempIndexFile,"%350s %10d %10d %8s %10d \n",
- fpath,size,compressed_size,date,start_block);
-
- fflush(stdout);
- fflush(TempIndexFile);
- }
-
- /* --------------------------------------------------------------------------------------*/
- void close_index_file()
- {
-
- if (tempindexfileopen)
- {
- fclose(TempIndexFile);
- if (debug)
- {
- printf("closed temp index file \n");
- fflush(stdout);
- }
- tempindexfileopen = FALSE;
- }
- }
-
- /* --------------------------------------------------------------------------------------*/
-
- void mt_compress_file(filename,size)
- char filename[];
- DWORD size;
-
- {
- char lbuffer[bsize1];
- HANDLE hFile;
- LPTSTR ppszFilePart; /* address of filename in path */
- DWORD rvalue;
- FILETIME wtime;
- BOOLEAN oktime;
- DWORD dwAttrs;
- char savepath[513];
- int ldwBytesRead = 0;
- char compress_name[500];
- char fnamecopy[500];
- int queue_elements;
- READ_QUEUE_TYPE element;
- BOOLEAN compressed = FALSE;
- BOOLEAN compressed_ok = FALSE;
-
-
- strcpy(fnamecopy,lbuffer);
- hFile = open_file_for_read(filename,TRUE);
-
- if (hFile == NULL) /* skip it since it couldn't be opened */
- {
- ++filesskipped;
- printf("Warning skipping file %s which could not be opened. \n",filename);
- fflush(stdout);
- }
-
- else
-
- {
-
- if (debug_child)
- {
- printf("TapeIO:--> In child thread Attempting to compress %s size is %ld \n",filename,size);
- fflush(stdout);
- }
- /* write full path to file */
- /* but erase first 3 chars ie i:\ so that restore is not drive specific */
-
- rvalue = GetFullPathName((LPCSTR)filename,buffersize,(LPTSTR)lbuffer,&ppszFilePart);
- if (rvalue == 0)
- {
- CloseHandle(hFile);
- printf("Warning skipping file %s because full path and filename is longer than 512 chars \n",filename);
- fflush(stdout);
- ++filesskipped;
- }
- else
- {
-
- strcpy(fnamecopy,lbuffer);
-
- lbuffer[0] = ' ';
- lbuffer[1] = ' ';
- lbuffer[2] = ' ';
-
- strcpy(savepath,lbuffer);
-
- if (debug_child)
- {
- printf("TapeIO:--> Attempting to compress %s size is %ld \n",savepath,size);
- fflush(stdout);
- }
-
- /* now write file date/time and attributes */
- oktime = GetFileTime(hFile,NULL,NULL,&wtime);
- if (!oktime)
- report_error(" Couldn't retrieve file time \n",0,warning);
-
- /* get attr string */
-
- dwAttrs = GetFileAttributes(filename);
- sprintf(lbuffer + rvalue," %d %d %d %d",size,dwAttrs,
- wtime.dwLowDateTime,wtime.dwHighDateTime);
-
- CloseHandle(hFile);
- /* only compress if below threshold size to try and keep tape streaming */
- if (((size < compress_threshold) && (size > (DWORD)blocksize)) && (want_compression))
- {
- compressed = TRUE;
- rvalue = compress_file(filename,&compress_name);
- if (debug_child)
- {
- printf("rvalue from compression = %d \n",rvalue);
- fflush(stdout);
- }
-
- if (rvalue == 0)
- {
- compressed_ok = TRUE;
- /* file was compressed ok so log the stuff to the queue and go on */
- if (debug_child)
- {
- printf("file %s compressed correctly temp name = %s\n",filename,compress_name);
- fflush(stdout);
- }
-
- }
- else
- {
- compressed_ok = FALSE;
- }
-
- }
- else
- {
- compressed = FALSE;
- /* copy name */
- strcpy(compress_name,fnamecopy);
- }
-
- if ((!compressed) || (compressed_ok))
- {
- /* now attempt to put it in the queue and go on as long as the queue is not too full
- if it is too full sleep and try again */
- queue_elements = 0;
- do
- {
- queue_elements = read_elements_in_queue();
- if (queue_elements >= 29)
- {
- /* wait */
- Sleep(500);
- if (debug_child)
- {
- printf("Woke up from .5 second wait queue size was %d \n",queue_elements);
- fflush(stdout);
- }
- }
- } while (queue_elements >= 29);
-
- /* if we got here there is room in the queue to do it */
- strcpy(element.original_filename,savepath);
- strcpy(element.temp_filename,compress_name);
- element.size = size;
- element.attrs = dwAttrs;
- element.lowdate = wtime.dwLowDateTime;
- element.highdate = wtime.dwHighDateTime;
- element.compressed = compressed;
-
- if (debug_child)
- {
- printf("Filled in element with: \n");
- printf("original name = %s \n",element.original_filename);
- printf("temp name = %s \n",element.temp_filename);
- printf("size = %d attrs = %d lowdate = %d highdate = %d \n",
- element.size,element.attrs,element.lowdate,element.highdate);
- fflush(stdout);
- }
- push_element(element);
-
- } /* compressed ok or not compressed */
- } /* path ok */
- } /* opened ok */
- }
-
- /* --------------------------------------------------------------------------------------*/
-
- void backup_index_file(filename,size,attributes)
- char filename[];
- DWORD size;
-
- {
- char lbuffer[bsize1];
- HANDLE hFile;
- LPTSTR ppszFilePart; /* address of filename in path */
- DWORD rvalue;
- int start_block = current_tape_block_number;
- int ldwBytesRead = 0;
-
-
- hFile = open_file_for_read(filename,TRUE);
-
- /* now since file opened ok write out first buffer with file name and
- size */
- if (hFile == NULL) /* skip it since it couldn't be opened */
- {
- ++filesskipped;
- printf("Warning skipping file %s which could not be opened. \n",filename);
- fflush(stdout);
- }
-
- else
-
- {
-
- if (debug)
- {
- printf("TapeIO:--> Backing up %s size is %ld \n",filename,size);
- fflush(stdout);
- }
- /* write full path to file */
- /* but erase first 3 chars ie i:\ so that restore is not drive specific */
-
- rvalue = GetFullPathName((LPCSTR)filename,buffersize,(LPTSTR)lbuffer,&ppszFilePart);
- if (rvalue == 0)
- {
- CloseHandle(hFile);
- report_error(" Path + file name longer than max buffer size (512)\n",rvalue,severe);
- }
-
- lbuffer[0] = ' ';
- lbuffer[1] = ' ';
- lbuffer[2] = ' ';
-
- if (debug)
- {
- printf("TapeIO:--> Backing up %s size is %ld \n",lbuffer,size);
- fflush(stdout);
- }
-
-
- sprintf(lbuffer + rvalue," %d %d %d %d",size,0,
- 0,0);
-
- write_tape_block(lbuffer);
-
- if (debug)
- {
- printf("wrote block for file header %2048s \n",lbuffer);
- fflush(stdout);
- }
-
- do {
- dwBytesRead = read_file_block(hFile,lbuffer);
- if (dwBytesRead > 0)
- {
- if (debug)
- {
- printf("TapeIO:-->Attempting to write the buff to tape\n");
- fflush(stdout);
- }
-
- write_tape_block(lbuffer);
-
- } /* bytes > 0 */
-
- } while (dwBytesRead == buffersize);
- /* close the file handle */
- CloseHandle(hFile);
-
- ++filesuncompressed;
- total_backup_size = total_backup_size + size;
- total_original_size = total_original_size + size;
- } /* skip file */
- }
- /* --------------------------------------------------------------------------------------*/
-
- void mt_backup_files()
-
- /* modify routine to simply read queue element and backup the file if not index file
- and compression on */
-
- {
-
- char lbuffer[bsize1];
- HANDLE hFile, hMapHandle;
- unsigned int compress_size = 0;
- int elements_in_queue;
- READ_QUEUE_TYPE element;
- FILETIME wtime;
- unsigned short dostime;
- unsigned short dosdate;
- char file_date[9];
- int start_block = current_tape_block_number;
- BOOLEAN mapok = FALSE;
- LPVOID memory_address = NULL;
- DWORD fsize;
- int compress_size_to_write = 0;
- BOOLEAN skipping_file = FALSE;
- BOOLEAN old_method_ok = FALSE;
- BOOLEAN unmap_ok = FALSE;
-
- /* lgk add case to handle uncompressed file below threshold and to turn off file mapping */
-
- elements_in_queue = 0;
- do /* loop until we are signaled that we are done and there are no more elements to be processed */
-
- {
- /* get element from queue if it is waiting if not sleep for two seconds and try again */
-
- do /* loop while there are no elements to process and we are not done */
- {
- elements_in_queue = read_elements_in_queue();
-
- if ((elements_in_queue == 0) && (!processed_all_files))
- Sleep(500);
- } while ((elements_in_queue == 0) && (!processed_all_files));
-
- /* now that we have an item read it */
- /* need to read it again here because between the time elements was 0 and the end of
- the while loop processed_all_files is getting set to true and the loop is exiting
- without realizing about the last few files in the queue */
-
- elements_in_queue = read_elements_in_queue();
- if (elements_in_queue > 0)
- {
- element = pop_element();
- /* now process_it */
- compress_size = 0;
- start_block = current_tape_block_number;
-
- if (debug)
- {
- printf("TapeIO:--> Backing up %s aka %s size is %ld \n",
- element.original_filename,element.temp_filename,element.size);
- fflush(stdout);
- }
-
- skipping_file = FALSE;
- old_method_ok = FALSE;
- mapok = FALSE;
- memory_address = NULL;
-
- hFile = open_file_for_read(element.temp_filename,TRUE);
- if (hFile == NULL) /* skip it since it couldn't be opened */
- {
- ++filesskipped;
- printf("Warning skipping file %s since temp file/tempfile %s could not be opened. \n",
- element.original_filename,element.temp_filename);
- fflush(stdout);
- skipping_file = TRUE;
- mapok = FALSE;
- }
- else /* skipping */
- {
- sprintf(lbuffer,"%350s %d %d %d %d",element.original_filename,element.size,element.attrs,
- element.lowdate,element.highdate);
- write_tape_block(lbuffer);
- if (debug)
- {
- printf("wrote block for file header %2048s \n",lbuffer);
- fflush(stdout);
- }
-
- /* only use file mapping if on */
-
- if (file_mapping)
- {
- mapok = TRUE;
- /* lgk new code here to speed things up by reading the entire file into a memory
- buffer and then writting to tape if this fails default to the old method */
-
- /* get the file size */
- fsize = GetFileSize(hFile,NULL);
- if (fsize == 0xFFFFFFFF)
- {
- if (debug)
- {
- printf("Getfile size for %s failed \n",element.temp_filename);
- fflush(stdout);
- CloseHandle(hFile);
- mapok = FALSE;
- }
- }
- else
- {
- hMapHandle = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,"compress_map");
- if (hMapHandle == NULL)
- {
- if (debug)
- {
- printf("Map file did not open correctly rvalue = %d \n",GetLastError());
- fflush(stdout);
- CloseHandle(hFile);
- mapok = FALSE;
- }
- }
- else
- {
- /* now map the handle into memory */
- memory_address = MapViewOfFile(hMapHandle,FILE_MAP_READ,0,0,0);
- if (memory_address == NULL)
- {
- printf("Map file view did not open correctly rvalue = %d \n",GetLastError());
- fflush(stdout);
- CloseHandle(hFile);
- CloseHandle(hMapHandle);
- mapok = FALSE;
- }
- else
- {
- /* ok now process the memory in blocks that the tape drive can handle */
- compress_size = 0;
- mapok = TRUE;
-
- do
- {
- write_tape_block((char *)((DWORD)(memory_address) + compress_size));
- compress_size = compress_size + buffersize;
- } while (compress_size < fsize);
- /* ok reset compress_size which got too big */
- compress_size = fsize;
-
- } /* ok address */
- } /* ok handle */
- } /* ok size */
-
- /* clean up if worked ok otherwise try other method */
- if (mapok)
- {
- if (debug)
- {
- printf("file map method worked \n");
- fflush(stdout);
- }
- unmap_ok = TRUE;
- unmap_ok = UnmapViewOfFile(memory_address);
- if (!unmap_ok)
- {
- printf("Warning unmapping of file view failed error code = %d \n",GetLastError());
- fflush(stdout);
- }
- /* now close the handles */
- CloseHandle(hMapHandle);
- CloseHandle(hFile);
- } /* mapped ok */
-
- } /* end file mapping on */
-
- else /* either it failed or don't want file mapping */
- {
-
-
- do {
- dwBytesRead = read_file_block(hFile,lbuffer);
- if (dwBytesRead > 0)
- {
- if (debug)
- {
- printf("TapeIO:-->Attempting to write the buff to tape\n");
- fflush(stdout);
- }
-
- write_tape_block(lbuffer);
- compress_size = compress_size + dwBytesRead;
-
- } /* bytes > 0 */
-
- } while (dwBytesRead == buffersize);
-
- /* close the file handle */
- CloseHandle(hFile);
- old_method_ok = TRUE;
- } /* end of old method */
-
- if (old_method_ok || mapok)
- {
- /* now handle the index entry */
-
- wtime.dwLowDateTime = element.lowdate;
- wtime.dwHighDateTime = element.highdate;
-
- /* need to convert to file date for the index entry */
-
- if (element.compressed)
- {
- compress_size_to_write = compress_size;
- total_backup_size = total_backup_size + compress_size;
- }
- else
- {
- compress_size_to_write = 0;
- total_backup_size = total_backup_size + element.size;
- }
-
- if (!FileTimeToDosDateTime(&wtime,&dosdate,&dostime))
- {
-
- printf("Warning couldn't convert file date to dos date using todays date \n");
- fflush(stdout);
- write_index_entry(element.original_filename,element.size,compress_size_to_write,
- todays_date,start_block);
- }
- /* ok we got the date no set it into varibles and convert to string */
- else
- {
- int nDay = dosdate & 0x1f;
- int nMonth = (dosdate >> 5) & 0x0f;
- int nYear = (dosdate >> 9) + 80;
-
- /* now convert to string */
- sprintf(file_date,"%02d-%02d-%02d",nMonth,nDay,nYear);
- write_index_entry(element.original_filename,element.size,compress_size_to_write,
- file_date,start_block);
- }
-
- /* only delete file if actually was temp file don't do it for uncompressed files */
- if (element.compressed)
- {
- ++filescompressed;
- DeleteFile(element.temp_filename);
- }
- else ++filesuncompressed;
-
- total_original_size = total_original_size + element.size;
- } /* mpa ok or old meethod ok */
- } /* not skipping file */
- } /* we have an element */
-
- } while ((elements_in_queue != 0) || (!processed_all_files));
- }
-
- /* ------------------------------------------------------------------------------------- */
- void set_file_info(filename,lowtime,hightime,lattrs)
-
- char *filename;
- DWORD lowtime;
- DWORD hightime;
- DWORD lattrs;
-
- {
-
- FILETIME local_file_time;
- HANDLE writeHandle;
-
- /* attempt to set date and file attributes */
- if (lattrs != 0)
- {
- if (debug)
- {
- printf("Attempting to set file attributes to %d \n",lattrs);
- fflush(stdout);
- }
-
- if (!SetFileAttributes(filename,lattrs))
- {
- printf("Warning couldn't set file %s attributes to %s during restore \n",filename,lattrs);
- fflush(stdout);
- }
- }
-
- /* now fill in a wtime struct and attempt to reset the time */
- local_file_time.dwLowDateTime = lowtime;
- local_file_time.dwHighDateTime = hightime;
-
- writeHandle = open_file_for_set_time(filename);
-
- if (!SetFileTime(writeHandle,NULL,NULL,&local_file_time))
- {
- printf("Warning couldn't set file last write time for %s error = %d \n",
- filename,GetLastError());
- fflush(stdout);
- }
- CloseHandle(writeHandle);
- }
-
- /* --------------------------------------------------------------------------------------*/
-
- void restore_file(filename,size,csize,isindexfile)
- char *filename;
- int size;
- int csize;
- BOOLEAN isindexfile;
-
- /* return the restored file name */
- /* if it is the index file create it as orinally but append the temp drive to it */
-
- {
- char temppath[400];
- BOOLEAN compressed = FALSE;
- char lbuffer[bsize1];
- HANDLE hFile;
- int restore_size;
- DWORD lcopied = 0;
- unsigned int rvalue2;
- char TempFileName[400];
- char *nameloc;
- BOOLEAN done;
- int size_restored_so_far = 0;
- char lname[400];
- DWORD lowtime;
- DWORD hightime;
- DWORD lattrs;
- int lsize;
-
-
- if (csize > 0)
- {
- compressed = TRUE;
- restore_size = csize;
- /* create a temp file name/path to restore the file to */
-
- } /* compress */
- else
- {
- compressed = FALSE;
- restore_size = size;
- }
-
-
- /* get the temp path for a compress restore or restore of the index file */
-
- if (compressed || isindexfile)
- {
- lcopied = GetTempPath(100,temppath);
- if (lcopied <= 0)
- {
- report_error(" Cannot retrieve temporary directory path \n",0,severe);
- }
- else
- {
- /* now create a temp name and concat path to name */
- rvalue2 = GetTempFileName(temppath, /* dir. for temp. files */
- "NEW", /* temp. filename prefix */
- 0, /* create unique name w/ sys. time */
- (LPTSTR) TempFileName); /* buffer for name */
-
- if (rvalue2 == 0)
- {
- report_error(" Getting temp file name for decompression \n",rvalue2,severe);
- }
- else
- {
- /* concat path to name */
- /* we only need to name form the temp file as it appends \temp\ to it
- and we already have the temppath */
- nameloc = strrchr(TempFileName,'\\');
- /* skip over slash */
- ++nameloc;
-
- strcat(temppath,nameloc);
-
- if (debug)
- {
- printf("temp file for decompress = %s \n",temppath);
- fflush(stdout);
- }
-
- } /* name ok */
- } /* path ok */
- } /* for index or compressed file */
- else
- {
- /* not compressed or index means regular file uncompressed to copy file name to temppath */
- strcpy(temppath,filename);
- }
-
- if (debug)
- {
- printf("TapeIO:--> Restoring file about to read name block \n");
- fflush(stdout);
- }
- read_tape_block(lbuffer);
- if (debug)
- {
- printf("In restore file got name block number %s\n",lbuffer);
- fflush(stdout);
- }
-
-
- if (isindexfile)
- {
- /* get the size out of the buffer */
- sscanf(lbuffer,"%350s %10d",filename,&size);
- restore_size = size; /* index file is not compressed */
- if (debug)
- {
- printf("got name/size for index file name = %s size = %d \n",filename,size);
- fflush(stdout);
- }
- }
-
- /* check to make sure name in file matches restore name ignore check for index file */
- else
- { /* must skip over first 3 characters in buffer that had e:\ etc. in it */
-
- /* get times and attributes */
- lsize = 0;
- lattrs = 0;
- lowtime = 0;
- hightime = 0;
- sscanf(lbuffer + 3,"%s %d %d %d %d",lname,&lsize,&lattrs,&lowtime,&hightime);
-
- if (strncmp(filename,lname,strlen(filename)) != 0)
- {
- printf("Tape IO Error Name in buffer %350s does not match restore file name %s \n",
- lbuffer,filename);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- }
- /* now restore the file wherever (to temppath) */
-
- if (debug)
- {
- printf("attempting to open for write/restore: %s \n",temppath);
- fflush(stdout);
- }
-
- hFile = open_file_for_write(temppath);
- done = FALSE;
- size_restored_so_far = 0;
-
- /* problem here for file of 0 length we don't want to read the block or we are off when
- it comes to the next file since a block was not written out */
-
- /* restore the file pointed to by hfile */
- if (restore_size > 0)
- {
- do {
- read_tape_block(lbuffer);
-
- if (debug)
- {
- printf("TapeIO:-->Attempting to write the buff to file\n");
- fflush(stdout);
- }
-
- if ((size_restored_so_far + blocksize) <= restore_size)
- {
- write_file_block(hFile,lbuffer,blocksize);
- if ((size_restored_so_far + blocksize) == restore_size)
- done = TRUE;
-
- size_restored_so_far = size_restored_so_far + blocksize;
- }
-
- else /* write last partial block */
- {
- write_file_block(hFile,lbuffer,restore_size - size_restored_so_far);
- if (debug)
- {
- printf("Writing out last partial block of %d characters \n",
- restore_size - size_restored_so_far);
- fflush(stdout);
- }
- done = TRUE;
- size_restored_so_far = size_restored_so_far + (restore_size - size_restored_so_far);
-
- } /* bytes > 0 */
-
- } while (!done);
- } /* end of size > 0 */
-
- /* close the file handle */
- CloseHandle(hFile);
-
- /* now if the file was uncompressed or the index file
- we are done otherwise if it was compressed we need to decompress it to the
- original file */
-
- if (!compressed)
- {
- if (!isindexfile)
- set_file_info(filename,lowtime,hightime,lattrs);
-
- if ((!quiet_mode) && (!isindexfile))
- {
- printf("Restored Uncompressed file %s \n",filename);
- fflush(stdout);
- }
-
-
- ++filesuncompressed;
- total_bytes_read = total_bytes_read + size;
- /* if index file copy name to ifle name */
- if (isindexfile)
- strcpy(filename,temppath);
- }
-
- else /* compressed */
- {
- /* now decompress it */
- /* when decompressing the name somehow gets changes to / probably in the mkdir
- routine can't find it so copy it, and copy back after decompress */
- strcpy(lname,filename);
-
- if (decompress_file(filename,temppath) == -1)
- {
- printf("Warning couldn't decompress file %s \n",lname);
- printf("File NOT RESTORED \n");
- printf("Leaving temp file %s for an attempt at manual decompression. \n",temppath);
- fflush(stdout);
- }
- else
- {
- /* copy back */
- strcpy(filename,lname);
-
- set_file_info(filename,lowtime,hightime,lattrs);
- if (!quiet_mode)
- {
- printf("Restored Compressed file %s\n",filename);
- fflush(stdout);
- }
- ++filescompressed;
- total_bytes_read = total_bytes_read + csize;
- DeleteFile(temppath);
- }
-
- }
-
- }
-
- /* -------------------------------------------------------------------------------------- */
- void print_backup_stats()
- {
- DWORD total_time;
- unsigned long int minutes;
- unsigned long int backuprate;
-
- total_time = GetTickCount() - start_time;
-
- if (debug)
- printf("total time = %d \n",total_time);
-
- minutes = (int)(((float)total_time) / ((float)60000.0000));
- /* 60 * 1000 which equal the number
- of milliseconds in a minute */
-
- backuprate = (int)(((float)total_original_size / (float)minutes) / (float)1024.000);
- if (!quiet_mode)
- {
- printf("\n----------------------------------------------------------------\n");
- printf("Files Backed Up --> %d \n",filescompressed+filesuncompressed);
- printf(" No Compressed --> %d \n",filescompressed);
- printf(" No UnCompressed --> %d \n",filesuncompressed);
- printf("Files Skipped --> %d \n\n",filesskipped);
- printf("Original Size --> %d \n",total_original_size);
- printf("Size on Tape --> %d \n",total_backup_size);
- printf("Compression Ratio --> (%2d%%)\n\n",
- (int)(100.00 * (1.000 - (float)((float)total_backup_size/(float)total_original_size))));
- printf("Backup Time (minutes) --> %d \n",minutes);
- printf("Backup Rate K/minute --> %d \n",backuprate);
- printf("\n----------------------------------------------------------------\n");
- fflush(stdout);
- }
- }
-
- /* --------------------------------------------------------------------------------------- */
- void print_restore_stats()
- {
- DWORD total_time;
- unsigned long int minutes;
- unsigned long int restoreuprate;
-
- total_time = GetTickCount() - start_time;
-
- if (debug)
- printf("total time = %d \n",total_time);
-
- minutes = (int)(((float)total_time) / ((float)60000.0000));
- /* 60 * 1000 which equal the number
- of milliseconds in a minute */
-
- restoreuprate = (int)(((float)total_bytes_read / (float)minutes) / (float)1024.000);
- if (!quiet_mode)
- {
- printf("\n----------------------------------------------------------------\n");
- printf("Files Restored --> %d \n",filescompressed+filesuncompressed);
- printf(" No Compressed --> %d \n",filescompressed);
- printf(" No UnCompressed --> %d \n\n",filesuncompressed);
- printf("Total Bytes Restored --> %d \n",total_bytes_read);
- printf("Restore Time (minutes) --> %d \n",minutes);
- printf("Restore Rate K/minute --> %d \n",restoreuprate);
- printf("\n----------------------------------------------------------------\n");
- fflush(stdout);
- }
- }
- /* --------------------------------------------------------------------------------------- */
- void write_directory_file()
- {
- int fsize;
-
- fsize = ftell(TempIndexFile);
- close_index_file();
- /* size is not important for this file */
- /*ignore drive letter on file */
- /* we need the file size here otherwise it will not know how much to restore */
-
- backup_index_file(TempIndexFileName,fsize);
- /* now delete the file */
- DeleteFile(TempIndexFileName);
-
- }
-
- /* ----------------------------------------------------------------------------------- */
-
- void process_write_directory(SearchString,process_subdirs)
- char *SearchString;
- BOOLEAN process_subdirs;
-
- /* if process subdirs set first go through entire directory then do it again and process subdirs */
-
- {
- WIN32_FIND_DATA FileData;
- HANDLE hSearch;
- BOOLEAN done = FALSE;
- BOOLEAN rvalue;
- BOOLEAN onefound = FALSE;
-
- /* Start searching for files in the current directory. */
-
- hSearch = FindFirstFile(SearchString, &FileData);
- if (hSearch == INVALID_HANDLE_VALUE)
- {
- /* no files in search parameters */
- if ((debug) && (!process_subdirs))
- {
- printf("TapeIO:--> Warning no files found in search parameter %s \n",SearchString);
- fflush(stdout);
- }
- if (!process_subdirs)
- {
- FindClose(hSearch);
- return; /* cannot do this directory */
- }
- }
- else onefound = TRUE;
-
- if (onefound)
- {
- /* get size and process file only gets here if handle opened ok */
- /* skip directories */
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- mt_compress_file(FileData.cFileName,FileData.nFileSizeLow);
-
- /* loop through remainder of files */
-
- do {
- rvalue = FindNextFile(hSearch,&FileData);
- if ((rvalue == FALSE) && (GetLastError() == ERROR_NO_MORE_FILES))
- {
- done = TRUE;
- FindClose(hSearch);
- }
-
- else
- {
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- mt_compress_file(FileData.cFileName,FileData.nFileSizeLow);
- }
- } while (!done);
-
- } /* onefound */
-
- /* now if process subdirs set go through and stop at all subdirs and recurse */
- if (process_subdirs)
- {
- done = FALSE;
-
- /* Start searching for all subdirectories to recurse on */
- hSearch = FindFirstFile("*", &FileData);
- if (hSearch == INVALID_HANDLE_VALUE)
- {
-
- FindClose(hSearch);
- return; /* cannot do this directory */
-
- } /* no files */
-
- /* now check if file is subdir if so process if it is not "." or ".." */
- if ((strncmp(FileData.cFileName,".",1) != 0) &&
- (strncmp(FileData.cFileName,"..",2) != 0))
- {
- /* ok is not bs names */
-
- if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
-
- if (SetCurrentDirectory(FileData.cFileName) == FALSE)
- {
- printf("TapeIO:--> Warning Couldn't change directory to %s \n",FileData.cFileName);
- fflush(stdout);
- }
- else {
- process_write_directory(SearchString,process_subdirs);
- /* set current directory back */
- SetCurrentDirectory("..");
- }
- } /* is directory */
- } /* is not . or .. */
-
- /* when it returns recurse through remainder of subdirs */
- do
- {
- rvalue = FindNextFile(hSearch,&FileData);
- if ((rvalue == FALSE) && (GetLastError() == ERROR_NO_MORE_FILES))
- {
- done = TRUE;
- FindClose(hSearch);
- }
-
- else
- {
- /* now check if file is subdir if so process if it is not "." or ".." */
- if ((strncmp(FileData.cFileName,".",1) != 0) &&
- (strncmp(FileData.cFileName,"..",2) != 0))
- {
- /* ok is not bs names */
- /* instead of using getfileattrs dwFileAttributes */
-
- if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
-
- /* is a directory so set directory and recurse */
- if (SetCurrentDirectory(FileData.cFileName) == FALSE)
- {
- printf("TapeIO:--> Warning Couldn't change directory to %s \n",FileData.cFileName);
- fflush(stdout);
- }
- else {
- process_write_directory(SearchString,process_subdirs);
- SetCurrentDirectory("..");
- }
- } /* is directory */
- } /* is not . or .. */
-
- } /* else not last file */
- } while (!done);
-
- } /* process subdirs */
- }
-
- /* ------------------------------------------------------------------------------------------ */
- void mt_process_write_directory(LPVOID dummy)
- {
- /* call read process write directory */
- /* get the global values */
-
- if (debug_child)
- {
- printf("in top level mt process write directory search string = %s subdirs = %d \n",
- Global_SearchString,global_process_subdirs);
- fflush(stdout);
- }
- process_write_directory(Global_SearchString,global_process_subdirs);
- if (debug_child)
- {
- printf("in thread done processing files \n");
- fflush(stdout);
- }
- processed_all_files = TRUE;
- thread_active = FALSE;
-
- }
-
- /* ------------------------------------------------------------------------------------ */
- void space_sequential_filemarks(no_marks)
- DWORD no_marks;
- {
- DWORD rvalue;
-
- if (debug)
- {
- printf("Attempting to Space %d Seqential file marks\n",no_marks);
- fflush(stdout);
- }
-
- rvalue = SetTapePosition(hTape,TAPE_SPACE_SEQUENTIAL_FMKS,0,no_marks,0,FALSE);
- if (rvalue != NO_ERROR)
- report_error(" Tape positioning by sequential filemarks error ",rvalue,severe);
-
- }
- /* ------------------------------------------------------------------------------------ */
- void space_scsi_blocks(no_blocks)
- DWORD no_blocks;
- {
- DWORD rvalue;
-
- if (debug)
- {
- printf("Attempting to Space %d Scsi data blocks \n",no_blocks);
- fflush(stdout);
- }
-
- rvalue = SetTapePosition(hTape,TAPE_SPACE_RELATIVE_BLOCKS,0,no_blocks,0,FALSE);
- if (rvalue != NO_ERROR)
- report_error(" Tape positioning by scsi (relative) block error ",rvalue,severe);
-
- }
- /* ---------------------------------------------------------------------------------- */
-
- void eject_tape()
- {
- DWORD rvalue;
-
- rvalue = PrepareTape(hTape,TAPE_UNLOAD,FALSE);
-
- if (rvalue != NO_ERROR)
- {
- report_error("Ejecting tape ",rvalue,severe);
- }
- else
- {
- if (debug)
- {
- printf("TapeIO:-->Unloaded/Ejected Tape \n");
- fflush(stdout);
- }
- }
- }
-
- /* ---------------------------------------------------------------------------------- */
- void list_tape()
-
- {
-
- int element_number = 0;
-
- read_tape_index();
- printf("Number Saveset Name Original Size Compressed Size Date \n");
- printf("__________________________________________________________________\n");
- for (element_number = 0; element_number < max_save_sets; element_number++)
- dump_header_element(element_number);
- printf("\nListing Complete\n\n");
- fflush(stdout);
-
-
- }
-
- /* ------------------------------------------------------------------------------------ */
- int find_free_saveset_element()
-
- {
- BOOLEAN found = FALSE;
- int number = 0;
- int element_number = 0;
-
- for (element_number = 0; element_number < max_save_sets; element_number++)
- {
- if (strncmp(raw_tape_header.header[element_number].saveset_name,"EMPTY001_____",13) == 0)
- {
- number = element_number;
- found = TRUE;
- break;
- }
- }
- if (found)
- return(number);
- else return(-1);
-
- }
-
- /* ------------------------------------------------------------------------------------- */
- BOOLEAN get_index_file_entry(indexrec)
- INDEX_REC_TYPE *indexrec;
- {
-
- int lsize;
- int csize;
- int sblock;
- char ldate[9];
- char fname[351];
- int rvalue;
-
- rvalue = fscanf(TempIndexFile,"%350s %10d %10d %8s %10d \n",fname,&lsize,&csize,ldate,&sblock);
- if (rvalue == 0)
- report_error("Reading index file entry \n",0,severe);
-
- if (rvalue == EOF)
- {
- if (debug)
- {
- printf("EOF of index file found \n");
- fflush(stdout);
- }
- fclose(TempIndexFile);
- return(FALSE);
- }
-
- if (debug)
- {
- printf("Successfully retrieved index entry %s %d %d %8s %d\n",fname,lsize,csize,ldate,sblock);
- fflush(stdout);
- }
-
- /* fill in fields */
- indexrec->original_size = lsize;
- indexrec->compressed_size = csize;
- strcpy(indexrec->fname,fname);
- strcpy(indexrec->date,ldate);
- indexrec->start_block = sblock;
-
- if (debug)
- {
- printf("Successfully filled in index entry %s %d %d %8s %d\n",
- indexrec->fname,
- indexrec->original_size,
- indexrec->compressed_size,
- indexrec->date,
- indexrec->start_block);
- fflush(stdout);
- }
- return(TRUE);
-
- }
-
-
- /* -------------------------------------------------------------------------------------- */
-
- void list_index_file(indexfilename2,savesetname2)
- char *indexfilename2;
- char *savesetname2;
- {
-
-
- INDEX_REC_TYPE indexrec;
- BOOLEAN rvalue = FALSE;
-
-
- /* print header */
- printf("Saveset Listing for %s \n",savesetname2);
- printf("Original Size Compressed Size Date Start Block Filename\n");
- printf("__________________________________________________________________________\n");
-
- /* loop through and get file entry and print out contents */
- /* first open up the index file for reading */
-
- TempIndexFile = fopen(indexfilename2,"r");
-
- if (TempIndexFile == NULL)
- report_error(" Could not open temporary index file.",0,severe);
- else
- {
- if (debug)
- {
- printf("opened for read temp index file %s \n",indexfilename2);
- fflush(stdout);
- }
-
- tempindexfileopen = TRUE;
- }
-
- do {
- rvalue = get_index_file_entry(&indexrec);
- if (rvalue)
- {
- printf("%10d %10d %8s %10d %-s\n",
- indexrec.original_size,
- indexrec.compressed_size,
- indexrec.date,
- indexrec.start_block,
- indexrec.fname);
- fflush(stdout);
- }
-
- } while (rvalue == TRUE);
-
- printf("\nListing Complete\n\n");
- fflush(stdout);
- }
-
- /* ------------------------------------------------------------------------------------ */
- int find_saveset_element(saveset)
- char saveset[18];
-
- {
- BOOLEAN found = FALSE;
- int number = 0;
- int element_number = 0;
- int slen = strlen(saveset);
-
- for (element_number = 0; element_number < max_save_sets; element_number++)
- {
- if (strncmp(raw_tape_header.header[element_number].saveset_name,saveset,slen) == 0)
- {
- number = element_number;
- found = TRUE;
- break;
- }
- }
- if (found)
- return(number);
- else return(-1);
-
- }
-
- /* --------------------------------------------------------------------------------------*/
- void list_saveset(saveset)
- char *saveset[18];
- {
- int element_number;
- char indexfilename[400];
-
- read_tape_index();
- rewind_tape(FALSE);
- element_number = find_saveset_element(saveset);
-
- if (element_number < 0)
- {
- printf("Saveset %s Not found on the tape, use LKBACKUP -l for a listing. \n",saveset);
- fflush(stdout);
- close_tape();
- report_error(" ",0,severe);
- }
-
- /* now that we found the saveset space to the directory listing and read it */
- /* tape id 1
- 1 data 2 index 3 saveset 0
- 3 data 4 index 5 saveset 1
- 5 data 6 index 7 saveset 2
- 7 data 8 index 9 saveset 3
- .
- .
- .
- tape index [filemark]
-
- etc. */
- space_filemarks((element_number * 2) + 2);
- /* now recreate the file and list it */
- restore_file(indexfilename,0,0,TRUE);
-
- list_index_file(indexfilename,saveset);
- DeleteFile(indexfilename);
-
- rewind_tape(TRUE);
- close_tape();
-
- }
-
- /* --------------------------------------------------------------------------------- */
- void process_restore(indexfilename2,search_string)
- char *indexfilename2;
- char search_string[];
-
- {
-
- /* now go through each line in the index file and check if name matches */
-
- int lsize;
- int csize;
- int sblock;
- char ldate[9];
- char fname[351];
- int rvalue;
- BOOLEAN eof_found = FALSE;
- INDEX_REC_TYPE indexrec;
-
-
- /* first open up the index file for reading */
-
- TempIndexFile = fopen(indexfilename2,"r");
-
- if (TempIndexFile == NULL)
- report_error(" Could not open temporary index file.",0,severe);
- else
- {
- if (debug)
- {
- printf("opened for read temp index file %s \n",indexfilename2);
- fflush(stdout);
- }
-
- tempindexfileopen = TRUE;
- }
-
- do {
-
- rvalue = fscanf(TempIndexFile,"%350s %10d %10d %8s %10d \n",fname,&lsize,&csize,ldate,&sblock);
- if (rvalue == 0)
- report_error("Reading index file entry \n",0,severe);
-
- if (rvalue == EOF)
- {
- if (debug)
- {
- printf("EOF of index file found \n");
- fflush(stdout);
- }
- fclose(TempIndexFile);
- eof_found = TRUE;
- }
- else
- {
- if (debug)
- {
- printf("Successfully retrieved index entry %s %d %d %8s %d\n",fname,lsize,csize,ldate,sblock);
- fflush(stdout);
- }
-
- /* fill in fields */
- indexrec.original_size = lsize;
- indexrec.compressed_size = csize;
- strcpy(indexrec.fname,fname);
- strcpy(indexrec.date,ldate);
- indexrec.start_block = sblock;
-
- if (debug)
- {
- printf("Successfully filled in index entry %s %d %d %8s %d\n",
- indexrec.fname,
- indexrec.original_size,
- indexrec.compressed_size,
- indexrec.date,
- indexrec.start_block);
- fflush(stdout);
- }
- /* now check for match */
-
- if (wild_match(search_string,indexrec.fname))
- {
- if (debug)
- {
- printf("match found %s with %s \n",search_string,indexrec.fname);
- printf("current block = %d need to be at block %d \n",current_tape_block_number,
- indexrec.start_block);
- fflush(stdout);
- }
- if (current_tape_block_number < indexrec.start_block)
- {
- if (debug)
- {
- printf("attempting to space forward %d blocks \n",
- indexrec.start_block - current_tape_block_number);
- fflush(stdout);
- }
- space_scsi_blocks(indexrec.start_block - current_tape_block_number);
- current_tape_block_number = indexrec.start_block;
- }
- else if (current_tape_block_number > indexrec.start_block)
- {
- /* error condition */
- printf("TapeIO --->: Error tape position of %d > start block of %d shouldn't happen \n",
- current_tape_block_number,indexrec.start_block);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- /* now restore the file */
- restore_file(indexrec.fname,indexrec.original_size,indexrec.compressed_size,FALSE);
-
- } /* end of ok match */
-
- } /* eof not found */
-
- } while (!eof_found);
-
- }
- /* --------------------------------------------------------------------------------------*/
-
- void do_restore(saveset,search_string)
- char saveset[18];
- char search_string[];
- {
- int element_number;
- char indexfilename[400];
-
- total_bytes_read = 0;
- filescompressed = 0;
- filesuncompressed = 0;
-
- store_start_time();
- read_tape_index();
- rewind_tape(FALSE);
- element_number = find_saveset_element(saveset);
-
- if (element_number < 0)
- {
- printf("Saveset %s Not found on the tape, use LKBACKUP -l for a listing. \n",saveset);
- fflush(stdout);
- close_tape();
- report_error(" ",0,severe);
- }
-
- /* now that we found the saveset space to the directory listing and read it */
- /* tape id 1
- 1 data 2 index 3 saveset 0
- 3 data 4 index 5 saveset 1
- 5 data 6 index 7 saveset 2
- 7 data 8 index 9 saveset 3
- .
- .
- .
- tape index [filemark]
-
- etc. */
- space_filemarks((element_number * 2) + 2);
- /* now recreate the file and list it */
- restore_file(indexfilename,0,0,TRUE);
-
- /* now position to the backup set */
- rewind_tape(FALSE);
- space_filemarks((element_number * 2) + 1);
- current_tape_block_number = 0;
-
- /* now process the restore */
- total_bytes_read = 0;
- filescompressed = 0;
- filesuncompressed = 0;
-
- process_restore(indexfilename,search_string);
-
- /* now finish up */
- DeleteFile(indexfilename);
-
- rewind_tape(TRUE);
- close_tape();
-
- if ((filescompressed+filesuncompressed) <= 0)
- {
- printf("Warning no files in saveset %s found with search string %s \n",saveset,
- search_string);
- fflush(stdout);
- }
- else print_restore_stats();
-
- }
-
- /* ------------------------------------------------------------------------------------ */
-
- void do_backup(saveset_name,search_string,do_subdirs)
- char saveset_name[];
- char search_string[];
- BOOLEAN do_subdirs;
- {
- int free_element = 0;
- int taken_element = 0;
- DWORD dwThreadId;
-
- read_tape_index();
- rewind_tape(FALSE);
-
- free_element = find_free_saveset_element();
- if (free_element < 0)
- report_error("No room for any more savesets on tape, initialize it or switch tapes \n",0,severe);
-
- taken_element = find_saveset_element(saveset_name);
- if (taken_element >= 0)
- {
- printf("Error: Saveset %s Already exists on the tape... Try another name. \n",saveset_name);
- fflush(stdout);
- report_error(" ",0,severe);
- }
- else
- {
- store_start_time();
- /* now space to the correct file mark and start writing the backup */
- space_filemarks((free_element * 2) + 1 ); // 1 extra to get over header */
- /* reset the current tape block number to be relative from the beginning of the
- save set */
- current_tape_block_number = 0;
-
- /* this should put the tape ready to write the backup since there is two file marks
- per backup 1 before the backup and 1 between the backup and its directory so the
- directory can be retrieved quickly ie element 0 is filemark 0 element4 is file mark
- 8 */
-
- /* now do the backup */
- total_original_size = 0;
- total_backup_size = 0;
- filescompressed = 0;
- filesuncompressed = 0;
- processed_all_files = FALSE;
-
- /* initialize critical sections */
- InitializeCriticalSection(&Protected_Element);
- InitializeCriticalSection(&Protected_Queue);
- /* set globals here */
- global_process_subdirs = do_subdirs;
- strcpy(Global_SearchString,search_string);
-
- /* spawn a thread to process process_write_directory and go on here
- to call mt_backup_files */
- hThread = CreateThread(NULL,0,
- (LPTHREAD_START_ROUTINE)mt_process_write_directory,
- (LPVOID)filesuncompressed,0,&dwThreadId);
-
- if (hThread == NULL)
- {
- printf("ERROR: child thread for compression failed to start \n");
- printf(" error code = %d \n",GetLastError());
- report_error(" ",0,severe);
- }
- else
-
- {
-
- /* now that the thread started call the receive routine to get process
- the compressed files */
- thread_active = TRUE;
- /* allow this thread to sleep to give the compress thread time to do some
- processing */
- /* only sleep if doing compression */
- if (want_compression)
- Sleep(10000); /* ten seconds */
- mt_backup_files();
- }
-
-
- /* close the thread handle */
-
- CloseHandle(hThread);
- thread_active = FALSE;
-
-
- /* dont write marks if nothing was backed up */
- if ((filescompressed + filesuncompressed) == 0)
- {
- printf("Warning no files found in search parameter %s \n",search_string);
- fflush(stdout);
- }
- else
- {
- /* now write the file mark */
- write_filemarks(1);
- /* now write the directory file */
- write_directory_file();
- /* now write another file mark */
- write_filemarks(1);
-
- /* now fill in the total size/compressed size and rewind and rewrite header */
- /* also print out status messages */
- fill_in_header_element(saveset_name,total_original_size,total_backup_size,
- todays_date,free_element);
- /* now rewrite header */
- write_tape_index(TRUE);
- }
-
- /* now rewind tape */
- rewind_tape(TRUE);
- close_tape();
- print_backup_stats();
-
- } /* is room for new saveset */
- }
-
- /* ------------------------------------------------------------------------------------ */
- void disp_help()
- {
- printf(" USAGE for LKBACKUP Version 1.0 by L. Kahn 1993 \n");
- printf("LKBACKUP [-d -q -c -s] -b saveset_name search_string [include_subdirs] \n");
- printf("LKBACKUP [-d -q -c] -e [long_or_short] or LGKBACKUP -h or \n");
- printf("LKBACKUP [-d -q -c -s] -i or\n");
- printf("LKBACKUP [-d -q -c -s] -L saveset_name or\n");
- printf("LKBACKUP [-d -q -c -s] -l or \n");
- printf("LKBACKUP [-d -q -c -s] -r saveset_name search_string \n");
- printf("LKBACKUP [-d -q -c -s] -C no_of_good_savesets\n");
- printf("-b = Backup using the search string starting from the current directory, \n");
- printf(" including subdirs is optional and depedent on the value of \n");
- printf(" include_subddirs (t or f) \n");
- printf("-e = Erase tape where erasing long or short is optional. Default is short \n");
- printf("-h = Display this HELP message \n");
- printf("-i = Initialize tape (necessary before usage) \n");
- printf("-l = List tape (i.e., name of all savesets)\n");
- printf("-L = List the contents of a specific saveset \n");
- printf("-r = Restore the saveset_name using the search_string\n");
- printf("-C = Catalog tape (set index to say there are no_good_savesets) \n");
- printf(" Should be used if for some reason a backup fails or power goes out\n");
- printf(" during a backup. Rewrites the tape index, restores can then be \n");
- printf(" performed but further backups may be unreliable.\n");
- printf("-d = debug main, -q = quiet_mode, -D debug thread, -B debug both,\n");
- printf("-c = turn comprssion on, -s use setmarks not filemarks");
-
- }
-
- /* ------------------------- main program */
-
- void main(int argc,char *argv[])
- {
-
- int current_arg = 1;
- BOOLEAN more_args = TRUE;
- BOOLEAN done = FALSE;
- BOOLEAN do_subdirs = FALSE;
-
- file_mapping = FALSE;
- want_compression = FALSE; /* this also does not speed things up and uses more tape
- since the drive cannot keep streaming */
-
- fill_in_todays_date();
- if ((argc < 2) || (argc > 8))
- disp_help();
- else
-
- {
- /* process arguments */
- if (argv[current_arg][0] != '-')
- disp_help();
- else
-
- do
- {
- /* get the first one and if it doesn't start with a - we have a problem */
-
- switch (argv[current_arg][1])
- {
- case 'q':
- quiet_mode = TRUE;
- break;
-
- case 'c':
- want_compression = TRUE;
- break;
-
- /* undocumented default is no file mapping since this does not seem to speed
- things up */
- case 'm':
- file_mapping = TRUE;
- break;
-
- case 'd':
- debug = TRUE;
- break;
-
- case 'D':
- debug_child = TRUE;
- break;
-
- case 'B':
- debug_child = TRUE;
- debug = TRUE;
- break;
-
- case 'h':
- disp_help();
- done = TRUE;
- break;
-
- case 's':
- set_mark_positioning = TRUE;
- break;
-
- case 'C':
- if (argc < (current_arg + 2))
- {
- printf("ERROR: Number of good savesets needed for catalog procedure \n");
- fflush(stdout);
- }
- else {
- catalog_tape(argv[current_arg + 1]);
- }
-
- done = TRUE;
- break;
-
- case 'i':
- initialize_tape();
- done = TRUE;
- break;
-
- case 'l':
- list_tape();
- done = TRUE;
- break;
-
- case 'L':
- if (argc < (current_arg + 2))
- {
- printf("ERROR: Saveset name needed for tape listing. Use LKBACKUP -h for help \n");
- fflush(stdout);
- }
- else {
- list_saveset(argv[current_arg + 1]);
- }
-
- done = TRUE;
- break;
-
- case 'e':
- if (argc >= (current_arg + 2))
- {
- /* we have a short or long option so check it */
- switch (argv[current_arg+1][0])
- {
- case 's':
- erase_tape(FALSE);
- done = TRUE;
- break;
-
- case 'l':
- erase_tape(TRUE);
- done = TRUE;
- break;
-
- default:
- printf("ERROR: Legal options for erase are s for short erase or l for long erase \n");
- printf("Use LKBACKUP -h for help \n");
- fflush(stdout);
- done = TRUE;
- break;
- }
- if (done)
- break;
- } /* end have extra arg */
-
- else erase_tape(FALSE);
- done = TRUE;
- break;
-
- case 'b':
- /* make sure we have enough parms */
- if (argc < (current_arg+3))
- {
- printf("ERROR: The search_string and the saveset_name are required for a backup operation. \n");
- printf("Use LKBACKUP -h for help \n");
- fflush(stdout);
- done = TRUE;
- break;
- }
-
- /* check for include subdirs */
- if (argc == (current_arg + 4))
- {
-
- switch (argv[current_arg+3][0])
- {
- case 't':
- do_subdirs = TRUE;
- break;
- case 'f':
- do_subdirs = FALSE;
- break;
- default:
- printf("Error: The legal options for including subdirectories are t for f.\n");
- printf("Use LKBACKUP -h for help \n");
- fflush(stdout);
- done = TRUE;
- break;
- }
- } /* have optional parm */
- if (done)
- break;
-
- /* if we get here do the backup */
- if (debug)
- {
- printf("calling backup %s %s %d \n",argv[current_arg+1],
- argv[current_arg+2],do_subdirs);
- fflush(stdout);
- }
- do_backup(argv[current_arg+1],argv[current_arg+2],do_subdirs);
- done = TRUE;
- break;
-
- case 'r':
- /* make sure we have enough parms */
- if (argc < (current_arg+3))
- {
- printf("ERROR: The search_string and the saveset_name are required for a restore operation. \n"); printf("Use LKBACKUP -h for help \n");
- fflush(stdout);
- done = TRUE;
- break;
- }
-
- else
- {
- if (debug)
- {
- printf("Restore %s %s \n",argv[current_arg+1],argv[current_arg+2]);
- fflush(stdout);
- }
-
- do_restore(argv[current_arg+1],argv[current_arg+2]);
- done = TRUE;
- break;
- }
-
- default:
- printf("Illegal option %s \n",argv[current_arg]);
- disp_help();
- done = TRUE;
- break;
-
- } /* end of switch */
-
- ++current_arg;
- if (current_arg > argc)
- more_args = FALSE;
-
- } while ((!done) && (more_args));
-
- } /* end of ok case */
- } /* end of main */
-
-
-
-