/* * UNG's Not GNU * * Copyright (c) 2022, Jakob Kaivo * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #define UINT16_BIT (16) #define BLOCK_SIZE (512) static int sum(const char *path, int alt) { FILE *f = stdin; if (path && strcmp(path, "-")) { f = fopen(path, "rb"); } if (f == NULL) { fprintf(stderr, "sum: %s: %s\n", path, strerror(errno)); return 1; } int c; uintmax_t size = 0; uintmax_t sum = 0; while ((c = fgetc(f)) != EOF) { size++; if (alt) { sum = (sum >> 1) + ((sum & 1) << (UINT16_BIT - 1)); } sum += c; if (alt) { sum &= UINT16_MAX; } } sum = (sum & UINT16_MAX) + (sum >> UINT16_BIT); if (size % BLOCK_SIZE != 0) { size += BLOCK_SIZE; } size /= BLOCK_SIZE; printf("%ju %ju", sum, size); if (f != stdin) { printf(" %s", path); fclose(f); } putchar('\n'); return 0; } int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); fprintf(stderr, "sum: utility is obsolete; use cksum\n"); int alt = 0; int c; while ((c = getopt(argc, argv, "r")) != -1) { switch (c) { case 'r': alt = 1; break; default: return 1; } } int r = 0; do { r |= sum(argv[optind++], alt); } while (optind < argc); return r; }