Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/coreutils/sum.c


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/coreutils/sum.c

    r821 r1765  
    1111 * Taken from coreutils and turned into a busybox applet by Mike Frysinger
    1212 *
    13  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    1414 */
    1515
    16 #include <stdio.h>
    17 #include <sys/types.h>
    18 #include <sys/stat.h>
    19 #include <fcntl.h>
    20 #include <unistd.h>
     16#include "libbb.h"
    2117
    22 #include "busybox.h"
     18enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
    2319
    24 /* 1 if any of the files read were the standard input */
    25 static int have_read_stdin;
    26 
    27 /* make a little more readable and avoid using strcmp for just 2 bytes */
    28 #define IS_STDIN(s) (s[0] == '-' && s[1] == '\0')
    29 
    30 /* Calculate and print the rotated checksum and the size in 1K blocks
    31    of file FILE, or of the standard input if FILE is "-".
    32    If PRINT_NAME is >1, print FILE next to the checksum and size.
    33    The checksum varies depending on sizeof (int).
    34    Return 1 if successful.  */
    35 static int bsd_sum_file(const char *file, int print_name)
     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.  */
     24static unsigned sum_file(const char *file, const unsigned type)
    3625{
    37     FILE *fp;
    38     int checksum = 0;          /* The checksum mod 2^16. */
    39     uintmax_t total_bytes = 0; /* The number of bytes. */
    40     int ch;                    /* Each character read. */
    41 
    42     if (IS_STDIN(file)) {
    43         fp = stdin;
    44         have_read_stdin = 1;
    45     } else {
    46         fp = bb_wfopen(file, "r");
    47         if (fp == NULL)
    48             return 0;
    49     }
    50 
    51     while ((ch = getc(fp)) != EOF) {
    52         ++total_bytes;
    53         checksum = (checksum >> 1) + ((checksum & 1) << 15);
    54         checksum += ch;
    55         checksum &= 0xffff;             /* Keep it within bounds. */
    56     }
    57 
    58     if (ferror(fp)) {
    59         bb_perror_msg(file);
    60         bb_fclose_nonstdin(fp);
    61         return 0;
    62     }
    63 
    64     if (bb_fclose_nonstdin(fp) == EOF) {
    65         bb_perror_msg(file);
    66         return 0;
    67     }
    68 
    69     printf("%05d %5ju ", checksum, (total_bytes+1023)/1024);
    70     if (print_name > 1)
    71         puts(file);
    72     else
    73         printf("\n");
    74 
    75     return 1;
    76 }
    77 
    78 /* Calculate and print the checksum and the size in 512-byte blocks
    79    of file FILE, or of the standard input if FILE is "-".
    80    If PRINT_NAME is >0, print FILE next to the checksum and size.
    81    Return 1 if successful.  */
    82 #define MY_BUF_SIZE 8192
    83 static int sysv_sum_file(const char *file, int print_name)
    84 {
    85     RESERVE_CONFIG_BUFFER(buf, MY_BUF_SIZE);
    86     int fd;
     26#define buf bb_common_bufsiz1
    8727    uintmax_t total_bytes = 0;
     28    int fd = 0, r;
    8829
    8930    /* The sum of all the input bytes, modulo (UINT_MAX + 1).  */
    90     unsigned int s = 0;
     31    unsigned s = 0;
    9132
    92     if (IS_STDIN(file)) {
    93         fd = 0;
    94         have_read_stdin = 1;
    95     } else {
     33    if (NOT_LONE_DASH(file)) {
    9634        fd = open(file, O_RDONLY);
    9735        if (fd == -1)
    98             goto release_and_ret;
     36            goto ret_bad;
    9937    }
    10038
    10139    while (1) {
    102         size_t bytes_read = safe_read(fd, buf, MY_BUF_SIZE);
     40        size_t bytes_read = safe_read(fd, buf, BUFSIZ);
    10341
    104         if (bytes_read == 0)
    105             break;
    106 
    107         if (bytes_read == -1) {
    108 release_and_ret:
     42        if ((ssize_t)bytes_read <= 0) {
     43            r = (fd && close(fd) != 0);
     44            if (!bytes_read && !r)
     45                /* no error */
     46                break;
     47 ret_bad:
    10948            bb_perror_msg(file);
    110             RELEASE_CONFIG_BUFFER(buf);
    111             if (!IS_STDIN(file))
    112                 close(fd);
    11349            return 0;
    11450        }
    11551
    11652        total_bytes += bytes_read;
    117         while (bytes_read--)
    118             s += buf[bytes_read];
     53        if (type >= SUM_SYSV) {
     54            do s += buf[--bytes_read]; while (bytes_read);
     55        } else {
     56            r = 0;
     57            do {
     58                s = (s >> 1) + ((s & 1) << 15);
     59                s += buf[r++];
     60                s &= 0xffff; /* Keep it within bounds. */
     61            } while (--bytes_read);
     62        }
    11963    }
    12064
    121     if (!IS_STDIN(file) && close(fd) == -1)
    122         goto release_and_ret;
    123     else
    124         RELEASE_CONFIG_BUFFER(buf);
    125 
    126     {
    127         int r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
     65    if (type < PRINT_NAME)
     66        file = "";
     67    if (type >= SUM_SYSV) {
     68        r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
    12869        s = (r & 0xffff) + (r >> 16);
    129 
    130         printf("%d %ju ", s, (total_bytes+511)/512);
    131     }
    132     puts(print_name ? file : "");
    133 
     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);
    13473    return 1;
     74#undef buf
    13575}
    13676
     77int sum_main(int argc, char **argv);
    13778int sum_main(int argc, char **argv)
    13879{
    139     int flags;
    140     int ok;
    141     int (*sum_func)(const char *, int) = bsd_sum_file;
     80    unsigned n;
     81    unsigned type = SUM_BSD;
    14282
    143     /* give the bsd func priority over sysv func */
    144     flags = bb_getopt_ulflags(argc, argv, "sr");
    145     if (flags & 1)
    146         sum_func = sysv_sum_file;
    147     if (flags & 2)
    148         sum_func = bsd_sum_file;
     83    n = getopt32(argv, "sr");
     84    if (n & 1) type = SUM_SYSV;
     85    /* give the bsd priority over sysv func */
     86    if (n & 2) type = SUM_BSD;
    14987
    150     have_read_stdin = 0;
    151     if ((argc - optind) == 0)
    152         ok = sum_func("-", 0);
    153     else
    154         for (ok = 1; optind < argc; optind++)
    155             ok &= sum_func(argv[optind], 1);
    156 
    157     if (have_read_stdin && fclose(stdin) == EOF)
    158         bb_perror_msg_and_die("-");
    159 
    160     exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
     88    if (argc == optind) {
     89        /* Do not print the name */
     90        n = sum_file("-", type);
     91    } else {
     92        /* Need to print the name if either
     93           - more than one file given
     94           - doing sysv */
     95        type += argc - 1 > optind || type == SUM_SYSV;
     96        for (n = 1; optind < argc; optind++)
     97            n &= sum_file(argv[optind], type);
     98    }
     99    return !n;
    161100}
Note: See TracChangeset for help on using the changeset viewer.