home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / trojanpr / chksum.arc / CHKSUM.C next >
Text File  |  1988-04-06  |  7KB  |  201 lines

  1. /****************************************************************************/
  2. /***    CHKSUM.C -- computes and verifies a 16 bit CRC for any file.      ***/
  3. /***                Can be used to see if two files with the same or      ***/
  4. /***                different names are identical.  Can also be used to   ***/
  5. /***                make sure that no surreptitious changes have been     ***/
  6. /***                made to a file ... say by a virus.                    ***/
  7. /***                                                                      ***/
  8. /***    Written by Bob Taylor, 8602 Woodlake Dr., Richmond, VA 23229.     ***/
  9. /***    using Turbo C, V1.5    March 1,1988                               ***/
  10. /****************************************************************************/
  11. /***    Revision History:                                                  ***/
  12. /***       4/6/88  -- Added ERRORLEVEL control: 1 for mis-match, 0 for    ***/
  13. /***                  OK.  Allows automated use.  Also, added silent      ***/
  14. /***                  switch so that ERRORLEVEL is the only way a mis-    ***/
  15. /***                  match is reported.  (This may be DANGEROUS!)        ***/
  16. /***                                                                      ***/
  17. /***       3/13/88 -- Cleaned up comments and added "Hit any key ..."     ***/
  18. /***                  when incorrect chksum detected.  Also, changed      ***/
  19. /***                  emergency output to go directly to the console via  ***/
  20. /***                  cprintf and cputs, rather than to stderr.           ***/
  21. /****************************************************************************/
  22.  
  23. #include <dos.h>
  24. #include <dir.h>
  25. #include <string.h>
  26. #include <stdio.h>
  27. #include <conio.h>
  28. #include <stdarg.h>
  29. #include <fcntl.h>
  30.  
  31. #include "stoi.c"    /* String TO Integer -- interpret argv[].          */
  32. #include "crc16.c"    /* Table Lookup for 16 bit CRC, and updcrc macro. */
  33.  
  34. #define    odd(x) (1 == ((x) & 1))
  35. #define E(x)    fprintf(stderr,x)
  36.  
  37. #define FALSE    0
  38. #define TRUE    !FALSE
  39.  
  40. #define MISMATCH 1
  41.  
  42. unsigned int bufsiz;        /* Size of buffer to allocate for files.  */
  43. char * bufptr;                /* Ptr to buffer where files are read in. */
  44.  
  45.  
  46. /****************************************************************************/
  47. /*** usage() - display the syntax options for chksum                      ***/
  48. /****************************************************************************/
  49. void usage()
  50. {
  51.     E("syntax is: chksum filspec      -or-\n");
  52.     E("           chksum [-s] fil1 sum1 fil2 sum2 ... filn sumn\n");
  53.     E("In the first form, filspec may be a wildcard.  The\n");
  54.     E("checksum is calculated for all matching files.\n");
  55.     E("In the second, a checksum is calculated for each\n");
  56.     E("file, and compared to the number given after the file\n");
  57.     E("name on the command line.  Any mismatch is noted.\n");
  58.     E("\n-s indicates that chksum will be silent, i.e. only\n");
  59.     E("report mismatches via DOS's ERRORLEVEL.  It will be\n");
  60.     E("set to 1 if a mismatch occurs, 0 otherwise.\n\n");
  61.     exit(1);
  62. }
  63.  
  64.  
  65. /****************************************************************************/
  66. /*** dochksum(file name) -- calculate the CRC for a specified file. No    ***/
  67. /***    wildcards are allowed ... the file name must be fully specified.  ***/
  68. /****************************************************************************/
  69. int dochksum(char *path)
  70. {
  71.     unsigned int bytes;
  72.     int crc,fi;
  73.     register unsigned int i;
  74.  
  75.     if( -1 == (fi=open(path,O_RDONLY | O_BINARY)) ) {
  76.         fprintf(stderr,"chksum: Can't open %s\n ",path);
  77.         return(0);
  78.         }
  79.  
  80.     crc=0;
  81.     while( 0 < (bytes=read(fi,bufptr,bufsiz)) )
  82.     {
  83.         for (i=0; bytes > i; i++)
  84.             crc = updcrc(bufptr[i],crc);    /* macro to do CRC table lookup */
  85.     }
  86.  
  87.     close(fi);
  88.     return(crc);
  89. }
  90.  
  91.  
  92. /****************************************************************************/
  93. /***  showcksum(file spec) -- Given a file spec, which may be a wild-card,***/
  94. /***    calculate a CRC for each matching file.  Include Hidden and System***/
  95. /***    files, since they are most prone to viral infection.              ***/
  96. /****************************************************************************/
  97. void showcksum(char *fn)
  98. {
  99.     struct ffblk fil;
  100.     char    path[MAXPATH],dr[MAXDRIVE],dir[MAXDIR],fin[MAXFILE],ex[MAXEXT];
  101.     char    *pathend;
  102.     int        crc;
  103.  
  104.     if( 0!=findfirst(fn,&fil,FA_HIDDEN | FA_SYSTEM) ) {
  105.         fprintf(stderr,"chksum: can't find file %s\n",fn);
  106.         exit(3);
  107.         }
  108.  
  109.     fnsplit(fn,dr,dir,fin,ex);
  110.     strcpy(path,dr);
  111.     strcat(path,dir);
  112.     pathend = path + strlen(path);
  113.  
  114.     do {
  115.         strcpy(pathend,fil.ff_name);
  116.         crc=dochksum(path);
  117.         printf("\n%s%s%-12s : %#06X (%u)",dr,dir,fil.ff_name,crc,crc);
  118.     }
  119.         while( 0==findnext(&fil) );
  120.    printf("\n");
  121. }
  122.  
  123.  
  124. /****************************************************************************/
  125. /*** verifycksum(file name,CRC) -- compute a CRC for the specified file,  ***/
  126. /***    and compare it with the given CRC value.  If they aren't the same,***/
  127. /***    Yell to the console (NOT stderr) using "cprintf and cputs".       ***/
  128. /****************************************************************************/
  129. int verifycksum(char *fil,int num,int silent)
  130. {
  131.     int crc;
  132.     int badfile = FALSE;    /* flag that indicates a mis-match found. */
  133.  
  134.     crc=dochksum(fil);
  135.  
  136.     if( crc != num ) {
  137.         if( silent == 0) {
  138.             cprintf(" * * * WARNING!! ... Checksum NOT verified. *\a *\a *\a\n");
  139.             cprintf(" File: %s  Submitted CRC: %#04X  Calculated CRC: %#04X\n\n",
  140.                     fil,num,crc);
  141.             cputs("Hit any key to continue ...");
  142.             getch();
  143.             cputs("\n\n");
  144.             }
  145.         badfile = MISMATCH;
  146.         }
  147.     return(badfile);
  148. }
  149.  
  150.  
  151. /****************************************************************************/
  152. /*** allocbuf() -- allocate a large input buffer for reading in the files,***/
  153. /***    and assign its size and location to global variables, for use in  ***/
  154. /***    dochksum().                                                          ***/
  155. /****************************************************************************/
  156. void allocbuf()
  157. {
  158.     bufsiz=coreleft()-256;
  159.     bufptr =(char *) malloc((size_t) bufsiz);
  160.     if( bufptr == NULL ) {
  161.         fprintf(stderr,"chksum: Can't allocate input buffer of size %u.\n",
  162.                 bufsiz);
  163.         exit(4);
  164.         }
  165. }
  166.  
  167.  
  168. /****************************************************************************/
  169. /*** MAIN -- check the number of command line arguments, and dispatch     ***/
  170. /***    accordingly.  If there are no arguments, show the syntax.          ***/
  171. /****************************************************************************/
  172. main(int argc,char **argv)
  173. {
  174.     int    i;
  175.     int silent = FALSE;    /* flag for the silent option        */
  176.     int rc = 0;            /* return code - sets ERRORLEVEL     */
  177.  
  178.     if( argc<2 ) usage();
  179.  
  180.     if( '-'==argv[1][0] )
  181.         if( (2==strlen(argv[1])) && ('s'==tolower(argv[1][1])) )
  182.                 silent = 1;
  183.         else {
  184.                 fprintf(stderr,"chksum: illegal option: %s\n\n",argv[1]);
  185.                 usage();
  186.              }
  187.  
  188.     if( (argc-silent)>2 && !odd(argc-silent) ) {
  189.         E("chksum: Files and Checksums must be paired.\n\n");
  190.         usage();
  191.         }
  192.     else {
  193.             allocbuf();
  194.             if( (argc-silent)==2 )    showcksum(argv[1+silent]);
  195.             else for( i=1+silent; i<argc; i+=2)
  196.                         rc |= verifycksum(argv[i],stoi(&argv[i+1]),silent);
  197.          }
  198.     return(rc);
  199. }
  200.  
  201.