--- coreutils/sum.c +++ coreutils/sum.c @@ -23,22 +23,23 @@ //kbuild:lib-$(CONFIG_SUM) += sum.o //usage:#define sum_trivial_usage -//usage: "[-rs] [FILE]..." +//usage: "[-rsp] [FILE]..." //usage:#define sum_full_usage "\n\n" //usage: "Checksum and count the blocks in a file\n" //usage: "\n -r Use BSD sum algorithm (1K blocks)" //usage: "\n -s Use System V sum algorithm (512byte blocks)" +//usage: "\n -p Print pure sum of all bytes of the file" #include "libbb.h" #include "common_bufsiz.h" -enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; +enum { SUM_BSD, SUM_SYSV, SUM_PURE }; /* BSD: calculate and print the rotated checksum and the size in 1K blocks The checksum varies depending on sizeof (int). */ /* SYSV: calculate and print the checksum and the size in 512-byte blocks */ /* Return 1 if successful. */ -static unsigned sum_file(const char *file, unsigned type) +static unsigned sum_file(const char *file, unsigned type, unsigned print_name) { unsigned long long total_bytes = 0; int fd, r; @@ -77,11 +78,15 @@ } } - if (type < PRINT_NAME) + if (!print_name) file = ""; if (type >= SUM_SYSV) { - r = (s & 0xffff) + ((s & 0xffffffff) >> 16); - s = (r & 0xffff) + (r >> 16); + if (type == SUM_PURE) { + s = s & 0xffffffff; + } else { + r = (s & 0xffff) + ((s & 0xffffffff) >> 16); + s = (r & 0xffff) + (r >> 16); + } printf("%u %llu %s\n", s, (total_bytes + 511) / 512, file); } else printf("%05u %5llu %s\n", s, (total_bytes + 1023) / 1024, file); @@ -95,23 +100,24 @@ unsigned n; unsigned type = SUM_BSD; - n = getopt32(argv, "sr"); + n = getopt32(argv, "srp"); argv += optind; + if (n & 4) type = SUM_PURE; if (n & 1) type = SUM_SYSV; /* give the bsd priority over sysv func */ if (n & 2) type = SUM_BSD; if (!argv[0]) { /* Do not print the name */ - n = sum_file("-", type); + n = sum_file("-", type, 0); } else { /* Need to print the name if either * - more than one file given - * - doing sysv */ - type += (argv[1] || type == SUM_SYSV); + * - doing sysv or pure sum */ + unsigned print_name = (argv[1] || type >= SUM_SYSV); n = 1; do { - n &= sum_file(*argv, type); + n &= sum_file(*argv, type, print_name); } while (*++argv); } return !n;