Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/sum.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 2330 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 /* 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     *
13     * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14     */
15    
16     #include "busybox.h"
17    
18     enum { sysv_sum, bsd_sum };
19    
20     /* BSD: calculate and print the rotated checksum and the size in 1K blocks
21     The checksum varies depending on sizeof (int). */
22     /* SYSV: calculate and print the checksum and the size in 512-byte blocks */
23     /* Return 1 if successful. */
24     static int sum_file(const char *file, int type, int print_name)
25     {
26     #define buf bb_common_bufsiz1
27     int r, fd;
28     uintmax_t total_bytes = 0;
29    
30     /* The sum of all the input bytes, modulo (UINT_MAX + 1). */
31     unsigned s = 0;
32    
33     fd = 0;
34     if (NOT_LONE_DASH(file)) {
35     fd = open(file, O_RDONLY);
36     if (fd == -1)
37     goto ret_bad;
38     }
39    
40     while (1) {
41     size_t bytes_read = safe_read(fd, buf, BUFSIZ);
42    
43     if ((ssize_t)bytes_read <= 0) {
44     r = (fd && close(fd) != 0);
45     if (!bytes_read && !r)
46     /* no error */
47     break;
48     ret_bad:
49     bb_perror_msg(file);
50     return 0;
51     }
52    
53     total_bytes += bytes_read;
54     if (type == sysv_sum) {
55     do s += buf[--bytes_read]; while (bytes_read);
56     } else {
57     r = 0;
58     do {
59     s = (s >> 1) + ((s & 1) << 15);
60     s += buf[r++];
61     s &= 0xffff; /* Keep it within bounds. */
62     } while (--bytes_read);
63     }
64     }
65    
66     if (!print_name) file = "";
67     if (type == sysv_sum) {
68     r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
69     s = (r & 0xffff) + (r >> 16);
70     printf("%d %ju %s\n", s, (total_bytes+511)/512, file);
71     } else
72     printf("%05d %5ju %s\n", s, (total_bytes+1023)/1024, file);
73     return 1;
74     #undef buf
75     }
76    
77     int sum_main(int argc, char **argv)
78     {
79     int n;
80     int type = bsd_sum;
81    
82     n = getopt32(argc, argv, "sr");
83     if (n & 1) type = sysv_sum;
84     /* give the bsd priority over sysv func */
85     if (n & 2) type = bsd_sum;
86    
87     if (argc == optind)
88     n = sum_file("-", type, 0);
89     else
90     for (n = 1; optind < argc; optind++)
91     n &= sum_file(argv[optind], type, 1);
92    
93     return !n;
94     }