home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / chksum < prev    next >
Internet Message Format  |  1989-02-03  |  29KB

  1. Path: lll-winken!ames!mailrus!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i025: Yet Another Checksumming Program
  5. Message-ID: <47757@uunet.UU.NET>
  6. Date: 29 Jan 89 21:16:48 GMT
  7. Sender: allbery@uunet.UU.NET
  8. Reply-To: naz@hslrswi.UUCP (Norman H. Azadian)
  9. Lines: 900
  10. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  11. X-Arch-Keywords: c, bsd, ibmpc, crc-32
  12.  
  13. Posting-number: Volume 6, Issue 25
  14. Submitted-by: naz@hslrswi.UUCP (Norman H. Azadian)
  15. Archive-name: chksum
  16.  
  17. #--------------------------------CUT HERE-------------------------------------
  18. #! /bin/sh
  19. #
  20. # This is a shell archive.  Save this into a file, edit it
  21. # and delete all lines above this comment.  Then give this
  22. # file to sh by executing the command "sh file".  The files
  23. # will be extracted into the current directory owned by
  24. # you with default permissions.
  25. #
  26. # The files contained herein are:
  27. #
  28. # -rw-r--r--  1 naz          1991 Jan 25 15:14 readme
  29. # -rw-r--r--  1 naz           536 Jan 25 15:05 makefile
  30. # -rw-r--r--  1 naz           436 Jan 25 14:53 debug.h
  31. # -rw-r--r--  1 naz          2837 Jan 25 14:41 gen.h
  32. # -rw-r--r--  1 naz          8136 Jan 25 14:41 chksum.c
  33. # -rw-r--r--  1 naz         11016 Jan 25 15:14 crc32.c
  34. #
  35. echo 'x - readme'
  36. if test -f readme; then echo 'shar: not overwriting readme'; else
  37. sed 's/^X//' << '________This_Is_The_END________' > readme
  38. X
  39. XChksum is a little program that I've developed and used a lot over the
  40. Xyears. The prime difference between it and the ones that it copies, is
  41. Xthat it can read a list of pathnames from stdin.  This turns out to be
  42. Xvery handy indeed. Also, it uses a 32-bit CRC, which means that a false
  43. Xmatch is 2**16 times less likely than with the 16-bit brands.  It
  44. Xproduces identical results on both PCs and VAXen.
  45. X
  46. XThe 32-bit CRC routine was donated by kind souls on the net.  I have
  47. Xtweaked it for my use, principally by adding inline optimized assembly
  48. Xcode for my PC. I don't pretend to know what is going on inside, and I
  49. Xregard it as a minor miracle that it actually produces the same numbers
  50. Xon PCs as on VAXen.  Perhaps somebody will tell me if it produces the
  51. X"right" numbers.
  52. X
  53. XI've developed it on an Aztec C compiler, currently version 4.10a.  You
  54. Xshouldn't have much trouble porting it to your favorite compiler.  I
  55. Xhave found that on the VAX I had to comment-out the #asm stuff in
  56. Xcrc32.c, in spite of the fact that it is already conditionally compiled
  57. Xout.  I have stubbed-out my debugging stuff, so the printd()'s and
  58. Xinitdebug() won't produce any code.
  59. X
  60. XIf you don't have string.h, then you probably don't have the string
  61. Xlibrary either.  No sweat, all you need do is delete the include for
  62. Xstring.h, and add the following routine to chksum.c:
  63. X
  64. X    local void strcpy(dst, src)
  65. X    char *dst, *src;
  66. X        {
  67. X        while ((*dst++ = *src++) != '\0')
  68. X            continue;
  69. X        }
  70. X
  71. XYou'll need to remove the reference to the library in the makefile too.
  72. XIf all else fails, the DOS executable is now available at fine
  73. Xcomp.binaries.pc  newsgroups everywhere.
  74. X
  75. XI hereby donate this program to the Public Domain for any and all
  76. Xpurposes. Enjoy.
  77. X
  78. XHere is the output of "chksum -v *.h *.c makefile":
  79. X
  80. X26b5c1c7         436   debug.h
  81. X02180ae4        2837   gen.h
  82. X872b0f18        8136   chksum.c
  83. X6d239b68       11016   crc32.c
  84. X44bdd9f4         536   makefile
  85. X====================
  86. X86c94990       22961   Grand Totals for 5 files
  87. ________This_Is_The_END________
  88. if test `wc -c < readme` -ne 1991; then
  89.     echo 'shar: readme was damaged during transit (should have been 1991 bytes)'
  90. fi
  91. fi        ; : end of overwriting check
  92. echo 'x - makefile'
  93. if test -f makefile; then echo 'shar: not overwriting makefile'; else
  94. sed 's/^X//' << '________This_Is_The_END________' > makefile
  95. X#    /usr/bin/src    870407    NHA
  96. X
  97. X#this is for 4.3bsd
  98. XCOPT=        -O
  99. XCFLAGS=        -I. -c
  100. XLNFLAGS=    -o chksum
  101. XCC=            /bin/cc
  102. XLN=            /bin/cc
  103. X
  104. X#this is for the Aztec version 4.10a under DOS
  105. X#AOPT=        -186
  106. X#COPT=        +a +2
  107. X#AFLAGS=        -DMODEL=3 $(AOPT)
  108. X#CFLAGS=        -I. -ansi -c +l +b $(COPT)
  109. X#LNFLAGS=    -t -g
  110. X#LIBS=        -lstringl  -lcl
  111. X#CC=            /manx/cc.exe
  112. X#LN=            ln
  113. X#RM=            del
  114. X
  115. X.c.o:
  116. X    ${CC} ${CFLAGS} $<
  117. X
  118. X.c.asm:
  119. X    ${CC} -at ${CFLAGS} $<
  120. X
  121. X
  122. Xchksum.exe:        chksum.o  crc32.o
  123. X    $(LN)  $(LNFLAGS)  chksum.o  crc32.o  $(LIBS)
  124. X
  125. Xclean:
  126. X    -rm *.o
  127. X    -rm *.sym
  128. X    -rm *.dbg
  129. X    -rm chksum.exe
  130. ________This_Is_The_END________
  131. if test `wc -c < makefile` -ne 536; then
  132.     echo 'shar: makefile was damaged during transit (should have been 536 bytes)'
  133. fi
  134. fi        ; : end of overwriting check
  135. echo 'x - debug.h'
  136. if test -f debug.h; then echo 'shar: not overwriting debug.h'; else
  137. sed 's/^X//' << '________This_Is_The_END________' > debug.h
  138. X/*   /usr/include/stub/debug.h    890123  NHA */
  139. X/* This is the version for use with public sharing of my sources */
  140. X/* The intent is to neutralize initdebug() and printd() so that */
  141. X/* any compiler will swallow them without complaint */
  142. X/* You may have to tweak this for yours */
  143. X
  144. X#ifndef    __DEBUG__
  145. X#define    __DEBUG__
  146. X
  147. X/** #define printd    + **/
  148. X#define printd
  149. X#define initdebug(acptr,avptr,confile,lstfile,initstring)
  150. X
  151. X#endif    __DEBUG__
  152. ________This_Is_The_END________
  153. if test `wc -c < debug.h` -ne 436; then
  154.     echo 'shar: debug.h was damaged during transit (should have been 436 bytes)'
  155. fi
  156. fi        ; : end of overwriting check
  157. echo 'x - gen.h'
  158. if test -f gen.h; then echo 'shar: not overwriting gen.h'; else
  159. sed 's/^X//' << '________This_Is_The_END________' > gen.h
  160. X/*    /usr/include/stub/gen.h    890123    NHA    */
  161. X/* This is the version for use with public sharing of my sources */
  162. X/* The intent is to neutralize initdebug() and printd() so that */
  163. X/* any compiler will swallow them without complaint */
  164. X
  165. X#ifndef    __GEN__
  166. X#define    __GEN__
  167. X
  168. X#include    <stdio.h>
  169. X#include    <fcntl.h>
  170. X#include    <ctype.h>
  171. X/** #include    "config.h" **/
  172. X#include    <debug.h>
  173. X
  174. X#define    import            extern
  175. X#define    local            static
  176. X#define    export
  177. X/**    This will not work with prototypes in version 4.10a **/
  178. X/** typedef    char            bool; **/
  179. Xtypedef int                bool;
  180. X#define    NULLFP            ((int (*)())0)            /* NULL Function Pointer */
  181. X
  182. X#define    YES        1
  183. X#define    NO        0
  184. X#define    NOBREAK                /* used for a switch case which flows into next */
  185. X#define    CRLF    037            /* Unit Separator sometimes replaces \n\r pair */
  186. X
  187. X/*** NOTE that this include must follow the definition of bool ***/
  188. X/** #include    <window.h> **/                    /* Norman's direct windows */
  189. X/** import WINDOW    *wopen(char *dev); **/
  190. X
  191. X/* macros */
  192. X#define    abs(x)        ((x < 0) ? (-(x)) : (x))
  193. X#define    max(x,y)    (((x) < (y)) ? (y) : (x))
  194. X#define    min(x,y)    (((x) < (y)) ? (x) : (y))
  195. X
  196. X
  197. X/* for use with Aztec farcall(), sysint(), and segreg() functions */
  198. Xstruct regs        { int    ax, bx, cx, dx, si, di, ds, es; };
  199. Xstruct segregs    { unsigned    cs, ss, ds, es; };
  200. X
  201. X/* use this to fiddle with longs and pointers and such */
  202. Xunion u_long    {
  203. X                unsigned long            lunsigned;
  204. X                long                    lsigned;
  205. X                void                    *ptr;
  206. X                struct    {
  207. X                        unsigned        lo;
  208. X                        unsigned        hi;
  209. X                        }                half;
  210. X                struct    {
  211. X                        unsigned char    b0;        /* Least Significant byte */
  212. X                        unsigned char    b1;
  213. X                        unsigned char    b2;
  214. X                        unsigned char    b3;        /* Most Significant byte */
  215. X                        }                byte;
  216. X                };
  217. X
  218. X
  219. X#define    BIT0    0x0001
  220. X#define    BIT1    0x0002
  221. X#define    BIT2    0x0004
  222. X#define    BIT3    0x0008
  223. X#define    BIT4    0x0010
  224. X#define    BIT5    0x0020
  225. X#define    BIT6    0x0040
  226. X#define    BIT7    0x0080
  227. X#define    BIT8    0x0100
  228. X#define    BIT9    0x0200
  229. X#define    BIT10    0x0400
  230. X#define    BIT11    0x0800
  231. X#define    BIT12    0x1000
  232. X#define    BIT13    0x2000
  233. X#define    BIT14    0x4000
  234. X#define    BIT15    0x8000
  235. X
  236. X#define    BIT0L    0x00000001
  237. X#define    BIT1L    0x00000002
  238. X#define    BIT2L    0x00000004
  239. X#define    BIT3L    0x00000008
  240. X#define    BIT4L    0x00000010
  241. X#define    BIT5L    0x00000020
  242. X#define    BIT6L    0x00000040
  243. X#define    BIT7L    0x00000080
  244. X#define    BIT8L    0x00000100
  245. X#define    BIT9L    0x00000200
  246. X#define    BIT10L    0x00000400
  247. X#define    BIT11L    0x00000800
  248. X#define    BIT12L    0x00001000
  249. X#define    BIT13L    0x00002000
  250. X#define    BIT14L    0x00004000
  251. X#define    BIT15L    0x00008000
  252. X#define    BIT16L    0x00010000
  253. X#define    BIT17L    0x00020000
  254. X#define    BIT18L    0x00040000
  255. X#define    BIT19L    0x00080000
  256. X#define    BIT20L    0x00100000
  257. X#define    BIT21L    0x00200000
  258. X#define    BIT22L    0x00400000
  259. X#define    BIT23L    0x00800000
  260. X#define    BIT24L    0x01000000
  261. X#define    BIT25L    0x02000000
  262. X#define    BIT26L    0x04000000
  263. X#define    BIT27L    0x08000000
  264. X#define    BIT28L    0x10000000
  265. X#define    BIT29L    0x20000000
  266. X#define    BIT30L    0x40000000
  267. X#define    BIT31L    0x80000000
  268. X
  269. X#endif    __GEN__
  270. ________This_Is_The_END________
  271. if test `wc -c < gen.h` -ne 2837; then
  272.     echo 'shar: gen.h was damaged during transit (should have been 2837 bytes)'
  273. fi
  274. fi        ; : end of overwriting check
  275. echo 'x - chksum.c'
  276. if test -f chksum.c; then echo 'shar: not overwriting chksum.c'; else
  277. sed 's/^X//' << '________This_Is_The_END________' > chksum.c
  278. X/*  /usr/bin/src/chksum.c 880118  NHA */
  279. X
  280. X#define    DEBUG    0
  281. X#define    MAJOR    'P'
  282. X#define    MINOR    'C'
  283. X
  284. X#include    <gen.h>
  285. X#include    <string.h>
  286. X
  287. X#define    SUCCESS    0
  288. X#define    FAILURE    (!SUCCESS)
  289. X
  290. X
  291. X#ifdef __STDC__
  292. Ximport char                *gets(void *buffer);
  293. Ximport int                open(char *filename, int mode);
  294. Ximport int                read(int fd, void *buf, int count);
  295. Ximport int                close(int fd);
  296. Ximport char                *getenv(char *name);
  297. Ximport void                exit(int status);
  298. Ximport unsigned long    crc32buf(unsigned long initialSum,
  299. X                                        unsigned char *buf, unsigned count);
  300. X#else
  301. Ximport char                *gets();
  302. Ximport int                open();
  303. Ximport int                read();
  304. Ximport int                close();
  305. Ximport char                *getenv();
  306. Ximport void                exit();
  307. Ximport unsigned long    crc32buf();
  308. X#endif __STDC__
  309. X
  310. Xlocal unsigned char    buffer[BUFSIZ];            /* reads go into this buffer */
  311. Xlocal bool            showCount;                /* show the byte count [-c] */
  312. Xlocal bool            showError;                /* show Errors in any case */
  313. Xlocal bool            totalOnly;                /* don't show file sums [-t] */
  314. Xlocal bool            verbose;                /* print filenames [-v] */
  315. Xlocal bool            firstFile;                /* only true for 1st file */
  316. Xlocal unsigned        fileCount;                /* # of files processed OK */
  317. Xlocal unsigned        errorCount;                /* # of files with errors */
  318. Xlocal unsigned long    sum;                    /* checksum for a file */
  319. Xlocal unsigned long    grandSum;                /* checksum over all files */
  320. Xlocal unsigned long    byteCount;                /* byte count for a file */
  321. Xlocal unsigned long    grandByteCount;            /* byte count over all files */
  322. X
  323. X
  324. X
  325. X
  326. X/*+     c h k s u m
  327. X * Calculate two chksums for the file.
  328. X * One is simply the chksum of the bytes in the file.
  329. X * The other is updating the grandSum with the bytes in the file.
  330. X * The grandSum is only updated for files after the first file.
  331. X * The byteCount and grandByteCount variables are also updated.
  332. X * Return FAILURE for file errors, else SUCCESS.
  333. X */
  334. Xlocal bool chksum(fd)
  335. Xint fd;                                        /* File Descriptor */
  336. X    {
  337. X    int            status;                        /* status returned from sys calls */
  338. X
  339. X    printd(4, "chksum(%d)\n", fd);
  340. X
  341. X    sum       = 0L;
  342. X    while (1)
  343. X        {
  344. X        /* read next bufferload from the file */
  345. X        status = read( fd, buffer, sizeof buffer );
  346. X        printd(9, "read status=%d\n", status);
  347. X        if (status < 0)
  348. X            {
  349. X            printd(4, "chksum(): returning FAILURE\n");
  350. X            return FAILURE;
  351. X            }
  352. X        if (status == 0)
  353. X            break;                            /* End Of File */
  354. X
  355. X        /* update checksums */
  356. X        sum = crc32buf(sum, buffer, (unsigned)status);
  357. X        if ( ! firstFile )
  358. X            grandSum = crc32buf(grandSum, buffer, (unsigned)status);
  359. X
  360. X        /* update byte counts */
  361. X        byteCount += (unsigned long)status;
  362. X        grandByteCount += (unsigned long)status;
  363. X
  364. X        printd(8, "sum=%08lx, grandSum=%08lx, byteCount=%ld, grandByteCount=%ld\n",
  365. X          sum, grandSum, byteCount, grandByteCount);
  366. X        }
  367. X
  368. X    printd(4, "chksum(): returning SUCCESS with sum=%08lx,  grandSum=%08lx\n",
  369. X      sum, grandSum);
  370. X    return SUCCESS;
  371. X    }
  372. X
  373. X
  374. X
  375. X/*+        s u m F i l e
  376. X * Given a filename, calculate the checksum, do any necessary displaying,
  377. X * and update all the necessary global variables.
  378. X * If the filename is a NULL pointer or a pointer to '\0', we use stdin.
  379. X * In the event of file access errors, a sum of 0 is printed.
  380. X */
  381. Xlocal void sumFile(filename)
  382. Xchar    *filename;
  383. X    {
  384. X    int fd;                                    /* File Descriptor */
  385. X    char name[88];
  386. X    bool isBad;                                /* YES for file errors */
  387. X
  388. X    printd(4, "sumFile(%s)\n", filename);
  389. X    byteCount = 0L;
  390. X    
  391. X    /* open input file.  NULL or ptr to '\0' is taken to mean standard input */
  392. X    if (filename == NULL   ||   filename[0] == '\0')
  393. X        {
  394. X        strcpy(name, "--Stdin--");
  395. X        fd = fileno(stdin);
  396. X        }
  397. X    else
  398. X        {
  399. X        strcpy(name, filename);
  400. X        fd = open(filename, O_RDONLY);
  401. X        if (fd < 0)
  402. X            {
  403. X            isBad = YES;
  404. X            ++errorCount;
  405. X            sum = 0L;
  406. X               printd(2, "sumFile(%s): can't open file for read\n", filename);
  407. X            if (showError)
  408. X                fprintf(stderr, "chksum: can't open \"%s\" for reading\n",
  409. X                                filename);
  410. X            }
  411. X        else
  412. X            isBad = NO;
  413. X        }
  414. X
  415. X    /* calculate the checksum */
  416. X    if (0 <= fd)
  417. X        {
  418. X        if (chksum(fd) == SUCCESS)
  419. X            {
  420. X            isBad = NO;
  421. X            ++fileCount;
  422. X            if (firstFile)
  423. X                {
  424. X                grandSum = sum;
  425. X                firstFile = NO;
  426. X                }
  427. X            }
  428. X        else
  429. X            {
  430. X            isBad = YES;
  431. X            ++errorCount;
  432. X            sum = 0L;
  433. X            printd(2, "sumFile(%s): error reading file\n", name);
  434. X            if (showError)
  435. X                fprintf(stderr, "chksum: error reading file \"%s\"\n",
  436. X                                filename);
  437. X            }
  438. X        if (fd != fileno(stdin))
  439. X            close(fd);
  440. X        }
  441. X
  442. X    /* report the results */
  443. X    if ( ! totalOnly)
  444. X        {
  445. X        printf("%08lx", sum);
  446. X        if (showCount)
  447. X            printf("  %10lu", byteCount);
  448. X        if (verbose)
  449. X            if (isBad)
  450. X                printf("   %s     *** ERROR ***", name);
  451. X            else
  452. X                printf("   %s", name);
  453. X        putchar('\n');
  454. X        }
  455. X    printd(4, "sumFile(): returning\n");
  456. X    }
  457. X
  458. X
  459. X
  460. X/*+        u s a g e
  461. X * Spew out the help message.
  462. X */
  463. Xlocal void usage()
  464. X    {
  465. X    fprintf(stderr, "chksum -- calculate 32-bit checksum for file(s), output to stdout\n");
  466. X    fprintf(stderr, "Usage:    chksum   [-cehtv]    {file|--|-}...\n");
  467. X    fprintf(stderr, "-c    Count bytes also\n");
  468. X    fprintf(stderr, "-e    give extended Error reports on stderr\n");
  469. X    fprintf(stderr, "-h    Help; give this help message and exit\n");
  470. X    fprintf(stderr, "-t    Total only; don't list sum for each file\n");
  471. X    fprintf(stderr, "-v    Verbose; list filenames along with checksums\n");
  472. X    fprintf(stderr, "--    take filenames from stdin, 1 name per line\n");
  473. X    fprintf(stderr, "-    take stdin as a file\n");
  474. X    fprintf(stderr, "Filenames may be mixed with options.\n");
  475. X    fprintf(stderr, "Exit status is the number of file errors encountered.\n");
  476. X    exit(1);
  477. X    }                                        /* usage */
  478. X
  479. X
  480. X
  481. X/*+     m a i n
  482. X * See usage() for command line parameters.
  483. X */
  484. Xexport int main(ac, av)
  485. Xint ac;
  486. Xchar **av;
  487. X    {
  488. X    char    *p;
  489. X    char    line[BUFSIZ];                    /* for reading from stdin */
  490. X    char    switchar;
  491. X
  492. X    /* initialize */
  493. X    initdebug(&ac, &av, "/dev/con", "/dev/fifo", "**0");
  494. X    showCount      = NO;                    /* default is no byte counts */
  495. X    showError      = NO;                    /* default is no reports on stderr*/
  496. X    totalOnly      = NO;                    /* default is show all checksums */
  497. X    verbose        = NO;                    /* default is no filenames */
  498. X    firstFile      = YES;                    /* no files checksummed yet */
  499. X    fileCount      = 0;
  500. X    errorCount     = 0;
  501. X    grandSum       = 0L;
  502. X    grandByteCount = 0L;
  503. X    p = getenv("SWITCHAR");
  504. X    if (p == NULL)
  505. X        switchar = '-';
  506. X    else
  507. X        switchar = *p;
  508. X
  509. X    /* process command line arguments */
  510. X    for (--ac, ++av   ;   0 < ac   ;   --ac, ++av)
  511. X        {
  512. X        printd(7, "main():  ac = %d,  *av = '%s'\n", ac, *av); 
  513. X        if (av[0][0] == switchar)
  514. X            switch (av[0][1])
  515. X                {
  516. X            case 'C':
  517. X            case 'c':
  518. X                showCount = YES;
  519. X                break;
  520. X            case 'E':
  521. X            case 'e':
  522. X                showError = YES;
  523. X                break;
  524. X            case 'H':
  525. X            case 'h':
  526. X                usage();
  527. X                break;
  528. X            case 'T':
  529. X            case 't':
  530. X                totalOnly = YES;
  531. X                break;
  532. X            case 'V':
  533. X            case 'v':
  534. X                verbose = YES;
  535. X                break;
  536. X            case '-':                        /* take filenames from stdin */
  537. X                while (gets(line) != NULL)
  538. X                    sumFile(line);
  539. X                if (showError  &&  ferror(stdin))
  540. X                    fprintf(stderr, "chksum: error reading standard input\n");
  541. X                clearerr(stdin);
  542. X                break;
  543. X            case '\0':
  544. X                sumFile(NULL);                /* use standard input for file */
  545. X                break;
  546. X            default:
  547. X                fprintf(stderr, "chksum: unknown option  %s\n", av[0]);
  548. X                }                            /* switch */
  549. X        else
  550. X            sumFile(av[0]);                    /* file */
  551. X        }
  552. X
  553. X
  554. X    /* put out the Grand Total */
  555. X    if ((fileCount + errorCount)  ==  0)
  556. X        usage();                            /* no files specified */
  557. X    else if ((fileCount + errorCount)  ==  1)
  558. X        {                                    /* one file specified */
  559. X        if (totalOnly)
  560. X            {
  561. X            printf("%08lx", grandSum);
  562. X            if (showCount)
  563. X                printf("  %10lu", grandByteCount);
  564. X            putchar('\n');
  565. X            }
  566. X        }
  567. X    else
  568. X        {                                    /* multiple files specified */
  569. X        if ( ! totalOnly)
  570. X            {
  571. X            printf("========");
  572. X            if (showCount)
  573. X                printf("============");
  574. X            putchar('\n');
  575. X            }
  576. X        printf("%08lx", grandSum);
  577. X        if (showCount)
  578. X            printf("  %10lu", grandByteCount);
  579. X        if (verbose)
  580. X            {
  581. X            if (showCount)
  582. X                printf("   Grand Totals for %u files", fileCount);
  583. X            else
  584. X                printf("   Grand Total for %u files", fileCount);
  585. X            if (errorCount == 1)
  586. X                printf("   ***** plus 1 ERROR *****");
  587. X            else if (1 < errorCount)
  588. X                printf("   ***** plus %u ERRORS *****", errorCount);
  589. X            }
  590. X        putchar('\n');
  591. X        }
  592. X    printd(3, "chksum: returning %u", errorCount);
  593. X    exit(errorCount);
  594. X    }                                        /* main */
  595. ________This_Is_The_END________
  596. if test `wc -c < chksum.c` -ne 8136; then
  597.     echo 'shar: chksum.c was damaged during transit (should have been 8136 bytes)'
  598. fi
  599. fi        ; : end of overwriting check
  600. echo 'x - crc32.c'
  601. if test -f crc32.c; then echo 'shar: not overwriting crc32.c'; else
  602. sed 's/^X//' << '________This_Is_The_END________' > crc32.c
  603. X/* /usr/lib/src/pd/crc32.c    881102    NHA    */
  604. X/*
  605. X *  Crc - 32 BIT ANSI X3.66 CRC checksum files
  606. X */
  607. X
  608. X#define    TEST    0
  609. X#define    DEBUG    0
  610. X#define    FAST    0
  611. X
  612. X#define    MAJOR    'L'
  613. X#define    MINOR    'C'
  614. X
  615. X#include <gen.h>
  616. X
  617. X#define OK        0
  618. X#define ERROR    (-1)
  619. X#define LINT_ARGS
  620. X
  621. X/**********************************************************************\
  622. X|*                                                                    *|
  623. X|* Demonstration program to compute the 32-bit CRC used as the frame  *|
  624. X|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71     *|
  625. X|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level     *|
  626. X|* protocol).  The 32-bit FCS was added via the Federal Register,     *|
  627. X|* 1 June 1982, p.23798.  I presume but don't know for certain that   *|
  628. X|* this polynomial is or will be included in CCITT V.41, which        *|
  629. X|* defines the 16-bit CRC (often called CRC-CCITT) polynomial.  FIPS  *|
  630. X|* PUB 78 says that the 32-bit FCS reduces otherwise undetected       *|
  631. X|* errors by a factor of 10^-5 over 16-bit FCS.                       *|
  632. X|*                                                                    *|
  633. X\**********************************************************************/
  634. X
  635. X/* Need an unsigned type capable of holding 32 bits; */
  636. Xtypedef unsigned long int UNS_32_BITS;
  637. X
  638. X/*
  639. X * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
  640. X * code or tables extracted from it, as desired without restriction.
  641. X */
  642. X/* First, the polynomial itself and its table of feedback terms.  The  */
  643. X/* polynomial is                                                       */
  644. X/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
  645. X/* Note that we take it "backwards" and put the highest-order term in  */
  646. X/* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
  647. X/* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
  648. X/* the MSB being 1.                                                    */
  649. X
  650. X/* Note that the usual hardware shift register implementation, which   */
  651. X/* is what we're using (we're merely optimizing it by doing eight-bit  */
  652. X/* chunks at a time) shifts bits into the lowest-order term.  In our   */
  653. X/* implementation, that means shifting towards the right.  Why do we   */
  654. X/* do it this way?  Because the calculated CRC must be transmitted in  */
  655. X/* order from highest-order term to lowest-order term.  UARTs transmit */
  656. X/* characters in order from LSB to MSB.  By storing the CRC this way,  */
  657. X/* we hand it to the UART in the order low-byte to high-byte; the UART */
  658. X/* sends each low-bit to hight-bit; and the result is transmission bit */
  659. X/* by bit from highest- to lowest-order term without requiring any bit */
  660. X/* shuffling on our part.  Reception works similarly.                  */
  661. X
  662. X/* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
  663. X/*                                                                     */
  664. X/*  1. The table can be generated at runtime if desired; code to do so */
  665. X/*     is shown later.  It might not be obvious, but the feedback      */
  666. X/*     terms simply represent the results of eight shift/xor opera-    */
  667. X/*     tions for all combinations of data and CRC register values.     */
  668. X/*                                                                     */
  669. X/*  2. The CRC accumulation logic is the same for all CRC polynomials, */
  670. X/*     be they sixteen or thirty-two bits wide.  You simply choose the */
  671. X/*     appropriate table.  Alternatively, because the table can be     */
  672. X/*     generated at runtime, you can start by generating the table for */
  673. X/*     the polynomial in question and use exactly the same "updcrc",   */
  674. X/*     if your application needn't simultaneously handle two CRC       */
  675. X/*     polynomials.  (Note, however, that XMODEM is strange.)          */
  676. X/*                                                                     */
  677. X/*  3. For 16-bit CRCs, the table entries need be only 16 bits wide;   */
  678. X/*     of course, 32-bit entries work OK if the high 16 bits are zero. */
  679. X/*                                                                     */
  680. X/*  4. The values must be right-shifted by eight bits by the "updcrc"  */
  681. X/*     logic; the shift must be unsigned (bring in zeroes).  On some   */
  682. X/*     hardware you could probably optimize the shift in assembler by  */
  683. X/*     using byte-swap instructions.                                   */
  684. X
  685. Xstatic UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
  686. X0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
  687. X0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
  688. X0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
  689. X0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
  690. X0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
  691. X0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  692. X0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
  693. X0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
  694. X0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
  695. X0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
  696. X0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
  697. X0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  698. X0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
  699. X0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
  700. X0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  701. X0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
  702. X0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
  703. X0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  704. X0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
  705. X0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
  706. X0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
  707. X0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
  708. X0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
  709. X0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  710. X0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
  711. X0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
  712. X0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
  713. X0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
  714. X0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
  715. X0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  716. X0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
  717. X0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
  718. X0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
  719. X0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
  720. X0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
  721. X0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  722. X0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
  723. X0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
  724. X0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
  725. X0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
  726. X0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
  727. X0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  728. X0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
  729. X0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
  730. X0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
  731. X0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
  732. X0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
  733. X0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  734. X0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
  735. X0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
  736. X0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
  737. X0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
  738. X0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
  739. X0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  740. X0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
  741. X0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
  742. X0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
  743. X0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
  744. X0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
  745. X0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  746. X0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
  747. X0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  748. X0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  749. X0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  750. X};
  751. X
  752. X
  753. X
  754. X/*+    c r c 3 2 b u f
  755. X * Given an initial 32-bit CRC and a buffer, calculate the new CRC.
  756. X * Returns the new CRC.
  757. X */
  758. Xexport UNS_32_BITS crc32buf( crc, cp, cnt )
  759. XUNS_32_BITS    crc;                /* initial CRC */
  760. Xunsigned char    *cp;                /* pointer to buffer */
  761. Xunsigned    cnt;                /* # chars in buffer */
  762. X    {
  763. X    printd(3, "crc32buf(%lu, %p, %u)\n", crc, cp, cnt);
  764. X
  765. X#if    FAST
  766. X#asm
  767. X;es:si    holds pointer to buffer (cp)
  768. X;cx        holds count (cnt)
  769. X;dx,ax    holds crc hi,lo
  770. X    mov    cx, word ptr 14[bp]        ;cnt
  771. X    jcxz    done
  772. X    mov    ax, word ptr 6[bp]        ;crc lo
  773. X    mov    dx, word ptr 8[bp]        ;crc hi
  774. X    les    bx, dword ptr 10[bp]        ;cp
  775. X    mov    si, bx
  776. Xagain:
  777. X    mov    bl, es:byte ptr [si]        ;octet
  778. X    xor    bl, al                ;crc ^ octet & 0377
  779. X    xor    bh, bh
  780. X    shl    bx, 1
  781. X    shl    bx, 1                ;bx is index into crc_32_tab
  782. X    mov    al, ah                ;crc >>= 8
  783. X    mov    ah, dl
  784. X    mov    dl, dh
  785. X    xor    dh, dh
  786. X    xor    ax, word ptr crc_32_tab_[bx]    ;low word
  787. X    xor    dx, word ptr crc_32_tab_[bx+2]    ;high word
  788. X    inc    si
  789. X    loop    again
  790. X    mov    word ptr 6[bp], ax        ;crc lo
  791. X    mov    word ptr 8[bp], dx        ;crc hi
  792. Xdone:
  793. X#endasm
  794. X#else FAST
  795. X#define    W    16
  796. X#define    B    8
  797. X    while( cnt-- ) {
  798. X#  if SWAPPED
  799. X        crc = (crc<<B) ^ crc_32_tab[(crc>>(W-B)) ^ *cp++];
  800. X#  else SWAPPED
  801. X        crc = (crc>>B) ^ crc_32_tab[(crc & ((1<<B)-1)) ^ *cp++]; 
  802. X#  endif SWAPPED
  803. X        printd(8, "crc32buf(): cnt=%u, crc=%08lx\n", cnt, crc);
  804. X        }
  805. X#endif FAST
  806. X
  807. X    printd(3, "crc32buf(): returning %lu\n", crc);
  808. X    return( crc );
  809. X}                    /* crc32buf() */
  810. X
  811. X
  812. X
  813. X/*+        c r c 3 2 1
  814. X * Given a 32-bit CRC and a byte, return the new CRC which includes the byte.
  815. X */
  816. Xexport UNS_32_BITS crc321( crc, octet )
  817. XUNS_32_BITS    crc;
  818. Xunsigned char    octet;
  819. X    {
  820. X    UNS_32_BITS        newcrc;
  821. X    printd(3, "crc321(%lu, %#02x)\n", crc, octet);
  822. X#if FAST
  823. X#asm
  824. X    mov    bl, byte ptr 10[bp]        ;octet
  825. X    xor    bl, byte ptr 6[bp]        ;(crc ^ octet) & 0377
  826. X    xor    bh, bh
  827. X    shl    bx, 1
  828. X    shl    bx, 1                ;bx is index into crc_32_tab
  829. X    mov    ax, word ptr crc_32_tab_[bx]    ;low word
  830. X    mov    dx, word ptr crc_32_tab_[bx+2]    ;high word
  831. X    xor    ax, word ptr 7[bp]        ;xor with (crc >> 8), low word
  832. X    xor    dl, byte ptr 9[bp]        ;xor with (crc >> 8), high byte
  833. X    mov    word ptr -4[bp], ax        ;store in newcrc
  834. X    mov    word ptr -2[bp], dx        ; for printf() and return value
  835. X#endasm
  836. X#else FAST
  837. X    newcrc =  (crc_32_tab[((crc) ^ (octet)) & 0377]   ^   ((crc) >> 8));
  838. X#endif FAST
  839. X    printd(3, "crc321(): returning %lu\n", newcrc);
  840. X    return newcrc;
  841. X}                        /* crc321() */
  842. X
  843. X
  844. X#if TEST
  845. X
  846. X#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
  847. X
  848. X
  849. Xlocal crc32file(name)
  850. Xchar *name;
  851. X{
  852. X    register FILE *fin;
  853. X    register unsigned long oldcrc32;
  854. X    register unsigned long crc32;
  855. X    register unsigned long oldcrc;
  856. X    register c;
  857. X    register long charcnt;
  858. X
  859. X    oldcrc32 = 0xFFFFFFFF; charcnt = 0;
  860. X#ifdef M_I86SM
  861. X    if ((fin=fopen(name, "rb"))==NULL)
  862. X#else
  863. X    if ((fin=fopen(name, "r"))==NULL)
  864. X#endif
  865. X    {
  866. X        perror(name);
  867. X        return ERROR;
  868. X    }
  869. X    while ((c=getc(fin))!=EOF) {
  870. X        ++charcnt;
  871. X/**        oldcrc32 = UPDC32(c, oldcrc32); **/
  872. X        oldcrc32 = crc321(oldcrc32, c);
  873. X    }
  874. X
  875. X    if (ferror(fin)) {
  876. X        perror(name);
  877. X        charcnt = -1;
  878. X    }
  879. X    fclose(fin);
  880. X
  881. X    crc32 = oldcrc32;  oldcrc = oldcrc32 = ~oldcrc32;
  882. X
  883. X/*
  884. X    crc32 = UPDC32((oldcrc32 & 0377), crc32);  oldcrc32 >>=8;
  885. X    crc32 = UPDC32((oldcrc32 & 0377), crc32);  oldcrc32 >>=8;
  886. X    crc32 = UPDC32((oldcrc32 & 0377), crc32);  oldcrc32 >>=8;
  887. X    crc32 = UPDC32((oldcrc32 & 0377), crc32);  oldcrc32 >>=8;
  888. X    printf("%08lX ", crc32);
  889. X*/
  890. X
  891. X    printf("%08lX %7ld %s\n", oldcrc, charcnt, name);
  892. X
  893. X    return OK;
  894. X}
  895. X
  896. X
  897. Xexport main(argc, argp)
  898. Xchar **argp;
  899. X{
  900. X    register errors = 0;
  901. X
  902. X    while( --argc > 0)
  903. X        errors |= crc32file( *++argp);
  904. X    exit(errors != 0);
  905. X}
  906. X#endif TEST
  907. ________This_Is_The_END________
  908. if test `wc -c < crc32.c` -ne 11016; then
  909.     echo 'shar: crc32.c was damaged during transit (should have been 11016 bytes)'
  910. fi
  911. fi        ; : end of overwriting check
  912. exit 0
  913.