home *** CD-ROM | disk | FTP | other *** search
- /*
- * Produces a checksum of a byte stream that should be the same as
- * the standard SVR4 "sum" program. Note that the "sum" documentation
- * is misleading, the checksum is NOT simply a 16-bit checksum of all
- * the bytes. Here is the algorithm:
- *
- * 1. Add up all the bytes using an unsigned long (32-bit)
- * integer and treating each byte as unsigned.
- *
- * 2. Add the overflow from the lower 16 bits (the high 16
- * bits) back into the lower 16 bits using unsigned
- * arithmetic. I.E. treat the 32-bit long as two 16-bit
- * unsigned ints and add them using 32-bit unsigned
- * arithmetic.
- *
- * 3. Repeat step (2) one more time, presumably to catch
- * any additional overflow.
- *
- * If stdout is not a terminal, then the input is passed on to the
- * output, and the checksum is printed on stderr rather than stdout.
- * This allows natural use as either the end of a pipeline with the
- * checksum printed on stdout, or in the middle with it printed on
- * stderr.
- *
- * Written by Fred Fish. This file is public domain.
- */
-
- #include <stdio.h>
-
- #define BFSIZ 1024
-
- main ()
- {
- unsigned char buf[BFSIZ];
- int nbytes;
- unsigned long sum = 0;
- unsigned long temp = 0;
- int nopass;
-
- nopass = isatty (1);
- while ((nbytes = read (0, buf, sizeof (buf))) > 0)
- {
- if (!nopass)
- {
- (void) write (1, buf, (unsigned) nbytes);
- }
- while (nbytes-- > 0)
- {
- sum += buf[nbytes];
- }
- }
- temp = (sum >> 16) + (sum & 0xFFFF);
- sum = (temp >> 16) + (temp & 0xFFFF);
- if (nopass)
- {
- (void) fprintf (stdout, "%u\n", sum);
- }
- else
- {
- (void) fprintf (stderr, "%u\n", sum);
- }
- return (0);
- }
-