home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / VIRUS / PVALIDAT.ZIP / VALIDATE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-05  |  7.3 KB  |  213 lines

  1. /***********************************************************************
  2. VALIDATE - Portable "C" version of a CRC validation program which uses
  3.            the same mechanisms as McAfee's VALIDATE program.
  4.  
  5. Arguments: Filename(s) - The name(s) of the file(s) to be checked.
  6.  
  7. Author: Gary P. Mussar (gmussar on BIX)
  8.  
  9. This code is released to the public domain.  There are no restrictions,
  10. however, acknowledging the author by keeping this comment around would
  11. be appreciated.
  12. ***********************************************************************/
  13. #include <stdio.h>
  14.  
  15. /* This includes are used for obtaining and displaying the last modified
  16.    time for the file. */
  17. #include <time.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20.  
  21. char version[] = {"Portable VALIDATE (Public Domain) V1.0 1991-01-05"};
  22.  
  23. /***********************************************************************
  24. The following is used to define the types of variable used to hold or
  25. manipulate CRCs. The 16 bit CRCs require a data type which is at least
  26. 16 bits. In addition, the data bits reserved for the CRC must be
  27. manipulated in an unsigned fashion.  It is possible to define a data
  28. type which is larger than required to hold the CRC, however, this is an
  29. inefficient use of memory and usually results in less efficient code
  30. when manipulating the CRCs.
  31. ***********************************************************************/
  32. #define CRC16 unsigned short
  33.  
  34. /***********************************************************************
  35. The coefficient of each term of the generator polynomial is represented
  36. by a bit in the polynomial array (except for the highest order term
  37. which is always assumed to be 1).  The coefficient for the second
  38. highest term in the LSB of the first byte of the polynomial array.
  39.  
  40. CRC Check 1
  41.   Polynomial   x^16 + x^15 + x^2 + 1    (16 bit BCS polynomial)
  42.   Generator is pre-initialized to 0x0000
  43.  
  44. CRC Check 2
  45.   Polynomial   x^16 + x^15 + x^10 + x^3
  46.   Generator is pre-initialized to 0x0000
  47. ***********************************************************************/
  48. CRC16 crcchk1[256*2];              /* Fast lookup table */
  49. CRC16 poly_crcchk1 = {0xa001};     /* Generator polynomial */
  50. CRC16 init_crcchk1 = {0x0000};     /* Pre-init value */
  51. CRC16 crc_crcchk1;                 /* CRC accumulator */
  52.  
  53. CRC16 crcchk2[256*2];             /* Fast lookup table */
  54. CRC16 poly_crcchk2 = {0x1021};    /* Generator polynomial */
  55. CRC16 init_crcchk2 = {0x0000};    /* Pre-init value */
  56. CRC16 crc_crcchk2;                /* CRC accumulator */
  57.  
  58. /* File stuff. The file is read (and CRCs calculated) in chunks. The
  59.    size of a chunk is determined by the size of buff[] */
  60. FILE *fp;
  61. char buff[8192];
  62.  
  63. /***********************************************************************
  64. Utilities for fast CRC using table lookup
  65.  
  66. CRC calculations are performed one byte at a time using a table lookup
  67. mechanism.  Two routines are provided: one to initialize the CRC lookup
  68. table; and one to perform the CRC calculation over an array of bytes.
  69.  
  70. A CRC is the remainder produced by dividing a generator polynomial into
  71. a data polynomial using binary arthimetic (XORs).  The data polynomial
  72. is formed by using each bit of the data as a coefficient of a term in
  73. the polynomial.  These utilities assume the data communications ordering
  74. of bits for the data polynomial, ie. the LSB of the first byte of data
  75. is the coefficient of the highest term of the polynomial, etc..
  76.  
  77. I_CRC16  -  Initialize the 256 entry CRC lookup table based on the
  78.             specified generator polynomial.
  79. Input:
  80.    Table[256]    - Lookup table
  81.    GenPolynomial - Generator polynomial
  82.  
  83. F_CRC16  -  Calculate CRC over an array of characters using fast
  84.             table lookup.
  85. Input:
  86.    Table[256]    - Lookup table
  87.    *CRC          - Pointer to the variable containing the result of
  88.                    CRC calculations of previous characters. The CRC
  89.                    variable must be initialized to a known value
  90.                    before the first call to this routine.
  91.    *dataptr      - Pointer to array of characters to be included in
  92.                    the CRC calculation.
  93.    count         - Number of characters in the array.
  94. ***********************************************************************/
  95. I_CRC16(Table, GenPolynomial)
  96.     CRC16 Table[256];
  97.     CRC16 GenPolynomial;
  98. {
  99.     int i;
  100.     CRC16 crc;
  101.  
  102.     for (i=0; i<256; i++)
  103.     {
  104.         crc = (CRC16) i;
  105.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  106.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  107.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  108.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  109.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  110.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  111.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  112.         crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
  113.  
  114.         Table[i] = crc;
  115.     }
  116. }
  117.  
  118. F_CRC16(Table, CRC, dataptr, count)
  119.     CRC16 Table[256];
  120.     CRC16 *CRC;
  121.     unsigned char *dataptr;
  122.     unsigned int count;
  123. {
  124.     CRC16 temp_crc;
  125.  
  126.     for (temp_crc = *CRC; count; count--)
  127.     {
  128.         temp_crc = (temp_crc >> 8) ^ Table[(temp_crc & 0xff) ^ *dataptr++];
  129.     }
  130.  
  131.     *CRC = temp_crc;
  132. }
  133.  
  134. /***********************************************************************
  135. Mainline
  136.  
  137. Each file specified on the input line is opened (in binary mode) and two
  138. CRCs are calculated over the data.
  139.  
  140. The CRC generators are initialized to 0 which means that null bytes (00)
  141. added to the front of a file will not affect the CRC (sigh, when will
  142. people ever learn).  Hopefully the file length will catch these kinds of
  143. problems.
  144. ***********************************************************************/
  145. main(argc, argv)
  146.     int argc;
  147.     char *argv[];
  148. {
  149.     unsigned len, files;
  150.     unsigned long byte_cnt;
  151.     struct stat statbuf;
  152.  
  153.     fprintf(stderr, "%s\n", version);
  154.  
  155.     /* We expect 1 or more arguments */
  156.     if (argc < 2)
  157.     {
  158.         fprintf(stderr, "This program prints the validation information for a file.\n");
  159.         fprintf(stderr, "Examples:\n");
  160.         fprintf(stderr, "          VALIDATE SCAN.EXE\n");
  161.         fprintf(stderr, "          VALIDATE SCANRES.EXE\n");
  162.         exit(1);
  163.     }
  164.  
  165.     /* Set up CRC tables */
  166.     I_CRC16(crcchk1, poly_crcchk1);
  167.     I_CRC16(crcchk2, poly_crcchk2);
  168.  
  169.     /* Loop through each filename on the invocation line */
  170.     for (files=1; files < argc; files++)
  171.     {
  172.         printf("\n         File Name:  %s\n", argv[files]);
  173.         fp=fopen(argv[files],"rb");
  174.         if    (!fp)
  175.         {
  176.             fprintf(stderr, "\n Sorry, I cannot open the input file.\n");
  177.             continue;
  178.         }
  179.  
  180.         /* Byte count and CRC generators to initial values */
  181.         byte_cnt = 0;
  182.         crc_crcchk1 = init_crcchk1;
  183.         crc_crcchk2 = init_crcchk2;
  184.  
  185.         /* Read the file in chunks until done */
  186.         while( (len = fread(buff,
  187.                             1,
  188.                             sizeof(buff),
  189.                             fp)           )   != 0)
  190.         {
  191.             /* Calculate CRC over this part of file */
  192.             F_CRC16(crcchk1, &crc_crcchk1, buff, len);
  193.             F_CRC16(crcchk2, &crc_crcchk2, buff, len);
  194.  
  195.             /* Byte count of file */
  196.             byte_cnt += len;
  197.         }
  198.  
  199.         /* Get file info so we can print last modified time for file */
  200.         fstat(fileno(fp), &statbuf);
  201.  
  202.         /* Give the user the results */
  203.         printf("               Size:  %ld\n", byte_cnt);
  204.         printf("               Date:  %s", ctime(&statbuf.st_mtime));
  205.         printf("File Authentication:\n");
  206.         printf("     Check Method 1 - %04X\n", crc_crcchk1);
  207.         printf("     Check Method 2 - %04X\n", crc_crcchk2);
  208.         fclose(fp);
  209.     }
  210.  
  211.     exit(0);
  212. }
  213.