]> pd.if.org Git - pdutils/blob - posix/cksum/cksum.c
rename utils to posix
[pdutils] / posix / cksum / cksum.c
1 /*
2  * cksum - report checksum and octet count of file(s)
3  *
4  * Version: 2008-1.01
5  * Build:   c89 -o cksum cksum.c
6  * Source:  <http://pdcore.sourceforge.net/>
7  * Spec:    <http://www.opengroup.org/onlinepubs/9699919799/utilities/cksum.html>
8  *
9  * This is free and unencumbered software released into the public domain,
10  * provided "as is", without warranty of any kind, express or implied. See the
11  * file UNLICENSE and the website <http://unlicense.org> for further details.
12  */
13
14
15 #define _POSIX_SOURCE
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <inttypes.h>
20 #include <locale.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #define BUFSIZE 4096
27
28 static void cksumfile(int fd, char *fn);
29 static void error(char *s);
30
31 static int exitstatus;
32
33
34 int main(int argc, char **argv)
35 {
36     int i, fd, hasrun = 0;
37     char *fn;
38
39     setlocale(LC_ALL, "");
40
41     for (i = 1; i < argc; i++)
42     {
43         fn = argv[i];
44
45         if (strcmp(fn, "--") == 0)
46             continue;
47         else
48         {
49             hasrun = 1;
50
51             if (strcmp(fn, "-") == 0)
52                 cksumfile(STDIN_FILENO, "stdin");
53             else
54                 if ((fd = open(fn, O_RDONLY)) == -1)
55                     error(fn);
56                 else
57                 {
58                     cksumfile(fd, fn);
59                     if (close(fd) == -1)
60                         error(fn);
61                 }
62         }
63     }
64
65     if (! hasrun)
66         cksumfile(STDIN_FILENO, "stdin");
67
68     return(exitstatus);
69 }
70
71
72 void cksumfile(int fd, char *fn)
73 {
74     unsigned char buf[BUFSIZE];
75     ssize_t cnt, n;
76     uint32_t crctab[256], crc, i;
77     int j;
78
79     for (i = 0; i < 256; ++i)
80     {
81         for (crc = i << 24, j = 0; j < 8; j++)
82             crc = (crc << 1) ^ (crc & 0x80000000 ? 0x04c11db7 : 0);
83         crctab[i] = crc;
84     }
85
86     cnt = crc = 0;
87
88     while ((n = read(fd, buf, BUFSIZE)) > 0)
89     {
90         cnt += n;
91
92         for (i = 0; i < (size_t)n; i++)
93             crc = crctab[((crc >> 24) ^ buf[i]) & 0xFF] ^ (crc << 8);
94     }
95
96     if (n < 0)
97         error(fn);
98     else
99     {
100         for (i = cnt; i != 0; i >>= 8)
101             crc = crctab[((crc >> 24) ^ i) & 0xFF] ^ (crc << 8);
102
103         printf("%lu %lu", (unsigned long)~crc, (unsigned long)cnt);
104         if (fd != STDIN_FILENO)
105             printf(" %s", fn);
106         printf("\n");
107     }
108 }
109
110
111 void error(char *s)
112 {
113     fprintf(stderr, "cksum: %s: %s\n", s, strerror(errno));
114     exitstatus = 1;
115 }