/* ************************************************************************ * Verify files * i.e. ensure the specified files to have total length and checksum * unchanged * * Call the routine * verify catalog_file_name [-s] * where * 'catalog_file_name' (with default extension .VRF) specifies the text * file containing information about files being verified. * The fist record of the file is a comment and skipped. * The other catalog entries are of form * name of a file to be verified * file length in blocks * file check sum (modulo 2^32) * date when information about this file was set * verify program may work in two modes. When mode 'set' is specified * by the key '-s' in the command string, the program fills in * 'file length' and 'file checksum' fields in each catalog entry. * In 'check' mode (set on default) the program reads catalog, for * each file obtains its length and checksum and compares them with * the values in the catalog entry. When they are same the file is * considered to be verified OK. * ************************************************************************ */ #include #include /* *----------------------------------------------------------------------- * Calculate checksum of a file */ static long int checksum(file) FILE *file; /* Assumed to be opened in BIN */ { /* mode */ long int sum = 0; while( !feof(file) ) sum += getw(file); return sum; } /* *======================================================================== * Mainline processing */ char Filename [16]; /* Name of the file to be verfd */ int Filesize; /* File size in blocks */ long int Checksum; /* File checksum */ char Datetime [25]; /* Date and time in form */ /* THU JAN 01 00:00:00 1970\0 */ /* Verify the file specifd by Filename */ /* and set Filesize and Checksum */ /* Return 1 if OK */ static int file_process() { FILE * fp; extern int $$flen; /* Length of the file just opend*/ fprintf(stderr,"Processing %-14s ... ",Filename); if( (fp = fopen(Filename,"rn")) == 0 ) { errmsg("Can't open: %s",errtxt()); return 0; /* Opening error occurred */ } Filesize = $$flen; Checksum = checksum(fp); if( ferror(fp) ) { errmsg("Read error: %s",errtxt()); fclose(fp); return 0; /* Reading error occured */ } fclose(fp); return 1; /* Successful completion */ } /* Processing in SET mode */ static set_mode_processing(catalog_file_name) char * catalog_file_name; { FILE *catif, /* Catalog input file */ *catof; /* Catalog output file */ char record [81]; /* A catalog record */ /* Open the catalog */ catif = fopenexc(catalog_file_name,"r","VRF"); catof = fopenexc(catalog_file_name,"w","VRF"); /* Skip a comment record */ fputs(fgets(record,sizeof(record)-1,catif),catof); while( !feof(catif) ) /* Main loop */ { if( ferror(catif) ) error("Error reading catalog: %s. Processing terminated",errtxt()); if( fgets(record,sizeof(record)-1,catif) == 0 )/*Get a catalog record*/ break; if( sscanf(record,"%16s",Filename) != 1 ) continue; /* Skip a bad catalog entry */ if( !file_processing() ) /* Error on opening or reading */ continue; /* file, skip the corr. cat recd*/ fprintf(catof,"%-16s %3d %8lx %s\n",Filename,Filesize,Checksum,Datetime); fprintf(stderr," Checksum is %8lx\n",Checksum); } fclose(catif); if( ferror(catof) ) { errmsg("\nError writing new catalog file. The catalog remains unchanged"); fpurge(catof); } else fclose(catof); } /* Processing in CHECK mode */ static check_mode_processing(catalog_file_name) char * catalog_file_name; { FILE *catif; /* Catalog input file */ char record [81]; /* A catalog record */ int old_filesize; /* Filesize from a catalog entry*/ long int old_checksum; /* Checksum from a catalog entry*/ int total_counter = 0; /* for files frocessed */ int ok_counter = 0; /* for files verified ok */ /* Open the catalog */ catif = fopenexc(catalog_file_name,"r","VRF"); fgets(record,sizeof(record)-1,catif); /* Skip a comment record */ while( !feof(catif) ) /* Main loop */ { if( ferror(catif) ) error("Error reading catalog: %s. Processing terminated",errtxt()); if( fgets(record,sizeof(record)-1,catif) == 0 )/*Get a catalog record*/ break; if( sscanf(record,"%16s %d %lx", Filename,&old_filesize,&old_checksum) != 3 ) continue; /* Skip a bad catalog entry */ total_counter++; if( !file_processing() ) /* Error on opening or reading */ continue; /* file, skip the corr. cat recd*/ if( Checksum == old_checksumi && Filesize == old_filesize ) { fprintf(stderr,"\b\b\b OK\r"); ok_counter++; } else errmsg("\n\tNew/old filesize %d/%d, new/old checksum %8lx/%8lx ***", Filesize,old_filesize,Checksum,old_checksum); } fclose(catif); fprintf(stderr,"\n\n%d files have been verified OK from the total %d\n", ok_counter, total_counter); } /* *======================================================================== * Initialization routines */ /* *----------------------------------------------------------------------- * Get the current date and time and fill in * Datetime string */ get_date_and_time() { long clock; /* Time in UNIX standard */ time(&clock); /* Get the UNIX-like time */ sprintf(Datetime,"%.24s",ctime(&clock)); /* and convert it to ASCII */ } /* *----------------------------------------------------------------------- * Root module * Parse the command string, set the mode and main control */ main(argc,argv) int argc; /* No. of arguments being passed*/ char *argv[]; /* Vector of pointers to args */ { char * catalog_file_name; int mode_SET = 0; /* 1 if mode is SET */ if(argc <= 1 || argc > 3) /* One or two arguments are */ { /* expected (except the pgm nam)*/ puts("\nVerify files\nUsage:"); puts("\n\tverify catalog_file_name [-s]"); puts("\nwhere key '-s' specifies for the SET mode"); exit(); } catalog_file_name = argv[1]; if( argc == 3 ) /* Next argument may be a key */ { register char *p = argv[2]; if( strcmp(p,"-s") != 0 ) error("\nIllegal key '%s' is specified. '-s' was expected",p); mode_SET = 1; /* Set the SET mode */ } get_date_and_time(); /* Double height header */ printf("\n\n\t\033#3* \033[1mVerify files\033[m *"); printf( "\n\t\033#4* \033[1mVerify files\033[m *"); printf("\n\nCatalog %s, mode \033[4m%s\033[m\n\n",catalog_file_name, ( mode_SET ? "SET" : "CHECK" ) ); if( mode_SET ) set_mode_processing(catalog_file_name); else check_mode_processing(catalog_file_name); }