Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/sum.c
Parent Directory | 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)
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 | } |