New applet cksum, from Rob Sullivan.
[oweals/busybox.git] / coreutils / cksum.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * cksum - calculate the CRC32 checksum of a file
4  *
5  * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
6  * 
7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
8
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <inttypes.h>
13 #include "busybox.h"
14
15 int cksum_main(int argc, char **argv) {
16         
17         uint32_t *crc32_table = bb_crc32_filltable(1);
18
19         FILE *fp;
20         uint32_t crc;
21         long length, filesize;
22         int bytes_read;
23         char *cp;
24         RESERVE_CONFIG_BUFFER(buf, BUFSIZ);
25         int inp_stdin = (argc == optind) ? 1 : 0;
26         
27         do {
28                 fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv);
29                         
30                 crc = 0;
31                 length = 0;
32                 
33                 while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) {
34                         cp = buf;
35                         length += bytes_read;
36                         while (bytes_read--)
37                                 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
38                 }
39                 
40                 filesize = length;
41                 
42                 for (; length; length >>= 8)
43                         crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
44                 crc ^= 0xffffffffL;
45
46                 if (inp_stdin) {
47                         printf("%"PRIu32" %li\n", crc, filesize);
48                         break;
49                 }
50                 
51                 printf("%"PRIu32" %li %s\n", crc, filesize, *argv);     
52                 fclose(fp);
53         } while (*(argv+1));
54         
55         return EXIT_SUCCESS;
56 }