source: MondoRescue/branches/3.3/mindi-busybox/coreutils/sum.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 2.8 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * sum -- checksum and count the blocks in a file
4 * Like BSD sum or SysV sum -r, except like SysV sum if -s option is given.
5 *
6 * Copyright (C) 86, 89, 91, 1995-2002, 2004 Free Software Foundation, Inc.
7 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
8 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
9 *
10 * Written by Kayvan Aghaiepour and David MacKenzie
11 * Taken from coreutils and turned into a busybox applet by Mike Frysinger
12 *
[2725]13 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
[821]14 */
15
[3232]16//usage:#define sum_trivial_usage
17//usage: "[-rs] [FILE]..."
18//usage:#define sum_full_usage "\n\n"
19//usage: "Checksum and count the blocks in a file\n"
20//usage: "\n -r Use BSD sum algorithm (1K blocks)"
21//usage: "\n -s Use System V sum algorithm (512byte blocks)"
22
[1765]23#include "libbb.h"
[3621]24#include "common_bufsiz.h"
[821]25
[1765]26enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
[821]27
[1765]28/* BSD: calculate and print the rotated checksum and the size in 1K blocks
29 The checksum varies depending on sizeof (int). */
30/* SYSV: calculate and print the checksum and the size in 512-byte blocks */
31/* Return 1 if successful. */
[2725]32static unsigned sum_file(const char *file, unsigned type)
[821]33{
[2725]34 unsigned long long total_bytes = 0;
35 int fd, r;
[821]36 /* The sum of all the input bytes, modulo (UINT_MAX + 1). */
[1765]37 unsigned s = 0;
[821]38
[3621]39#define buf bb_common_bufsiz1
40 setup_common_bufsiz();
41
[2725]42 fd = open_or_warn_stdin(file);
43 if (fd == -1)
44 return 0;
[821]45
46 while (1) {
[3621]47 size_t bytes_read = safe_read(fd, buf, COMMON_BUFSIZE);
[821]48
[1765]49 if ((ssize_t)bytes_read <= 0) {
50 r = (fd && close(fd) != 0);
51 if (!bytes_read && !r)
52 /* no error */
53 break;
[2725]54 bb_simple_perror_msg(file);
[821]55 return 0;
56 }
57
58 total_bytes += bytes_read;
[1765]59 if (type >= SUM_SYSV) {
60 do s += buf[--bytes_read]; while (bytes_read);
61 } else {
62 r = 0;
63 do {
64 s = (s >> 1) + ((s & 1) << 15);
65 s += buf[r++];
66 s &= 0xffff; /* Keep it within bounds. */
67 } while (--bytes_read);
68 }
[821]69 }
70
[1765]71 if (type < PRINT_NAME)
72 file = "";
73 if (type >= SUM_SYSV) {
74 r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
[821]75 s = (r & 0xffff) + (r >> 16);
[3621]76 printf("%u %llu %s\n", s, (total_bytes + 511) / 512, file);
[1765]77 } else
[3621]78 printf("%05u %5llu %s\n", s, (total_bytes + 1023) / 1024, file);
[821]79 return 1;
[1765]80#undef buf
[821]81}
82
[2725]83int sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
84int sum_main(int argc UNUSED_PARAM, char **argv)
[821]85{
[1765]86 unsigned n;
87 unsigned type = SUM_BSD;
[821]88
[1765]89 n = getopt32(argv, "sr");
[2725]90 argv += optind;
[1765]91 if (n & 1) type = SUM_SYSV;
92 /* give the bsd priority over sysv func */
93 if (n & 2) type = SUM_BSD;
[821]94
[2725]95 if (!argv[0]) {
[1765]96 /* Do not print the name */
97 n = sum_file("-", type);
98 } else {
99 /* Need to print the name if either
[3232]100 * - more than one file given
101 * - doing sysv */
[2725]102 type += (argv[1] || type == SUM_SYSV);
103 n = 1;
104 do {
105 n &= sum_file(*argv, type);
106 } while (*++argv);
[1765]107 }
108 return !n;
[821]109}
Note: See TracBrowser for help on using the repository browser.