home *** CD-ROM | disk | FTP | other *** search
- /*
- PROGRAM TO COMPARE THE CRC'S OF THE FILE LISTS IN
- CHECK$$$.NEW AND CHECK$$$.CRC
-
- Written by Ted H. Emigh -- emigh@ncsugn.uucp or NEMIGH@TUCC.BITNET
- Modifications by Jim Van Zandt <jrv@mitre-bedford.arpa>...
- Translated from Pascal to C.
- Explicitly checking for too many directories or too many files.
- Reading time and date of CRC check from old and new files.
- Optionally writing changes to hidden, system, or read-only files to screen.
- Writing deleted files out to FILES$$$.DEL.
- Customizing parameters at run time.
-
- */
-
- #include <string.h>
- #include <stdio.h>
-
- #define DESMET /* DeSmet C compiler */
- #define CUSTOMIZABLE /* enable run time customizing */
-
- /* the first three of these #defines should match the ones in FILECRC */
- #define COMPARE_PROGRAM_NAME "COMPARE.EXE"
- #define CHECK_NEW "CHECK$$$.NEW"
- #define CHECK_CRC "CHECK$$$.CRC"
-
- #define CHECK_OLD "CHECK$$$.OLD"
-
- #define FILES_NEW "FILES$$$.NEW"
- #define FILES_DEL "FILES$$$.DEL"
- #define FILES_MOD "FILES$$$.MOD"
- #define FILES_UPD "FILES$$$.UPD"
-
- #define FLAG1 "O4x7890aiudhvo8jh*&" /* 19 character strings to mark the */
- #define FLAG2 "0aijnvpo987G/&^%&_)" /* parameter block in the .EXE file */
-
- #define MAX_FILES 1500
- #define MAX_DIRECTORIES 200
-
- long lseek();
-
- #define VERSION_NUMBER "2.10"
-
- #define VERSION_DATE "19 November 1988"
-
-
- #define RR(a) if(debugging) printf a
- /* evaluates TRUE (nonzero) for equal strings */
- #define streq(a, b) (strcmp((a),(b)) == 0)
-
- /* These are the customizable parameters */
- typedef struct
- {char flag1[20];
- char compare_program[80];
- char new_crc_file[80];
- char cur_crc_file[80];
- char old_crc_file[80];
- char flag2[20];
- } PARMS;
-
- PARMS signature =
- {FLAG1,
- COMPARE_PROGRAM_NAME,
- CHECK_NEW,
- CHECK_CRC,
- CHECK_OLD,
- FLAG2
- };
-
-
-
- typedef char (months[12])[4];
- months month = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-
- typedef struct {
- char directory[65];
- int filenum;
- } directory_record;
- directory_record directories[MAX_DIRECTORIES];
-
- typedef struct {
- char name[13];
- int time_of_day;
- int date;
- long file_size;
- unsigned char attribute;
- int crc;
- char surviving;
- } file_rec;
- file_rec fileinfo[MAX_FILES];
-
- /**********
- show_dir(dirnum) int dirnum;
- { printf("directory %2d starting at file %3d is %s\n",
- dirnum,
- directories[dirnum].filenum,
- directories[dirnum].directory);
- }
-
- show_fil(filnum) int filnum;
- { char *get_time();
- printf("file %2d %12s %s %02x %10ld %04x %d\n",
- filnum,
- fileinfo[filnum].name,
- get_time(fileinfo[filnum].time_of_day, fileinfo[filnum].date),
- fileinfo[filnum].attribute,
- fileinfo[filnum].file_size,
- fileinfo[filnum].crc,
- fileinfo[filnum].surviving);
- }
- ***********/
-
- int timeofday, filedate; /* file creation time and date read from new file */
-
- int directory_number; /*
- directories[directory_number] is the first
- one with no directory name. However, after
- the old entries are all read,
- directories[directory_number].filenum is
- set to old_file.
- */
-
- /* Number of files in each category */
- int file_number;
- int old_file; /* fileinfo[old_file] is the first one with no entry */
- int new_file;
- int del_file;
- int ok_file;
- int update_file;
- int mod_file;
-
- int old_time, old_date, new_time, new_date; /* creation times of CRC files */
-
- char *cur_filename;
- char *new_filename;
-
- FILE *infile; /* file for reading file lists */
- FILE *newfile; /* file for writing names of new files created */
- FILE *delfile; /* file for writing names of deleted files */
- FILE *modfile; /* file for writing names of modified files */
- FILE *updatefile; /* file for writing names of updated files */
- FILE *tempfile; /* used in renaming files */
- int crc_value;
- char filename[13];
- char name_of_file[256];
- char crc_string[256];
- char instring[256];
- unsigned char attribute;
- long filesize;
- int new;
- int new_dir;
- int number_directories;
- int direct_count;
- int conservative = 0; /* nonzero if changes to hidden, system, or read-only
- files are to be displayed on the screen */
- int customizing = 0; /* nonzero if user wants to change file names */
- int debugging = 0; /* nonzero to enable trace output */
- char this_directory[65];
- char current_directory[65];
-
-
- /*
- This function returns a string up to the first space from infile
- */
-
- char *get_string()
- {
- int inchar;
- static char buf[256];
- char *s;
-
- /* Ignore any leading blanks */
- do {inchar = fgetc(infile);} while (inchar == ' ');
- s = buf;
- buf[0] = 0;
- /* Now, add on to string until a blank is found */
- do
- {*s++ = inchar;
- inchar = fgetc(infile);
- }
- while (inchar != ' ' && inchar != -1);
- *s = 0;
-
- return(buf);
- }
-
-
- /*
- returns zero if nonwhite characters remain in the file
- */
- eof(fp) FILE *fp;
- { int c;
- while(isspace(c = fgetc(fp))) {}
- if(c == -1) return 1;
- ungetc(c, fp);
- return 0;
- }
-
-
- /*
- Procedure to read in the old list of files and set up the list of
- directories (variable directories), and the list of files along with
- the various data (variable fileinfo).
- On return,
- old_file has the number of files in the list and
- number_directories has the number of directories.
-
- The variables directories and fileinfo have the following information:
- directories directory : Name of the directory (up to 64 characters)
- FileNum : Number of the name in fileinfo that contains
- the information for the first file in this
- directory.
-
- fileinfo name : Name of the file
- time_of_day : Time of day in DOS format
- date : Date in DOS format
- file_size : File size
- attribute : Attribute of the file
- crc : CRC of the file
-
- */
-
- /* // */
- void read_old_file()
- {
- fscanf(infile, "%d %d", &old_time, &old_date);
- /* Set to read Old List of Files */
- old_file = 0; /* Number of files in the list */
- number_directories = 0; /* Number of directories in the list */
- while (!eof(infile))
- {
- if(old_file == MAX_FILES)
- {printf("more than %d files in old CRC list - remainder ignored\n",
- MAX_FILES);
- break;
- }
- strcpy(this_directory, get_string()); /* Get the directory name */
- strcpy(fileinfo[old_file].name, get_string() );
- /* Get the file name */
- if (strcmp(this_directory, current_directory))
- {if(number_directories == MAX_DIRECTORIES - 1)
- {printf("more than %d directories in old CRC list - \
- remainder ignored\n",
- MAX_DIRECTORIES);
- break;
- }
-
- strcpy(current_directory, this_directory);
- strcpy(directories[number_directories].directory, this_directory);
- directories[number_directories].filenum = old_file;
- number_directories++;
- }
- fscanf(infile, "%d %d %d %ld %x\n",
- &(fileinfo[old_file].attribute),
- &(fileinfo[old_file].time_of_day),
- &(fileinfo[old_file].date),
- &(fileinfo[old_file].file_size),
- &(fileinfo[old_file].crc));
- fileinfo[old_file].surviving = 0;
- old_file++; /* Another file */
- }
- directories[number_directories].filenum = old_file;
- RR(("old file has %d directories and %d files\n", number_directories, old_file));
- }
-
-
- /*
- This function returns the time and date of file creation.
- date1 is the time of day in DOS directory format
- date2 is the date of creation in DOS directory format
-
- get_time is a string with the time and date (e.g., 14:31:42 8 AUG 1986)
- */
-
- char* get_time(date1, date2)
- int date1;
- int date2;
- {
- int hour, minute, second;
- int year, n_month, day;
- static char time[65];
-
- if (date2 != 0)
- {
- hour = (date1 >> 11);
- minute = ((date1 >> 5)) & 63;
- second = (date1 & 31) * 2;
- year = (date2 >> 9);
- n_month = ((date2 >> 5)) & 15;
- day = date2 & 31;
- sprintf(time, "%2d:%02d:%02d %2d %s %4d",
- hour, minute, second, day, month[n_month - 1], year + 1980);
- }
- else
- strcpy(time, " ");
- return(time);
- }
-
-
- /*
- Procedure to write the attribute, size and CRC for a file from
- the old list
-
- file_number is the number of the file name
-
- */
-
- void write_old_file(file_number)
- int file_number;
- {
- printf(" Attribute = %2d, Size = %10ld",
- fileinfo[file_number].attribute,
- fileinfo[file_number].file_size);
- printf(", CRC = %04x\n", fileinfo[file_number].crc);
- }
-
-
- /*
- Procedure to write the attribute, size and CRC for a file from
- the new list
-
- */
-
- void write_new_file()
- {
- fprintf(stdout , " Attribute = %2d, Size = %10ld", attribute, filesize);
- fprintf(stdout , ", CRC = %04x\n", crc_value);
- }
-
-
- /*
- Procedure to find the directory from the old list that matches the
- directory name from the new list
-
- If the directory name is the same as the current directory, then
- number and newdir are unchanged.
-
- If the directory name is not the same, and it exists on the old list,
- number will be the number of the old directory, and newdir is FALSE.
- The current directory will be updated.
-
- If the directory name is not the same, and it does not exist on the
- old list, newdir is FALSE. Number is number of directories + 1, but
- is never used.
-
- */
-
- void find_directory(number, newdir)
- int *number;
- int *newdir;
- {
- /* If the directory is the same, then the status of number and newdir */
- /* will not change */
- if ((strcmp(this_directory, current_directory) != 0))
- {
- /* search from the beginning -- nothing fancy */
- *number = 0;
- do
- {
- *number = *number + 1;
- }
- while (!(((*number > number_directories)
- || (streq(this_directory, directories[*number - 1].directory)))));
- *newdir = (*number > number_directories);
- strcpy(current_directory, this_directory);
- }
- }
-
-
- /*
- Procedure to find the file name. The directory name has been
- found prior to this time, so the starting point in the search
- has been found. The search will continue until the first file
- name in the next directory.
-
- */
-
- void find_file(number, new, number_begin, number_end)
- int *number;
- int *new;
- int number_begin;
- int number_end;
- {
-
- /*
- check fileinfo[i] for i in the range [number_begin ... number_end)
- or [directories[dn - 1].filenum ... directories[dn].filenum)
- */
- *new = 1;
- *number = number_begin - 1;
- do
- {
- *number = *number + 1;
- }
- while (*number < number_end &&
- (*new = strcmp(filename, fileinfo[*number].name)));
- }
-
- /*
- Write the full pathname of a file, advancing to the
- next line if the path is longer than 27 characters.
- */
- write_path(ofile, dir, name) FILE *ofile; char *dir, *name;
- { char path[60];
- sprintf(path, "%s\\%s", dir, name);
- if(strlen(path) > 28)
- fprintf(ofile, "%s\n ", path);
- else
- fprintf(ofile, "%-30s", path);
- }
-
- /*
- This procedure processes the new files. new_file is the counter
- for the number of new files. The file name and information is
- written to the file assigned to newfile.
- */
-
- void file_new()
- {
- new_file = new_file + 1;
- write_path(newfile, this_directory, filename);
- fprintf(newfile,
- "%s %2d %10ld %04x\n",
- get_time(timeofday, filedate),
- attribute, filesize, crc_value);
- }
-
- /*
- This procedure processes the deleted files. del_file is the counter
- for the number of deleted files. The file name and information is
- written to the file assigned to delfile.
- */
-
- void file_del(dirnum, filnum) int dirnum, filnum;
- {
- RR((" file #%d = %s was deleted\n", filnum, fileinfo[filnum].name));
- del_file = del_file + 1;
- write_path(delfile, directories[dirnum].directory, fileinfo[filnum].name);
- fprintf(delfile, "%s",
- get_time(fileinfo[filnum].time_of_day, fileinfo[filnum].date));
- fprintf(delfile, " %2d %10ld %04x\n",
- fileinfo[filnum].attribute,
- fileinfo[filnum].file_size,
- fileinfo[filnum].crc);
- }
-
- /*
- This procedure processes the updated files. Update_file is the counter
- for the number of updated files.
-
- format of file...
-
- Path Time Date Attr Length CRC
- I:\CHECK$$$.CRC 9:37:08 30 Aug 1988 32 1377 850C
- new: 9:37:08 30 Aug 1988 32 1377 850C
- ----22---1234567890---4444
- */
-
- void file_updated()
- { char old_attr;
-
- update_file = update_file + 1;
- old_attr = fileinfo[file_number].attribute;
- write_path(updatefile, this_directory, filename);
- RR((" file %s updated\n", filename));
- fprintf(updatefile, "%s",
- get_time(fileinfo[file_number].time_of_day,
- fileinfo[file_number].date));
- fprintf(updatefile, " %2d %10ld %04x\n",
- old_attr,
- fileinfo[file_number].file_size,
- fileinfo[file_number].crc);
- fprintf(updatefile, " new: %s",
- get_time(timeofday, filedate));
- fprintf(updatefile, " %2d %10ld %04x\n",
- attribute, filesize, crc_value);
- if(conservative && (old_attr & 0x07) )
- { /* system, hidden, or read-only attribute was set (note:
- we're checking the attribute in the OLD crc file) */
- printf("change to ");
- if(old_attr & 0x01) printf("read-only ");
- if(old_attr & 0x02) printf("hidden ");
- if(old_attr & 0x04) printf("system ");
- printf("file %s\\%s\n", this_directory, filename);
- printf("Old file: %s",
- get_time(fileinfo[file_number].time_of_day,
- fileinfo[file_number].date));
- write_old_file(file_number);
- printf("New file: %s", get_time(timeofday, filedate));
- write_new_file( );
- }
- }
-
-
- /*
- This procedure processes the files that have not been changed, modified
- or deleted. OK_file is the counter for the number of such files.
- */
-
- void file_ok()
- {
- RR((" file %s unchanged\n", filename));
- ok_file = ok_file + 1;
- }
-
-
- /*
- This procedure processes the files that have been modified without
- changing the directory entry date or time. Mod_file is the counter for
- the number of such files. In normal operations, this should not happen,
- so for such files, the name and date information is shown on the console
- and sent to the file assigned to modfile.
- */
-
- void bad_crc()
- {
-
- mod_file = mod_file + 1;
- printf("CRCs or file lengths do not match! File: %s\\%s\n",
- this_directory, filename);
- printf("Old file: %s",
- get_time(fileinfo[file_number].time_of_day,
- fileinfo[file_number].date));
- write_old_file(file_number);
- printf("New file: %s", get_time(timeofday, filedate));
- write_new_file( );
-
- write_path(modfile, this_directory, filename);
- fprintf(modfile, "%s %2d %10ld %04x\n",
- get_time(fileinfo[file_number].time_of_day,
- fileinfo[file_number].date),
- fileinfo[file_number].attribute,
- fileinfo[file_number].file_size,
- fileinfo[file_number].crc);
- fprintf(modfile,
- " new: %s %2d %10ld %04x\n",
- get_time(timeofday, filedate),
- attribute, filesize, crc_value);
- }
-
-
- /*
- Procedure to read the list of new files, and compare them to the
- old files. The various comparison types are processed according to
- the preceeding routines.
- */
-
- void read_new_file()
- {
- strcpy(current_directory, "");
- new_dir = FALSE;
- fscanf(infile, "%d %d", &new_time, &new_date);
-
- fprintf(newfile, "new files created on this disk\n");
- fprintf(newfile, "between %s ", get_time(old_time, old_date));
- fprintf(newfile, "and %s\n", get_time(new_time, new_date));
- fprintf(newfile, "\nPath Time ");
- fprintf(newfile, "Date Attr Length CRC\n");
-
- fprintf(delfile, "files deleted on this disk\n");
- fprintf(delfile, "between %s ", get_time(old_time, old_date));
- fprintf(delfile, "and %s\n", get_time(new_time, new_date));
- fprintf(delfile, "\nPath Time ");
- fprintf(delfile, "Date Attr Length CRC\n");
-
- fprintf(modfile, "files that were modified without updating ");
- fprintf(modfile, "the creation time/date\n");
- fprintf(modfile, "between %s ", get_time(old_time, old_date));
- fprintf(modfile, "and %s\n", get_time(new_time, new_date));
- fprintf(modfile, "\nPath Time ");
- fprintf(modfile, "Date Attr Length CRC\n");
-
- fprintf(updatefile, "files that were updated on this disk\n");
- fprintf(updatefile, "between %s ", get_time(old_time, old_date));
- fprintf(updatefile, "and %s\n", get_time(new_time, new_date));
- fprintf(updatefile, "\nPath Time ");
- fprintf(updatefile, "Date Attr Length CRC\n");
-
- while (!eof(infile))
- {
- strcpy(this_directory, get_string( ));
- /* First is the directory name */
-
- strcpy(filename, get_string( ));
- RR(("directory \"%s\", file \"%s\"\n", this_directory, filename));
- /* Next is the file name */
-
- fscanf(infile, "%d %d %d %ld %x\n",
- &attribute,
- &timeofday,
- &filedate,
- &filesize,
- &crc_value);
- /* Then the file parameters */
-
- /* Find the entry in the list of old files with the same name */
- find_directory(&directory_number, &new_dir);
- if (!new_dir)
- find_file(&file_number, &new,
- directories[directory_number - 1].filenum,
- directories[directory_number].filenum);
- /************
- if(debugging)
- {printf("checking directory %12s, file %12s: files [%2d,%2d) new_dir=%d new=%d\n",
- this_directory, filename,
- directories[directory_number - 1].filenum,
- directories[directory_number].filenum,
- new_dir, new);
- }
- ************/
- if (new_dir || new)
- /* New directory means new file */
- file_new( );
- else
- /* Existing file, compare the two */
- {
- RR((" file #%d = %s survived\n", file_number, filename));
- fileinfo[file_number].surviving = 1;
- if ((fileinfo[file_number].time_of_day != timeofday) ||
- (fileinfo[file_number].date != filedate) ||
- (fileinfo[file_number].attribute != attribute) )
- file_updated( );
- else
- if (fileinfo[file_number].crc != crc_value ||
- fileinfo[file_number].file_size != filesize)
- bad_crc( );
- else
- file_ok( );
- }
- }
- }
-
-
- help()
- {
- printf("\nusage: compare [options]\n");
- printf("options\n");
- printf(" -c conservative checking: report changes to \"hidden\", \n");
- printf(" \"system\", or \"read-only\" files to screen\n");
- #ifdef CUSTOMIZABLE
- printf(" -u user customizing - reset file names\n");
- #endif /* CUSTOMIZABLE */
- exit();
- }
-
-
- main(argc, argv) int argc; char *argv[];
- {
- int dirnum, filnum, ac, i;
- char *s, c, **av;
-
- /* Compare */
- printf("CRC file integrity comparison program\n");
- printf("Version %s, %s\n", VERSION_NUMBER, VERSION_DATE);
- printf("Written by Ted H. Emigh -- ");
- printf("emigh@ncsugn.uucp or NEMIGH@TUCC.BITNET\n");
- printf("Modified by James R. Van Zandt -- jrv@mitre-bedford.arpa\n");
-
- ac = argc;
- av = argv;
- argc = 1;
- while(--ac)
- {s = *++av;
- if(*s == '?') help();
- if(*s == '-')
- {while(c = *++s)
- {if(c == '?') help();
- else if(c == 'c') {conservative = 1;}
- else if(c == 'd') {debugging = 1;}
-
- #ifdef CUSTOMIZABLE
- else if(c == 'u') {customizing = 1;}
- #endif
-
- else printf("invalid command line switch %c ignored\n", c);
- }
- }
- else
- argv[argc++] = s;
- }
-
- #ifdef CUSTOMIZABLE
- if(customizing) rewrite_object_file();
- #endif
-
- number_directories = 1;
- strcpy(current_directory, "");
- strcpy(directories[0].directory, current_directory);
- directories[0].filenum = 0;
- /* Reset the counters for the various comparisons */
- new_file = 0;
- ok_file = 0;
- update_file = 0;
- mod_file = 0;
- /* Set up the input and output files */
- switch ((int)(argc - 1)) {
- case 0:
- {
- /* No command line parameters, use default names */
- cur_filename = signature.cur_crc_file;
- new_filename = signature.new_crc_file;
- }
- break;
- case 1:
- {
- /* File name with listing of new files has been given */
- cur_filename = signature.cur_crc_file;
- new_filename = argv[1];
- }
- break;
- default:
- {
- /* Both file names have been given */
- cur_filename = argv[2];
- new_filename = argv[1];
- }
- break;
- }
- /* Set up the various input and output files */
- infile = fopen(cur_filename, "r");
- if(!infile)
- {fprintf(stderr, "can't open %s\n", cur_filename);
- exit(1);
- }
- newfile = creat(FILES_NEW);
- delfile = creat(FILES_DEL);
- modfile = creat(FILES_MOD);
- updatefile = creat(FILES_UPD);
-
-
- printf("\nReading old CRC list from %s...\n", cur_filename);
- read_old_file( );
- fclose(infile);
-
- infile = fopen(new_filename, "r");
- if(!infile)
- {fprintf(stderr, "can't open %s\n", new_filename);
- fclose(newfile);
- fclose(delfile);
- fclose(modfile);
- fclose(updatefile);
- unlink(FILES_NEW);
- unlink(FILES_DEL);
- unlink(FILES_MOD);
- unlink(FILES_UPD);
- exit(1);
- }
-
- /**************
- if(debugging)
- {printf("number_directories=%d, old_file=%d\n",
- number_directories, old_file);
- for (dirnum = 0; dirnum < 5 && dirnum <= number_directories; dirnum++)
- show_dir(dirnum);
- for (filnum = 0;
- filnum < directories[number_directories].filenum;
- filnum++)
- show_fil(filnum);
- }
- **************/
-
- printf("Reading new CRC list from %s and comparing...\n\n", new_filename);
- read_new_file( );
- fclose(infile);
-
- for (dirnum = 0; dirnum < number_directories; dirnum++)
- {
- /**************
- if(debugging)
- {printf("directory %d, checking for deleted files in range [%d,%d)\n",
- dirnum,
- directories[dirnum].filenum,
- directories[dirnum + 1].filenum);
- }
- ***************/
- for (filnum = directories[dirnum].filenum;
- filnum < directories[dirnum + 1].filenum;
- filnum++)
- {if(fileinfo[filnum].surviving == 0)
- file_del(dirnum, filnum);
- }
- }
-
- /* Close the output files */
- fclose(newfile);
- fclose(delfile);
- fclose(modfile);
- fclose(updatefile);
-
- /*
- Print the summary numbers for this check,
- and erase the output files if they are empty
- */
- printf("\n");
- printf("%6d files in the last CRC check\n", old_file);
- printf("\n");
-
- printf( "%6d files were deleted", del_file);
- if(del_file) printf( " (see %s)", FILES_DEL);
- else unlink(FILES_DEL);
-
- printf("\n\n");
- printf("%6d files are the same as last time\n", ok_file);
-
- printf( "%6d new files", new_file);
- if(new_file) printf( " (see %s)", FILES_NEW);
- else unlink(FILES_NEW);
-
- printf("\n%6d updated files", update_file);
- if(update_file) printf( " (see %s)", FILES_UPD);
- else unlink(FILES_UPD);
-
- printf("\n%6d invalidly modified files", mod_file);
- if(mod_file) printf( " (see %s)", FILES_MOD);
- else unlink(FILES_MOD);
-
- printf("\n%6d files in this CRC check\n",
- ok_file + new_file + update_file + mod_file);
- printf("\n\n");
-
- /* No command line parameters -- Rename the files with the file lists */
- if (argc == 1)
- {
- unlink(signature.old_crc_file);
- rename(signature.cur_crc_file, signature.old_crc_file);
- rename(signature.new_crc_file, signature.cur_crc_file);
- printf("Old CRC file is now %s\n", signature.old_crc_file);
- printf("New CRC file is now %s\n", signature.cur_crc_file);
- printf("\n");
- }
- }
-
- #ifdef CUSTOMIZABLE
-
- /*
- customize parameters as instructed by the user
-
- */
-
- char *buffer;
- int buffer_length;
-
- customize(pp) PARMS *pp;
- { long ll, atol();
- int i;
- char time_string[9], *point, *index();
-
- printf("\nFile names may include drive letters and/or path names.\n");
-
- while(1)
- {printf(" new name for this program (default %12s): ",
- pp->compare_program);
- fgets(buffer, 100, stdin);
- buffer[strlen(buffer) - 1] = 0; /* zap the \n */
- strupr(buffer);
- if(buffer[0] == 0)
- break;
- point = index(buffer, '.');
- if(strlen(buffer) < sizeof(pp->compare_program) &&
- point && streq(point, ".EXE"))
- {strcpy(pp->compare_program, buffer);
- break;
- }
- }
-
- while(1)
- {while(1)
- {printf(" name for new CRC file (default %12s): ",
- pp->new_crc_file);
- fgets(buffer, 100, stdin);
- buffer[strlen(buffer) - 1] = 0; /* zap the \n */
- if(buffer[0] == 0) break;
- strupr(buffer);
- if(strlen(buffer) >= sizeof(pp->new_crc_file)) continue;
- strcpy(pp->new_crc_file, buffer);
- break;
- }
- while(1)
- {printf(" name for current CRC file (default %12s): ",
- pp->cur_crc_file);
- fgets(buffer, 100, stdin);
- buffer[strlen(buffer) - 1] = 0; /* zap the \n */
- if(buffer[0] == 0) break;
- strupr(buffer);
- if(strlen(buffer) >= sizeof(pp->cur_crc_file)) continue;
- strcpy(pp->cur_crc_file, buffer);
- break;
- }
- while(1)
- {printf(" name for old CRC file (default %12s): ",
- pp->old_crc_file);
- fgets(buffer, 100, stdin);
- buffer[strlen(buffer) - 1] = 0; /* zap the \n */
- strupr(buffer);
- if(strlen(buffer) >= sizeof(pp->old_crc_file)) continue;
- if(buffer[0]) strcpy(pp->old_crc_file, buffer);
- break;
- }
- if(strcmp(pp->old_crc_file, pp->new_crc_file) &&
- strcmp(pp->new_crc_file, pp->cur_crc_file) &&
- strcmp(pp->old_crc_file, pp->cur_crc_file)) break;
- printf("new, current, and old CRC file names must be different.\n");
- }
-
- printf("\nThe customizable values are now...\n");
- printf("\t\t compare program: %s\n", pp->compare_program);
- printf("\t\t new CRC file: %s\n", pp->new_crc_file);
- printf("\t\tcurrent CRC file: %s\n", pp->cur_crc_file);
- printf("\t\t old CRC file: %s\n", pp->old_crc_file);
- printf("\nrecord these values? ");
- if(tolower(getchar()) != 'y') exit();
- printf("\n");
-
- times(time_string); /* reseed the random number */
- srand(*(int *)(time_string + 7)); /* generator with the time of day */
-
- for (i = 0; i < 7; i++) /* change the search strings */
- {
- pp->flag1[ rand()%sizeof(pp->flag1) - 1 ] ^= (rand()&0x0f);
- pp->flag2[ rand()%sizeof(pp->flag2) - 1 ] ^= (rand()&0x0f);
- }
- }
-
- /* convert all characters in a string to upper case */
- strupr(s) char *s;
- { while(*s)
- {*s = toupper(*s);
- s++;
- }
- }
-
-
- /*
- based on a parameter update program in DeSmet Gazette, Dec 86
- by King Computer Services, Inc.
- modified for DeSmet environment by Pacific Data Works
- modified to search the path by J. R. Van Zandt
- */
- /* rewrite_object_file - change customizable parameters in file */
- rewrite_object_file()
- { long lseek(), findinst(), fpos, c;
- FILE *exefile; /* file to be modified */
- int j;
- char *pname();
- PARMS file_parms;
-
- buffer = fileinfo;
- buffer_length = sizeof(fileinfo);
-
- printf("\nCOMPARE user customization...\n");
-
- if(!pname(name_of_file, sizeof(name_of_file) - 1))
- strcpy(name_of_file, signature.compare_program);
-
- /* open for binary update */
- while((exefile = open(name_of_file,2)) == ERR)
- {printf("file %s not found\n", name_of_file);
- printf("path for this program (<return> to abort): ");
- fgets(name_of_file, sizeof(name_of_file) - 1, stdin);
- name_of_file[strlen(name_of_file) - 1] = 0; /* zap the \n */
- if(name_of_file[0] == 0) exit(1);
- strupr(name_of_file);
- }
- printf("%s opened for updating\n", name_of_file);
-
- fpos = findinst(exefile, &signature, signature.flag2,
- buffer, buffer_length);
-
- lseek(exefile, fpos, 0);
- fread(&file_parms, 1, sizeof(signature), exefile);
-
- lseek(exefile, fpos + 1, 0);
- if(findinst(exefile, &signature, signature.flag2,
- buffer, buffer_length))
- {/*
- We've found a second copy of the flag strings which
- surround the parameter block. This probably means the
- compiler left an extra copy of the flag strings in some
- buffer, then included the buffer in the compiled code. To
- work around the problem, make some change to the source
- code like adding a big string, then recompile. Changing
- the flag strings might be a good idea, too - just in case
- they match a piece of object code somewhere!
- */
- fprintf(stderr,
- "more than one parameter block in .EXE file - \
- don't know which to use!");
- exit(1);
- }
-
- customize(&signature);
-
- lseek(exefile, fpos, 0);
- fwrite(&signature, 1, sizeof(signature), exefile);
- printf("recorded\n");
-
- fclose(exefile);
- exit(0);
- }
-
- /*
- pname - get pathname of currently running program (else returns 0)
- */
- char *pname(buf, max_chars) char *buf; int max_chars;
- { unsigned length, seg, off;
- /* [bp-2] [bp-4] [bp-6] */
-
- #ifdef DESMET
- #pragma ex+ /* enable #asm directive */
-
- #asm
- mov ax,3000h ; check if DOS 3.0 or later
- int 21H ; (force al = 0 in case of DOS 1)
- cmp al,3
- jb argv7 ; DOS 1 or 2, return null parameter
- mov ax,cs
- sub ax,10h ; calculate PSP segment (for DeSmet compiler)
- mov es,ax
- mov es,es:[2ch] ; get environment segment from PSP
- mov ax,es
- mov [bp-4],ax ; seg = environment segment
- xor di,di ; find the program name by
- xor al,al ; first skipping over all the
- mov cx,-1 ; environment variables...
- cld
- argv9: repne scasb ; scan for double null (can't use
- scasb ; scasw since might be odd addr.)
- jne argv9 ; loop if it was a single null
- add di,2 ; skip count word in environment
- mov [bp-6],di ; off = program name offset
- mov cx,-1 ; now find its length...
- repne scasb ; scan for another null byte
- not cx ; convert cx to length
- dec cx
- jmp argvx
- ; REP MOVSB ; es:di++ = ds:si++, while(cx--)
-
- argv7: xor cx,cx
- argvx: mov [bp-2],cx ; length = program name length
- #endasm
-
- #else
- return 0;
- #endif /* DESMET */
-
- if(length == 0)
- return 0;
- if(length > max_chars) length = max_chars;
- _lmove(length, off, seg, buf, _showds());
- return buf;
- }
-
- /*
- This is the generic routine to find a flag string in an .exe file
- to be used as a pointer to the beginning of installable parameters.
- Returns a long containing the position of the flag, or zero if the
- flag is not found. File pointer points to the beginning of the
- struct. Buffer, which must be long enough, contains the structure
- starting at the flag.
-
- Method...
- 1. Read bytes into a buffer at least as long as the struct.
- 2. Search the buffer for a match on both flags.
- 3. If no match, move data at end of buffer to beginning of buffer,
- read in another batch from file.
- 4. Go to 2 until match found.
- 5. When match found, move matched code to head of buffer.
- 6. lseek to the file position found and return the fpos.
- */
- long findinst(filen, flag1, flag2, buffer, buflen)
- FILE *filen;
- char *flag1, *flag2, *buffer;
- unsigned buflen;
- { long f_pos;
- int nomatch, len;
- int structlen;
- int i, istop, j, k;
-
- nomatch = 1; /* initialize status to "no match" */
- structlen = flag2 - flag1 + strlen(flag2) + 1;
-
- f_pos = fseek(filen, 0L, 1);
- len = 0;
- while(nomatch)
- {len += read(filen, &buffer[len], buflen - len - 1);
- if(len < structlen) /* if we couldn't read enough bytes */
- return(0L);
-
- i = 0; /* step through buffer char by char */
- istop = len - structlen + 1;
-
- while(((buffer[i] != *flag1)||
- (nomatch = strcmp(&buffer[i], flag1))||
- (nomatch = strcmp(&buffer[i + flag2 - flag1], flag2))) &&
- (i < istop))
- i++; /* searching for the flags */
- if (nomatch)
- {/*
- if not found, move the tail end of the data to the head
- of the buffer, set the number of bytes in the buffer,
- reset file pointer, and return for another read
- */
- f_pos += i;
- for (j = 0; i < len; ) buffer[j++] = buffer[i++];
- len = j;
- }
- else
- {f_pos += i; /* update filepointer with the pos of match */
- /* move structure to head of buffer */
- for (j = 0; j < structlen; ) buffer[j++] = buffer[i++];
-
- }
- }
- lseek(filen, f_pos, 0); /* set file pointer to beginning of structure */
- return (f_pos);
- }
-
- #endif /* CUSTOMIZABLE */
-