OSDN Git Service

- pull from busybox_scratch: r15829:15850
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Mon, 28 Aug 2006 23:31:54 +0000 (23:31 -0000)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Mon, 28 Aug 2006 23:31:54 +0000 (23:31 -0000)
  Various fixes, cleanups and shrinkage:
saves 952 Bytes:
   text    data     bss     dec     hex filename
1087742   15853  790632 1894227  1ce753 ../busybox/busybox.old
1086790   15853  790632 1893275  1ce39b busybox
via:
# scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped
function                                             old     new   delta
ipcrm_main                                           756     822     +66
getval                                                 -      61     +61
maybe_set_utc                                          -      40     +40
udhcpc_main                                         2896    2912     +16
md5_hash_block                                       428     437      +9
opt                                                    8      16      +8
qgravechar                                           106     110      +4
make_bitmap                                          292     295      +3
inflate_unzip                                       2056    2059      +3
add_partition                                       1412    1414      +2
__parsespent                                         156     158      +2
qrealloc                                              41      42      +1
format                                                 -       1      +1
catv_main                                            313     314      +1
watch_main                                           293     292      -1
varunset                                              81      80      -1
part                                                   1       -      -1
check_if_skip                                        837     836      -1
start_stop_daemon_main                               840     837      -3
create_lost_and_found                                175     172      -3
supress_non_delimited_lines                            4       -      -4
static.l                                               4       -      -4
static.c                                               5       1      -4
bsd_sum_file                                         237     233      -4
eval2                                                338     332      -6
arithmetic_common                                    166     158      -8
cmpfunc                                               22       5     -17
cksum_main                                           294     275     -19
cmp_main                                             465     439     -26
dd_main                                             1535    1508     -27
rmmod_main                                           376     333     -43
cut_file                                             727     644     -83
ipcs_main                                           3809    3721     -88
cut_main                                             722     614    -108
date_main                                           1443    1263    -180
remove_ids                                           222       -    -222
------------------------------------------------------------------------------
(add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853)       Total: -636 bytes

20 files changed:
Makefile
coreutils/catv.c
coreutils/cksum.c
coreutils/cmp.c
coreutils/cut.c
coreutils/date.c
coreutils/dd.c
coreutils/du.c
coreutils/expr.c
coreutils/sum.c
coreutils/tail.c
coreutils/tee.c
coreutils/watch.c
include/libbb.h
include/unarchive.h
include/usage.h
libbb/xfuncs.c
testsuite/all_sourcecode.tests
util-linux/ipcrm.c
util-linux/ipcs.c

index 82e0026..cc22347 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -278,6 +278,7 @@ endif # CONFIG_FEATURE_FULL_LIBBUSYBOX
 APPLET_SRC:=$(APPLET_SRC-y)
 APPLETS_DEFINE:=$(APPLETS_DEFINE-y)
 else  # CONFIG_BUILD_AT_ONCE
+APPLET_SRC:=
 # no --combine, build archives out of the individual .o
 # This was the old way the binary was built.
 libbusybox-obj:=archival/libunarchive/libunarchive.a \
index e182039..f8229c2 100644 (file)
 
 int catv_main(int argc, char **argv)
 {
-       int retval = EXIT_SUCCESS, fd, flags;
+       int retval = EXIT_SUCCESS, fd;
+       unsigned long flags;
 
        flags = bb_getopt_ulflags(argc, argv, "etv");
-       flags ^= 4;
-
-       // Loop through files.
+#define CATV_OPT_e (1<<0)
+#define CATV_OPT_t (1<<1)
+#define CATV_OPT_v (1<<2)
+       flags ^= CATV_OPT_v;
 
        argv += optind;
        do {
-               // Read from stdin if there's nothing else to do.
-
+               /* Read from stdin if there's nothing else to do. */
                fd = 0;
-               if (*argv && 0>(fd = xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE;
-               else for(;;) {
+               if (*argv && 0 > (fd = xopen(*argv, O_RDONLY)))
+                       retval = EXIT_FAILURE;
+               else for (;;) {
                        int i, res;
 
                        res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1));
-                       if (res < 0) retval = EXIT_FAILURE;
-                       if (res <1) break;
-                       for (i=0; i<res; i++) {
-                               char c=bb_common_bufsiz1[i];
+                       if (res < 0)
+                               retval = EXIT_FAILURE;
+                       if (res < 1)
+                               break;
+                       for (i = 0; i < res; i++) {
+                               char c = bb_common_bufsiz1[i];
 
-                               if (c > 126 && (flags & 4)) {
+                               if (c > 126 && (flags & CATV_OPT_v)) {
                                        if (c == 127) {
-                                               printf("^?");
+                                               bb_printf("^?");
                                                continue;
                                        } else {
-                                               printf("M-");
+                                               bb_printf("M-");
                                                c -= 128;
                                        }
                                }
                                if (c < 32) {
                                        if (c == 10) {
-                                          if (flags & 1) putchar('$');
-                                       } else if (flags & (c==9 ? 2 : 4)) {
-                                               printf("^%c", c+'@');
+                                          if (flags & CATV_OPT_e)
+                                                  putchar('$');
+                                       } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
+                                               bb_printf("^%c", c+'@');
                                                continue;
                                        }
                                }
                                putchar(c);
                        }
                }
-               if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd);
+               if (ENABLE_FEATURE_CLEAN_UP && fd)
+                       close(fd);
        } while (*++argv);
 
        return retval;
index 5849dda..9a45fd6 100644 (file)
@@ -3,12 +3,13 @@
  * cksum - calculate the CRC32 checksum of a file
  *
  * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
- * 
+ *
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
 
 #include "busybox.h"
 
-int cksum_main(int argc, char **argv) {
+int cksum_main(int argc, char **argv)
+{
        
        uint32_t *crc32_table = crc32_filltable(1);
 
@@ -17,36 +18,36 @@ int cksum_main(int argc, char **argv) {
        long length, filesize;
        int bytes_read;
        char *cp;
-       RESERVE_CONFIG_BUFFER(buf, BUFSIZ);
+
        int inp_stdin = (argc == optind) ? 1 : 0;
-       
+
        do {
                fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv);
-                       
+
                crc = 0;
                length = 0;
-               
-               while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) {
-                       cp = buf;
+
+               while ((bytes_read = fread(bb_common_bufsiz1, 1, BUFSIZ, fp)) > 0) {
+                       cp = bb_common_bufsiz1;
                        length += bytes_read;
                        while (bytes_read--)
                                crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
                }
-               
+
                filesize = length;
-               
+
                for (; length; length >>= 8)
                        crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
                crc ^= 0xffffffffL;
 
                if (inp_stdin) {
-                       printf("%"PRIu32" %li\n", crc, filesize);
+                       bb_printf("%" PRIu32 " %li\n", crc, filesize);
                        break;
                }
-               
-               printf("%"PRIu32" %li %s\n", crc, filesize, *argv);     
+
+               bb_printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
                fclose(fp);
-       } while (*(argv+1));
-       
+       } while (*(argv + 1));
+
        return EXIT_SUCCESS;
 }
index a569eb3..ae3f502 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "busybox.h"
 
-static FILE *cmp_xfopen_input(const char *filename)
+static FILE *cmp_xfopen_input(const char * const filename)
 {
        FILE *fp;
 
@@ -40,32 +40,28 @@ static const char fmt_differ[] = "%s %s differ: char %d, line %d\n";
 static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n";
 
 static const char opt_chars[] = "sl";
-
-enum {
-       OPT_s = 1,
-       OPT_l = 2
-};
+#define CMP_OPT_s (1<<0)
+#define CMP_OPT_l (1<<1)
 
 int cmp_main(int argc, char **argv)
 {
        FILE *fp1, *fp2, *outfile = stdout;
-       const char *filename1, *filename2;
+       const char *filename1, *filename2 = "-";
        const char *fmt;
-       int c1, c2, char_pos, line_pos;
-       int opt_flags;
-       int exit_val = 0;
+       int c1, c2, char_pos = 0, line_pos = 1;
+       unsigned opt;
+       int retval = 0;
 
        bb_default_error_retval = 2;    /* 1 is returned if files are different. */
 
-       opt_flags = bb_getopt_ulflags(argc, argv, opt_chars);
+       opt = bb_getopt_ulflags(argc, argv, opt_chars);
 
-       if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) {
+       if ((opt & (CMP_OPT_s|CMP_OPT_l))
+                       || (((unsigned int)(--argc - optind)) > 1))
                bb_show_usage();
-       }
 
        fp1 = cmp_xfopen_input(filename1 = *(argv += optind));
 
-       filename2 = "-";
        if (*++argv) {
                filename2 = *argv;
        }
@@ -79,19 +75,17 @@ int cmp_main(int argc, char **argv)
                return 0;
        }
 
-       fmt = fmt_differ;
-       if (opt_flags == OPT_l) {
+       if (opt & CMP_OPT_l)
                fmt = fmt_l_opt;
-       }
+       else
+               fmt = fmt_differ;
 
-       char_pos = 0;
-       line_pos = 1;
        do {
                c1 = getc(fp1);
                c2 = getc(fp2);
                ++char_pos;
-               if (c1 != c2) {                 /* Remember -- a read error may have occurred. */
-                       exit_val = 1;           /* But assume the files are different for now. */
+               if (c1 != c2) {                 /* Remember: a read error may have occurred. */
+                       retval = 1;             /* But assume the files are different for now. */
                        if (c2 == EOF) {
                                /* We know that fp1 isn't at EOF or in an error state.  But to
                                 * save space below, things are setup to expect an EOF in fp1
@@ -109,13 +103,14 @@ int cmp_main(int argc, char **argv)
                                 * make sure we fflush before writing to stderr. */
                                xfflush_stdout();
                        }
-                       if (opt_flags != OPT_s) {
-                               if (opt_flags == OPT_l) {
+                       if (!opt & CMP_OPT_s) {
+                               if (opt & CMP_OPT_l) {
                                        line_pos = c1;  /* line_pos is unused in the -l case. */
                                }
                                bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
-                               if (opt_flags) {        /* This must be -l since not -s. */
-                                       /* If we encountered and EOF, the while check will catch it. */
+                               if (opt) {      /* This must be -l since not -s. */
+                                       /* If we encountered an EOF,
+                                        * the while check will catch it. */
                                        continue;
                                }
                        }
@@ -129,5 +124,5 @@ int cmp_main(int argc, char **argv)
        xferror(fp1, filename1);
        xferror(fp2, filename2);
 
-       bb_fflush_stdout_and_exit(exit_val);
+       bb_fflush_stdout_and_exit(retval);
 }
index 1b80e7e..d88a891 100644 (file)
@@ -4,28 +4,24 @@
  *
  * Copyright (C) 1999,2000,2001 by Lineo, inc.
  * Written by Mark Whitley <markw@codepoet.org>
+ * debloated by Bernhard Fischer
  *
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
 #include "busybox.h"
 
-
 /* option vars */
-static const char optstring[] = "b:c:f:d:sn";
-#define OPT_BYTE_FLGS    1
-#define OPT_CHAR_FLGS    2
-#define OPT_FIELDS_FLGS  4
-#define OPT_DELIM_FLGS   8
-#define OPT_SUPRESS_FLGS 16
-static char part; /* (b)yte, (c)har, (f)ields */
-static unsigned int supress_non_delimited_lines;
-static char delim = '\t'; /* delimiter, default is tab */
+static const char *const optstring = "b:c:f:d:sn";
+
+#define CUT_OPT_BYTE_FLGS      (1<<0)
+#define CUT_OPT_CHAR_FLGS      (1<<1)
+#define CUT_OPT_FIELDS_FLGS    (1<<2)
+#define CUT_OPT_DELIM_FLGS     (1<<3)
+#define CUT_OPT_SUPPRESS_FLGS (1<<4)
+static unsigned long opt;
+
+static char delim = '\t';      /* delimiter, default is tab */
 
 struct cut_list {
        int startpos;
@@ -38,295 +34,268 @@ enum {
        NON_RANGE = -1
 };
 
-static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */
-static unsigned int nlists = 0; /* number of elements in above list */
+/* growable array holding a series of lists */
+static struct cut_list *cut_lists;
+static unsigned int nlists;    /* number of elements in above list */
 
 
 static int cmpfunc(const void *a, const void *b)
 {
-       struct cut_list *la = (struct cut_list *)a;
-       struct cut_list *lb = (struct cut_list *)b;
-
-       if (la->startpos > lb->startpos)
-               return 1;
-       if (la->startpos < lb->startpos)
-               return -1;
-       return 0;
-}
+       return (((struct cut_list *) a)->startpos -
+                       ((struct cut_list *) b)->startpos);
 
+}
 
-/*
- * parse_lists() - parses a list and puts values into startpos and endpos.
- * valid list formats: N, N-, N-M, -M
- * more than one list can be separated by commas
- */
-static void parse_lists(char *lists)
+static void cut_file(FILE * file)
 {
-       char *ltok = NULL;
-       char *ntok = NULL;
-       char *junk;
-       int s = 0, e = 0;
-
-       /* take apart the lists, one by one (they are separated with commas */
-       while ((ltok = strsep(&lists, ",")) != NULL) {
-
-               /* it's actually legal to pass an empty list */
-               if (strlen(ltok) == 0)
-                       continue;
-
-               /* get the start pos */
-               ntok = strsep(&ltok, "-");
-               if (ntok == NULL) {
-                       fprintf(stderr, "Help ntok is null for starting position! What do I do?\n");
-               } else if (strlen(ntok) == 0) {
-                       s = BOL;
-               } else {
-                       s = strtoul(ntok, &junk, 10);
-                       if(*junk != '\0' || s < 0)
-                               bb_error_msg_and_die("invalid byte or field list");
-
-                       /* account for the fact that arrays are zero based, while the user
-                        * expects the first char on the line to be char # 1 */
-                       if (s != 0)
-                               s--;
-               }
-
-               /* get the end pos */
-               ntok = strsep(&ltok, "-");
-               if (ntok == NULL) {
-                       e = NON_RANGE;
-               } else if (strlen(ntok) == 0) {
-                       e = EOL;
-               } else {
-                       e = strtoul(ntok, &junk, 10);
-                       if(*junk != '\0' || e < 0)
-                               bb_error_msg_and_die("invalid byte or field list");
-                       /* if the user specified and end position of 0, that means "til the
-                        * end of the line */
-                       if (e == 0)
-                               e = INT_MAX;
-                       e--; /* again, arrays are zero based, lines are 1 based */
-                       if (e == s)
-                               e = NON_RANGE;
-               }
-
-               /* if there's something left to tokenize, the user past an invalid list */
-               if (ltok)
-                       bb_error_msg_and_die("invalid byte or field list");
-
-               /* add the new list */
-               cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
-               cut_lists[nlists-1].startpos = s;
-               cut_lists[nlists-1].endpos = e;
-       }
-
-       /* make sure we got some cut positions out of all that */
-       if (nlists == 0)
-               bb_error_msg_and_die("missing list of positions");
-
-       /* now that the lists are parsed, we need to sort them to make life easier
-        * on us when it comes time to print the chars / fields / lines */
-       qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
+       char *line = NULL;
+       unsigned int linenum = 0;       /* keep these zero-based to be consistent */
 
-}
+       /* go through every line in the file */
+       while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
 
+               /* set up a list so we can keep track of what's been printed */
+               char * printed = xzalloc(strlen(line) * sizeof(char));
+               char * orig_line = line;
+               unsigned int cl_pos = 0;
+               int spos;
 
-static void cut_line_by_chars(const char *line)
-{
-       int c, l;
-       /* set up a list so we can keep track of what's been printed */
-       char *printed = xzalloc(strlen(line));
-
-       /* print the chars specified in each cut list */
-       for (c = 0; c < nlists; c++) {
-               l = cut_lists[c].startpos;
-               while (l < strlen(line)) {
-                       if (!printed[l]) {
-                               putchar(line[l]);
-                               printed[l] = 'X';
+               /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
+               if ((opt & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS))) {
+                       /* print the chars specified in each cut list */
+                       for (; cl_pos < nlists; cl_pos++) {
+                               spos = cut_lists[cl_pos].startpos;
+                               while (spos < strlen(line)) {
+                                       if (!printed[spos]) {
+                                               printed[spos] = 'X';
+                                               putchar(line[spos]);
+                                       }
+                                       spos++;
+                                       if (spos > cut_lists[cl_pos].endpos
+                                               || cut_lists[cl_pos].endpos == NON_RANGE)
+                                               break;
+                               }
+                       }
+               } else if (delim == '\n') {     /* cut by lines */
+                       spos = cut_lists[cl_pos].startpos;
+
+                       /* get out if we have no more lists to process or if the lines
+                        * are lower than what we're interested in */
+                       if (linenum < spos || cl_pos >= nlists)
+                               goto next_line;
+
+                       /* if the line we're looking for is lower than the one we were
+                        * passed, it means we displayed it already, so move on */
+                       while (spos < linenum) {
+                               spos++;
+                               /* go to the next list if we're at the end of this one */
+                               if (spos > cut_lists[cl_pos].endpos
+                                       || cut_lists[cl_pos].endpos == NON_RANGE) {
+                                       cl_pos++;
+                                       /* get out if there's no more lists to process */
+                                       if (cl_pos >= nlists)
+                                               goto next_line;
+                                       spos = cut_lists[cl_pos].startpos;
+                                       /* get out if the current line is lower than the one
+                                        * we just became interested in */
+                                       if (linenum < spos)
+                                               goto next_line;
+                               }
                        }
-                       l++;
-                       if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos)
-                               break;
-               }
-       }
-       putchar('\n'); /* cuz we were handed a chomped line */
-       free(printed);
-}
-
 
-static void cut_line_by_fields(char *line)
-{
-       int c, f;
-       int ndelim = -1; /* zero-based / one-based problem */
-       int nfields_printed = 0;
-       char *field = NULL;
-       char d[2] = { delim, 0 };
-       char *printed;
-
-       /* test the easy case first: does this line contain any delimiters? */
-       if (strchr(line, delim) == NULL) {
-               if (!supress_non_delimited_lines)
+                       /* If we made it here, it means we've found the line we're
+                        * looking for, so print it */
                        puts(line);
-               return;
-       }
-
-       /* set up a list so we can keep track of what's been printed */
-       printed = xzalloc(strlen(line));
-
-       /* process each list on this line, for as long as we've got a line to process */
-       for (c = 0; c < nlists && line; c++) {
-               f = cut_lists[c].startpos;
-               do {
-
-                       /* find the field we're looking for */
-                       while (line && ndelim < f) {
-                               field = strsep(&line, d);
-                               ndelim++;
+                       goto next_line;
+               } else {                /* cut by fields */
+                       int ndelim = -1;        /* zero-based / one-based problem */
+                       int nfields_printed = 0;
+                       char *field = NULL;
+                       const char delimiter[2] = { delim, 0 };
+
+                       /* does this line contain any delimiters? */
+                       if (strchr(line, delim) == NULL) {
+                               if (!(opt & CUT_OPT_SUPPRESS_FLGS))
+                                       puts(line);
+                               goto next_line;
                        }
 
-                       /* we found it, and it hasn't been printed yet */
-                       if (field && ndelim == f && !printed[ndelim]) {
-                               /* if this isn't our first time through, we need to print the
-                                * delimiter after the last field that was printed */
-                               if (nfields_printed > 0)
-                                       putchar(delim);
-                               fputs(field, stdout);
-                               printed[ndelim] = 'X';
-                               nfields_printed++;
+                       /* process each list on this line, for as long as we've got
+                        * a line to process */
+                       for (; cl_pos < nlists && line; cl_pos++) {
+                               spos = cut_lists[cl_pos].startpos;
+                               do {
+
+                                       /* find the field we're looking for */
+                                       while (line && ndelim < spos) {
+                                               field = strsep(&line, delimiter);
+                                               ndelim++;
+                                       }
+
+                                       /* we found it, and it hasn't been printed yet */
+                                       if (field && ndelim == spos && !printed[ndelim]) {
+                                               /* if this isn't our first time through, we need to
+                                                * print the delimiter after the last field that was
+                                                * printed */
+                                               if (nfields_printed > 0)
+                                                       putchar(delim);
+                                               fputs(field, stdout);
+                                               printed[ndelim] = 'X';
+                                               nfields_printed++;      /* shouldn't overflow.. */
+                                       }
+
+                                       spos++;
+
+                                       /* keep going as long as we have a line to work with,
+                                        * this is a list, and we're not at the end of that
+                                        * list */
+                               } while (spos <= cut_lists[cl_pos].endpos && line
+                                                && cut_lists[cl_pos].endpos != NON_RANGE);
                        }
-
-                       f++;
-
-                       /* keep going as long as we have a line to work with, this is a
-                        * list, and we're not at the end of that list */
-               } while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos);
-       }
-
-       /* if we printed anything at all, we need to finish it with a newline cuz
-        * we were handed a chomped line */
-       putchar('\n');
-
-       free(printed);
-}
-
-
-static void cut_file_by_lines(const char *line, unsigned int linenum)
-{
-       static int c = 0;
-       static int l = -1;
-
-       /* I can't initialize this above cuz the "initializer isn't
-        * constant" *sigh* */
-       if (l == -1)
-               l = cut_lists[c].startpos;
-
-       /* get out if we have no more lists to process or if the lines are lower
-        * than what we're interested in */
-       if (c >= nlists || linenum < l)
-               return;
-
-       /* if the line we're looking for is lower than the one we were passed, it
-        * means we displayed it already, so move on */
-       while (l < linenum) {
-               l++;
-               /* move on to the next list if we're at the end of this one */
-               if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) {
-                       c++;
-                       /* get out if there's no more lists to process */
-                       if (c >= nlists)
-                               return;
-                       l = cut_lists[c].startpos;
-                       /* get out if the current line is lower than the one we just became
-                        * interested in */
-                       if (linenum < l)
-                               return;
                }
+               /* if we printed anything at all, we need to finish it with a
+                * newline cuz we were handed a chomped line */
+               putchar('\n');
+         next_line:
+               linenum++;
+               free(printed);
+               free(orig_line);
        }
-
-       /* If we made it here, it means we've found the line we're looking for, so print it */
-       puts(line);
 }
 
-
-/*
- * snippy-snip
- */
-static void cut_file(FILE *file)
+static int getval(char *ntok)
 {
-       char *line = NULL;
-       unsigned int linenum = 0; /* keep these zero-based to be consistent */
-
-       /* go through every line in the file */
-       while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
-
-               /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */
-               if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS)))
-                       cut_line_by_chars(line);
-
-               /* cut based on fields */
-               else {
-                       if (delim == '\n')
-                               cut_file_by_lines(line, linenum);
-                       else
-                               cut_line_by_fields(line);
-               }
+       char *junk;
+       int i = strtoul(ntok, &junk, 10);
 
-               linenum++;
-               free(line);
-       }
+       if (*junk != '\0' || i < 0)
+               bb_error_msg_and_die("invalid byte or field list");
+       return i;
 }
 
+static const char * const _op_on_field = " only when operating on fields";
 
 int cut_main(int argc, char **argv)
 {
-       unsigned long opt;
-       char *sopt, *sdopt;
+       char *sopt, *ltok;
 
        bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
-       opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt);
-       part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
-       if(part == 0)
-               bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
-       if(opt & BB_GETOPT_ERROR)
+       opt =
+               bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &ltok);
+       if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
+               bb_error_msg_and_die
+                       ("expected a list of bytes, characters, or fields");
+       if (opt & BB_GETOPT_ERROR)
                bb_error_msg_and_die("only one type of list may be specified");
-       parse_lists(sopt);
-       if((opt & (OPT_DELIM_FLGS))) {
-               if (strlen(sdopt) > 1) {
+
+       if ((opt & (CUT_OPT_DELIM_FLGS))) {
+               if (strlen(ltok) > 1) {
                        bb_error_msg_and_die("the delimiter must be a single character");
                }
-               delim = sdopt[0];
+               delim = ltok[0];
        }
-       supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS;
 
        /*  non-field (char or byte) cutting has some special handling */
-       if (part != OPT_FIELDS_FLGS) {
-               if (supress_non_delimited_lines) {
-                       bb_error_msg_and_die("suppressing non-delimited lines makes sense"
-                                       " only when operating on fields");
+       if (!(opt & CUT_OPT_FIELDS_FLGS)) {
+               if (opt & CUT_OPT_SUPPRESS_FLGS) {
+                       bb_error_msg_and_die
+                               ("suppressing non-delimited lines makes sense%s",
+                                _op_on_field);
                }
                if (delim != '\t') {
-                       bb_error_msg_and_die("a delimiter may be specified only when operating on fields");
+                       bb_error_msg_and_die
+                               ("a delimiter may be specified%s", _op_on_field);
                }
        }
 
+       /*
+        * parse list and put values into startpos and endpos.
+        * valid list formats: N, N-, N-M, -M
+        * more than one list can be separated by commas
+        */
+       {
+               char *ntok;
+               int s = 0, e = 0;
+
+               /* take apart the lists, one by one (they are separated with commas */
+               while ((ltok = strsep(&sopt, ",")) != NULL) {
+
+                       /* it's actually legal to pass an empty list */
+                       if (strlen(ltok) == 0)
+                               continue;
+
+                       /* get the start pos */
+                       ntok = strsep(&ltok, "-");
+                       if (ntok == NULL) {
+                               bb_error_msg
+                                       ("internal error: ntok is null for start pos!?\n");
+                       } else if (strlen(ntok) == 0) {
+                               s = BOL;
+                       } else {
+                               s = getval(ntok);
+                               /* account for the fact that arrays are zero based, while
+                                * the user expects the first char on the line to be char #1 */
+                               if (s != 0)
+                                       s--;
+                       }
+
+                       /* get the end pos */
+                       ntok = strsep(&ltok, "-");
+                       if (ntok == NULL) {
+                               e = NON_RANGE;
+                       } else if (strlen(ntok) == 0) {
+                               e = EOL;
+                       } else {
+                               e = getval(ntok);
+                               /* if the user specified and end position of 0, that means "til the
+                                * end of the line */
+                               if (e == 0)
+                                       e = EOL;
+                               e--;    /* again, arrays are zero based, lines are 1 based */
+                               if (e == s)
+                                       e = NON_RANGE;
+                       }
+
+                       /* if there's something left to tokenize, the user passed
+                        * an invalid list */
+                       if (ltok)
+                               bb_error_msg_and_die("invalid byte or field list");
+
+                       /* add the new list */
+                       cut_lists =
+                               xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists));
+                       cut_lists[nlists - 1].startpos = s;
+                       cut_lists[nlists - 1].endpos = e;
+               }
+
+               /* make sure we got some cut positions out of all that */
+               if (nlists == 0)
+                       bb_error_msg_and_die("missing list of positions");
+
+               /* now that the lists are parsed, we need to sort them to make life
+                * easier on us when it comes time to print the chars / fields / lines
+                */
+               qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc);
+       }
+
        /* argv[(optind)..(argc-1)] should be names of file to process. If no
         * files were specified or '-' was specified, take input from stdin.
         * Otherwise, we process all the files specified. */
-       if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
+       if (argv[optind] == NULL
+               || (argv[optind][0] == '-' && argv[optind][1] == '\0')) {
                cut_file(stdin);
-       }
-       else {
-               int i;
+       } else {
                FILE *file;
-               for (i = optind; i < argc; i++) {
-                       file = bb_wfopen(argv[i], "r");
-                       if(file) {
+
+               for (; optind < argc; optind++) {
+                       file = bb_wfopen(argv[optind], "r");
+                       if (file) {
                                cut_file(file);
                                fclose(file);
                        }
                }
        }
-
+       if (ENABLE_FEATURE_CLEAN_UP)
+               free(cut_lists);
        return EXIT_SUCCESS;
 }
index f08392e..2a82e04 100644 (file)
@@ -5,14 +5,17 @@
  * by Matthew Grant <grantma@anathoth.gen.nz>
  *
  * iso-format handling added by Robert Griebl <griebl@gmx.de>
+ * bugfixes and cleanup by Bernhard Fischer
  *
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */
 
+#include "busybox.h"
+
 /* This 'date' command supports only 2 time setting formats,
    all the GNU strftime stuff (its in libc, lets use it),
-   setting time using UTC and displaying int, as well as
-   an RFC 822 complient date output for shell scripting
+   setting time using UTC and displaying it, as well as
+   an RFC 2822 compliant date output for shell scripting
    mail commands */
 
 /* Input parsing code is always bulky - used heavy duty libc stuff as
 
 /* Default input handling to save surprising some people */
 
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdio.h>
-#include <string.h>
-#include "busybox.h"
 
 #define DATE_OPT_RFC2822       0x01
 #define DATE_OPT_SET           0x02
 #define DATE_OPT_TIMESPEC      0x20
 #define DATE_OPT_HINT          0x40
 
-
-static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)
-{
-       int nr;
-       char *cp;
-
-       nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon),
-                               &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min),
-                               &(tm_time->tm_year));
-
-       if (nr < 4 || nr > 5) {
-               bb_error_msg_and_die(bb_msg_invalid_date, t_string);
-       }
-
-       cp = strchr(t_string, '.');
-       if (cp) {
-               nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec));
-               if (nr != 1) {
-                       bb_error_msg_and_die(bb_msg_invalid_date, t_string);
-               }
-       }
-
-       /* correct for century  - minor Y2K problem here? */
-       if (tm_time->tm_year >= 1900) {
-               tm_time->tm_year -= 1900;
-       }
-       /* adjust date */
-       tm_time->tm_mon -= 1;
-
-       return (tm_time);
-
-}
-
-
-/* The new stuff for LRP */
-
-static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)
+static void maybe_set_utc(int opt)
 {
-       struct tm t;
-
-       /* Parse input and assign appropriately to tm_time */
-
-       if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min,
-                                                &t.tm_sec) == 3) {
-               /* no adjustments needed */
-       } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour,
-                                                               &t.tm_min) == 2) {
-               /* no adjustments needed */
-       } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon,
-                                               &t.tm_mday, &t.tm_hour,
-                                               &t.tm_min, &t.tm_sec) == 5) {
-               /* Adjust dates from 1-12 to 0-11 */
-               t.tm_mon -= 1;
-       } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon,
-                                               &t.tm_mday,
-                                               &t.tm_hour, &t.tm_min) == 4) {
-               /* Adjust dates from 1-12 to 0-11 */
-               t.tm_mon -= 1;
-       } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year,
-                                               &t.tm_mon, &t.tm_mday,
-                                               &t.tm_hour, &t.tm_min,
-                                                       &t.tm_sec) == 6) {
-               t.tm_year -= 1900;      /* Adjust years */
-               t.tm_mon -= 1;  /* Adjust dates from 1-12 to 0-11 */
-       } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year,
-                                               &t.tm_mon, &t.tm_mday,
-                                               &t.tm_hour, &t.tm_min) == 5) {
-               t.tm_year -= 1900;      /* Adjust years */
-               t.tm_mon -= 1;  /* Adjust dates from 1-12 to 0-11 */
-       } else {
-               bb_error_msg_and_die(bb_msg_invalid_date, t_string);
-       }
-       *tm_time = t;
-       return (tm_time);
+       if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0)
+               bb_error_msg_and_die(bb_msg_memory_exhausted);
 }
 
 int date_main(int argc, char **argv)
 {
-       char *date_str = NULL;
-       char *date_fmt = NULL;
-       int set_time;
-       int utc;
        time_t tm;
-       unsigned long opt;
        struct tm tm_time;
+       unsigned long opt;
+       int ifmt = -1;
+       char *date_str = NULL;
+       char *date_fmt = NULL;
        char *filename = NULL;
-
-       int ifmt = 0;
        char *isofmt_arg;
        char *hintfmt_arg;
 
-       bb_opt_complementally = "?:d--s:s--d";
+       bb_opt_complementally = "?:d--s:s--d"
+               USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
        opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:"
-                                       USE_FEATURE_DATE_ISOFMT("I::D:"),
+                                       USE_FEATURE_DATE_ISOFMT("I::D:"),
                                        &date_str, &date_str, &filename
                                        USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
-       set_time = opt & DATE_OPT_SET;
-       utc = opt & DATE_OPT_UTC;
-       if (utc && putenv("TZ=UTC0") != 0) {
-               bb_error_msg_and_die(bb_msg_memory_exhausted);
-       }
+       maybe_set_utc(opt);
 
-       if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
+       if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
                if (!isofmt_arg) {
-                       ifmt = 1;
+                       ifmt = 0; /* default is date */
                } else {
-                       char *isoformats[]={"date","hours","minutes","seconds"};
-                       for(ifmt = 4; ifmt;)
-                               if(!strcmp(isofmt_arg,isoformats[--ifmt]))
+                       const char * const isoformats[] =
+                               {"date", "hours", "minutes", "seconds"};
+
+                       for (ifmt = 0; ifmt < 4; ifmt++)
+                               if (!strcmp(isofmt_arg, isoformats[ifmt])) {
                                        break;
-               }
-               if (!ifmt) {
-                       bb_show_usage();
+                               }
+                       if (ifmt == 4) /* parse error */
+                               bb_show_usage();
                }
        }
 
@@ -156,18 +78,19 @@ int date_main(int argc, char **argv)
        if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
                date_fmt = &argv[optind][1];    /* Skip over the '+' */
        } else if (date_str == NULL) {
-               set_time = 1;
+               opt |= DATE_OPT_SET;
                date_str = argv[optind];
        }
 
        /* Now we have parsed all the information except the date format
           which depends on whether the clock is being set or read */
 
-       if(filename) {
+       if (filename) {
                struct stat statbuf;
-               xstat(filename,&statbuf);
-               tm=statbuf.st_mtime;
-       } else time(&tm);
+               xstat(filename, &statbuf);
+               tm = statbuf.st_mtime;
+       } else
+               time(&tm);
        memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
        /* Zero out fields - take her back to midnight! */
        if (date_str != NULL) {
@@ -179,9 +102,64 @@ int date_main(int argc, char **argv)
                if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
                        strptime(date_str, hintfmt_arg, &tm_time);
                } else if (strchr(date_str, ':') != NULL) {
-                       date_conv_ftime(&tm_time, date_str);
+                       /* Parse input and assign appropriately to tm_time */
+
+                       if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min,
+                                                                &tm_time.tm_sec) == 3) {
+                               /* no adjustments needed */
+                       } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour,
+                                                                               &tm_time.tm_min) == 2) {
+                               /* no adjustments needed */
+                       } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon,
+                                                               &tm_time.tm_mday, &tm_time.tm_hour,
+                                                               &tm_time.tm_min, &tm_time.tm_sec) == 5) {
+                               /* Adjust dates from 1-12 to 0-11 */
+                               tm_time.tm_mon -= 1;
+                       } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon,
+                                                               &tm_time.tm_mday,
+                                                               &tm_time.tm_hour, &tm_time.tm_min) == 4) {
+                               /* Adjust dates from 1-12 to 0-11 */
+                               tm_time.tm_mon -= 1;
+                       } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year,
+                                                               &tm_time.tm_mon, &tm_time.tm_mday,
+                                                               &tm_time.tm_hour, &tm_time.tm_min,
+                                                                       &tm_time.tm_sec) == 6) {
+                               tm_time.tm_year -= 1900;        /* Adjust years */
+                               tm_time.tm_mon -= 1;    /* Adjust dates from 1-12 to 0-11 */
+                       } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year,
+                                                               &tm_time.tm_mon, &tm_time.tm_mday,
+                                                               &tm_time.tm_hour, &tm_time.tm_min) == 5) {
+                               tm_time.tm_year -= 1900;        /* Adjust years */
+                               tm_time.tm_mon -= 1;    /* Adjust dates from 1-12 to 0-11 */
+                       } else {
+                               bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+                       }
                } else {
-                       date_conv_time(&tm_time, date_str);
+                       int nr;
+                       char *cp;
+
+                       nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon,
+                                               &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min,
+                                               &tm_time.tm_year);
+
+                       if (nr < 4 || nr > 5) {
+                               bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+                       }
+
+                       cp = strchr(date_str, '.');
+                       if (cp) {
+                               nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec);
+                               if (nr != 1) {
+                                       bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+                               }
+                       }
+
+                       /* correct for century  - minor Y2K problem here? */
+                       if (tm_time.tm_year >= 1900) {
+                               tm_time.tm_year -= 1900;
+                       }
+                       /* adjust date */
+                       tm_time.tm_mon -= 1;
                }
 
                /* Correct any day of week and day of year etc. fields */
@@ -190,12 +168,10 @@ int date_main(int argc, char **argv)
                if (tm < 0) {
                        bb_error_msg_and_die(bb_msg_invalid_date, date_str);
                }
-               if (utc && putenv("TZ=UTC0") != 0) {
-                       bb_error_msg_and_die(bb_msg_memory_exhausted);
-               }
+               maybe_set_utc(opt);
 
                /* if setting time, set it */
-               if (set_time && stime(&tm) < 0) {
+               if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
                        bb_perror_msg("cannot set date");
                }
        }
@@ -203,33 +179,43 @@ int date_main(int argc, char **argv)
        /* Display output */
 
        /* Deal with format string */
+
        if (date_fmt == NULL) {
-               /* Start with the default case */
-               
-               date_fmt = (opt & DATE_OPT_RFC2822 ?
-                                       (utc ? "%a, %d %b %Y %H:%M:%S GMT" :
-                                       "%a, %d %b %Y %H:%M:%S %z") :
-                                       "%a %b %e %H:%M:%S %Z %Y");
-
-               if (ENABLE_FEATURE_DATE_ISOFMT) {
-                       if (ifmt == 4)
-                               date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z";
-                       else if (ifmt == 3)
-                               date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z";
-                       else if (ifmt == 2) 
-                               date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z";
-                       else if (ifmt == 1)
-                               date_fmt = "%Y-%m-%d";
-               }
+               int i;
+               date_fmt = xzalloc(32);
+               if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
+                       strcpy(date_fmt, "%Y-%m-%d");
+                       if (ifmt > 0) {
+                               i = 8;
+                               date_fmt[i++] = 'T';
+                               date_fmt[i++] = '%';
+                               date_fmt[i++] = 'H';
+                               if (ifmt > 1) {
+                                       date_fmt[i++] = ':';
+                                       date_fmt[i++] = '%';
+                                       date_fmt[i++] = 'M';
+                               }
+                               if (ifmt > 2) {
+                                       date_fmt[i++] = ':';
+                                       date_fmt[i++] = '%';
+                                       date_fmt[i++] = 'S';
+                               }
+format_utc:
+                               date_fmt[i++] = '%';
+                               date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z';
+                       }
+               } else if (opt & DATE_OPT_RFC2822) {
+                       strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S ");
+                       i = 22;
+                       goto format_utc;
+               } else /* default case */
+                       date_fmt = "%a %b %e %H:%M:%S %Z %Y";
        }
-       
-       if (*date_fmt == '\0') {
 
+       if (*date_fmt == '\0') {
                /* With no format string, just print a blank line */
-               
-               *bb_common_bufsiz1=0;
+               *bb_common_bufsiz1 = 0;
        } else {
-
                /* Handle special conversions */
 
                if (strncmp(date_fmt, "%f", 2) == 0) {
index 052cd29..a9536a5 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "busybox.h"
+#include <signal.h>  /* For FEATURE_DD_SIGNAL_HANDLING */
 
 static const struct suffix_mult dd_suffixes[] = {
        { "c", 1 },
@@ -23,72 +24,72 @@ static const struct suffix_mult dd_suffixes[] = {
        { NULL, 0 }
 };
 
-static size_t out_full;
-static size_t out_part;
-static size_t in_full;
-static size_t in_part;
+static size_t out_full, out_part, in_full, in_part;
 
-static void dd_output_status(int cur_signal)
+static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
 {
-       fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
+       bb_fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
                        (long)in_full, (long)in_part,
                        (long)out_full, (long)out_part);
 }
 
 int dd_main(int argc, char **argv)
 {
+#define sync_flag      (1<<0)
+#define noerror                (1<<1)
+#define trunc_flag     (1<<2)
+#define twobufs_flag (1<<3)
+       int flags = trunc_flag;
        size_t count = -1, oc = 0, ibs = 512, obs = 512;
        ssize_t n;
        off_t seek = 0, skip = 0;
-       int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0,
-               oflag, ifd, ofd, i;
+       int oflag, ifd, ofd;
        const char *infile = NULL, *outfile = NULL;
        char *ibuf, *obuf;
 
-       if (ENABLE_FEATURE_DD_SIGNAL_HANDLING)
-       {
+       if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) {
                struct sigaction sa;
 
                memset(&sa, 0, sizeof(sa));
-               sa.sa_handler = dd_output_status; 
+               sa.sa_handler = dd_output_status;
                sa.sa_flags = SA_RESTART;
                sigemptyset(&sa.sa_mask);
-               sigaction(SIGUSR1, &sa, 0); 
+               sigaction(SIGUSR1, &sa, 0);
        }
 
-       for (i = 1; i < argc; i++) {
-               if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) {
-                       ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
-                       twobufs_flag++;
-               } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) {
-                       obs = bb_xparse_number(argv[i]+4, dd_suffixes);
-                       twobufs_flag++;
-               } else if (!strncmp("bs=", argv[i], 3)) {
-                       ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
-               } else if (!strncmp("count=", argv[i], 6))
-                       count = bb_xparse_number(argv[i]+6, dd_suffixes);
-               else if (!strncmp("seek=", argv[i], 5))
-                       seek = bb_xparse_number(argv[i]+5, dd_suffixes);
-               else if (!strncmp("skip=", argv[i], 5))
-                       skip = bb_xparse_number(argv[i]+5, dd_suffixes);
-               else if (!strncmp("if=", argv[i], 3))
-                       infile = argv[i]+3;
-               else if (!strncmp("of=", argv[i], 3))
-                       outfile = argv[i]+3;
-               else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) {
-                       ibuf = argv[i]+5;
+       for (n = 1; n < argc; n++) {
+               if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) {
+                       ibs = bb_xparse_number(argv[n]+4, dd_suffixes);
+                       flags |= twobufs_flag;
+               } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) {
+                       obs = bb_xparse_number(argv[n]+4, dd_suffixes);
+                       flags |= twobufs_flag;
+               } else if (!strncmp("bs=", argv[n], 3))
+                       ibs = obs = bb_xparse_number(argv[n]+3, dd_suffixes);
+               else if (!strncmp("count=", argv[n], 6))
+                       count = bb_xparse_number(argv[n]+6, dd_suffixes);
+               else if (!strncmp("seek=", argv[n], 5))
+                       seek = bb_xparse_number(argv[n]+5, dd_suffixes);
+               else if (!strncmp("skip=", argv[n], 5))
+                       skip = bb_xparse_number(argv[n]+5, dd_suffixes);
+               else if (!strncmp("if=", argv[n], 3))
+                       infile = argv[n]+3;
+               else if (!strncmp("of=", argv[n], 3))
+                       outfile = argv[n]+3;
+               else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) {
+                       ibuf = argv[n]+5;
                        while (1) {
                                if (!strncmp("notrunc", ibuf, 7)) {
-                                       trunc_flag = FALSE;
+                                       flags ^= trunc_flag;
                                        ibuf += 7;
                                } else if (!strncmp("sync", ibuf, 4)) {
-                                       sync_flag = TRUE;
+                                       flags |= sync_flag;
                                        ibuf += 4;
                                } else if (!strncmp("noerror", ibuf, 7)) {
-                                       noerror = TRUE;
+                                       flags |= noerror;
                                        ibuf += 7;
                                } else {
-                                       bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv");
+                                       bb_error_msg_and_die(bb_msg_invalid_arg, argv[n]+5, "conv");
                                }
                                if (ibuf[0] == '\0') break;
                                if (ibuf[0] == ',') ibuf++;
@@ -98,12 +99,14 @@ int dd_main(int argc, char **argv)
        }
        ibuf = xmalloc(ibs);
 
-       if (twobufs_flag) obuf = xmalloc(obs);
-       else obuf = ibuf;
+       if (flags & twobufs_flag)
+               obuf = xmalloc(obs);
+       else
+               obuf = ibuf;
 
-       if (infile != NULL) {
+       if (infile != NULL)
                ifd = xopen(infile, O_RDONLY);
-       else {
+       else {
                ifd = STDIN_FILENO;
                infile = bb_msg_standard_input;
        }
@@ -111,20 +114,18 @@ int dd_main(int argc, char **argv)
        if (outfile != NULL) {
                oflag = O_WRONLY | O_CREAT;
 
-               if (!seek && trunc_flag) {
+               if (!seek && (flags & trunc_flag))
                        oflag |= O_TRUNC;
-               }
 
                ofd = xopen3(outfile, oflag, 0666);
 
-               if (seek && trunc_flag) {
+               if (seek && (flags & trunc_flag)) {
                        if (ftruncate(ofd, seek * obs) < 0) {
                                struct stat st;
 
-                               if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
-                                               S_ISDIR (st.st_mode)) {
-                                       bb_perror_msg_and_die("%s", outfile);
-                               }
+                               if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) ||
+                                               S_ISDIR(st.st_mode))
+                                       goto die_outfile;
                        }
                }
        } else {
@@ -145,44 +146,42 @@ int dd_main(int argc, char **argv)
        }
 
        if (seek) {
-               if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
-                       bb_perror_msg_and_die("%s", outfile);
-               }
+               if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
+                       goto die_outfile;
        }
 
        while (in_full + in_part != count) {
-               if (noerror) {
+               if (flags & noerror) {
                        /* Pre-zero the buffer when doing the noerror thing */
                        memset(ibuf, '\0', ibs);
                }
 
                n = safe_read(ifd, ibuf, ibs);
-               if (n == 0) {
+               if (n == 0)
                        break;
-               }
                if (n < 0) {
-                       if (noerror) {
+                       if (flags & noerror) {
                                n = ibs;
                                bb_perror_msg("%s", infile);
-                       } else {
+                       } else
                                bb_perror_msg_and_die("%s", infile);
-                       }
                }
-               if ((size_t)n == ibs) {
+               if ((size_t)n == ibs)
                        in_full++;
-               else {
+               else {
                        in_part++;
                        if (sync_flag) {
                                memset(ibuf + n, '\0', ibs - n);
                                n = ibs;
                        }
                }
-               if (twobufs_flag) {
+               if (flags & twobufs_flag) {
                        char *tmp = ibuf;
                        while (n) {
                                size_t d = obs - oc;
 
-                               if (d > n) d = n;
+                               if (d > n)
+                                       d = n;
                                memcpy(obuf + oc, tmp, d);
                                n -= d;
                                tmp += d;
@@ -195,8 +194,10 @@ int dd_main(int argc, char **argv)
                        }
                } else {
                        xwrite(ofd, ibuf, n);
-                       if (n == ibs) out_full++;
-                       else out_part++;
+                       if (n == ibs)
+                               out_full++;
+                       else
+                               out_part++;
                }
        }
        
@@ -209,6 +210,7 @@ int dd_main(int argc, char **argv)
        }
 
        if (close (ofd) < 0) {
+die_outfile:
                bb_perror_msg_and_die("%s", outfile);
        }
 
index 29427c7..3cc9355 100644 (file)
  * 4) Fixed busybox bug #1284 involving long overflow with human_readable.
  */
 
-#include <stdlib.h>
-#include <limits.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/stat.h>
 #include "busybox.h"
 
 #ifdef CONFIG_FEATURE_HUMAN_READABLE
@@ -57,7 +52,7 @@ static int one_file_system;
 static dev_t dir_dev;
 
 
-static void print(long size, char *filename)
+static void print(long size, const char * const filename)
 {
        /* TODO - May not want to defer error checking here. */
 #ifdef CONFIG_FEATURE_HUMAN_READABLE
@@ -73,7 +68,7 @@ static void print(long size, char *filename)
 }
 
 /* tiny recursive du */
-static long du(char *filename)
+static long du(const char * const filename)
 {
        struct stat statbuf;
        long sum;
index 0a1baa1..e7fdc5f 100644 (file)
@@ -37,11 +37,13 @@ typedef enum valtype TYPE;
 
 #if ENABLE_EXPR_MATH_SUPPORT_64
 typedef int64_t arith_t;
+
 #define PF_REZ      "ll"
 #define PF_REZ_TYPE (long long)
 #define STRTOL(s, e, b) strtoll(s, e, b)
 #else
 typedef long arith_t;
+
 #define PF_REZ      "l"
 #define PF_REZ_TYPE (long)
 #define STRTOL(s, e, b) strtol(s, e, b)
@@ -49,8 +51,8 @@ typedef long arith_t;
 
 /* A value is.... */
 struct valinfo {
-       TYPE type;                      /* Which kind. */
-       union {                         /* The value itself. */
+       TYPE type;                      /* Which kind. */
+       union {                         /* The value itself. */
                arith_t i;
                char *s;
        } u;
@@ -60,17 +62,17 @@ typedef struct valinfo VALUE;
 /* The arguments given to the program, minus the program name.  */
 static char **args;
 
-static VALUE *docolon (VALUE *sv, VALUE *pv);
-static VALUE *eval (void);
-static VALUE *int_value (arith_t i);
-static VALUE *str_value (char *s);
-static int nextarg (char *str);
-static int null (VALUE *v);
-static int toarith (VALUE *v);
-static void freev (VALUE *v);
-static void tostring (VALUE *v);
-
-int expr_main (int argc, char **argv)
+static VALUE *docolon(VALUE * sv, VALUE * pv);
+static VALUE *eval(void);
+static VALUE *int_value(arith_t i);
+static VALUE *str_value(char *s);
+static int nextarg(char *str);
+static int null(VALUE * v);
+static int toarith(VALUE * v);
+static void freev(VALUE * v);
+static void tostring(VALUE * v);
+
+int expr_main(int argc, char **argv)
 {
        VALUE *v;
 
@@ -80,25 +82,25 @@ int expr_main (int argc, char **argv)
 
        args = argv + 1;
 
-       v = eval ();
+       v = eval();
        if (*args)
-               bb_error_msg_and_die ("syntax error");
+               bb_error_msg_and_die("syntax error");
 
        if (v->type == integer)
-               printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
+               bb_printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
        else
-               puts (v->u.s);
+               puts(v->u.s);
 
-       exit (null (v));
+       exit(null(v));
 }
 
 /* Return a VALUE for I.  */
 
-static VALUE *int_value (arith_t i)
+static VALUE *int_value(arith_t i)
 {
        VALUE *v;
 
-       v = xmalloc (sizeof(VALUE));
+       v = xmalloc(sizeof(VALUE));
        v->type = integer;
        v->u.i = i;
        return v;
@@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i)
 
 /* Return a VALUE for S.  */
 
-static VALUE *str_value (char *s)
+static VALUE *str_value(char *s)
 {
        VALUE *v;
 
@@ -118,28 +120,26 @@ static VALUE *str_value (char *s)
 
 /* Free VALUE V, including structure components.  */
 
-static void freev (VALUE *v)
+static void freev(VALUE * v)
 {
        if (v->type == string)
-               free (v->u.s);
-       free (v);
+               free(v->u.s);
+       free(v);
 }
 
 /* Return nonzero if V is a null-string or zero-number.  */
 
-static int null (VALUE *v)
+static int null(VALUE * v)
 {
-       switch (v->type) {
-               case integer:
-                       return v->u.i == 0;
-               default: /* string: */
-                       return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
-       }
+       if (v->type == integer)
+               return v->u.i == 0;
+       else                            /* string: */
+               return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0;
 }
 
 /* Coerce V to a string value (can't fail).  */
 
-static void tostring (VALUE *v)
+static void tostring(VALUE * v)
 {
        if (v->type == integer) {
                v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i);
@@ -149,9 +149,9 @@ static void tostring (VALUE *v)
 
 /* Coerce V to an integer value.  Return 1 on success, 0 on failure.  */
 
-static int toarith (VALUE *v)
+static int toarith(VALUE * v)
 {
-       if(v->type == string) {
+       if (v->type == string) {
                arith_t i;
                char *e;
 
@@ -160,7 +160,7 @@ static int toarith (VALUE *v)
                i = STRTOL(v->u.s, &e, 10);
                if ((v->u.s == e) || *e)
                        return 0;
-               free (v->u.s);
+               free(v->u.s);
                v->u.i = i;
                v->type = integer;
        }
@@ -170,221 +170,207 @@ static int toarith (VALUE *v)
 /* Return nonzero if the next token matches STR exactly.
    STR must not be NULL.  */
 
-static int
-nextarg (char *str)
+static int nextarg(char *str)
 {
        if (*args == NULL)
                return 0;
-       return strcmp (*args, str) == 0;
+       return strcmp(*args, str) == 0;
 }
 
 /* The comparison operator handling functions.  */
 
-static int cmp_common (VALUE *l, VALUE *r, int op)
+static int cmp_common(VALUE * l, VALUE * r, int op)
 {
        int cmpval;
 
        if (l->type == string || r->type == string) {
-               tostring (l);
-               tostring (r);
-               cmpval = strcmp (l->u.s, r->u.s);
-       }
-       else
+               tostring(l);
+               tostring(r);
+               cmpval = strcmp(l->u.s, r->u.s);
+       } else
                cmpval = l->u.i - r->u.i;
-       switch(op) {
-               case '<':
-                       return cmpval < 0;
-               case ('L'+'E'):
-                       return cmpval <= 0;
-               case '=':
-                       return cmpval == 0;
-               case '!':
-                       return cmpval != 0;
-               case '>':
-                       return cmpval > 0;
-               default: /* >= */
-                       return cmpval >= 0;
-       }
+       if (op == '<')
+               return cmpval < 0;
+       else if (op == ('L' + 'E'))
+               return cmpval <= 0;
+       else if (op == '=')
+               return cmpval == 0;
+       else if (op == '!')
+               return cmpval != 0;
+       else if (op == '>')
+               return cmpval > 0;
+       else                            /* >= */
+               return cmpval >= 0;
 }
 
 /* The arithmetic operator handling functions.  */
 
-static arith_t arithmetic_common (VALUE *l, VALUE *r, int op)
+static arith_t arithmetic_common(VALUE * l, VALUE * r, int op)
 {
-  arith_t li, ri;
-
-  if (!toarith (l) || !toarith (r))
-    bb_error_msg_and_die ("non-numeric argument");
-  li = l->u.i;
-  ri = r->u.i;
-  if((op == '/' || op == '%') && ri == 0)
-    bb_error_msg_and_die ( "division by zero");
-  switch(op) {
-       case '+':
+       arith_t li, ri;
+
+       if (!toarith(l) || !toarith(r))
+               bb_error_msg_and_die("non-numeric argument");
+       li = l->u.i;
+       ri = r->u.i;
+       if ((op == '/' || op == '%') && ri == 0)
+               bb_error_msg_and_die("division by zero");
+       if (op == '+')
                return li + ri;
-       case '-':
+       else if (op == '-')
                return li - ri;
-       case '*':
+       else if (op == '*')
                return li * ri;
-       case '/':
+       else if (op == '/')
                return li / ri;
-       default:
+       else
                return li % ri;
-  }
 }
 
 /* Do the : operator.
    SV is the VALUE for the lhs (the string),
    PV is the VALUE for the rhs (the pattern).  */
 
-static VALUE *docolon (VALUE *sv, VALUE *pv)
+static VALUE *docolon(VALUE * sv, VALUE * pv)
 {
        VALUE *v;
        regex_t re_buffer;
        const int NMATCH = 2;
        regmatch_t re_regs[NMATCH];
 
-       tostring (sv);
-       tostring (pv);
+       tostring(sv);
+       tostring(pv);
 
        if (pv->u.s[0] == '^') {
-               fprintf (stderr, "\
+               fprintf(stderr, "\
 warning: unportable BRE: `%s': using `^' as the first character\n\
-of a basic regular expression is not portable; it is being ignored",
-               pv->u.s);
+of a basic regular expression is not portable; it is being ignored", pv->u.s);
        }
 
-       memset (&re_buffer, 0, sizeof (re_buffer));
-       memset (re_regs, 0, sizeof (*re_regs));
-       if( regcomp (&re_buffer, pv->u.s, 0) != 0 )
+       memset(&re_buffer, 0, sizeof(re_buffer));
+       memset(re_regs, 0, sizeof(*re_regs));
+       if (regcomp(&re_buffer, pv->u.s, 0) != 0)
                bb_error_msg_and_die("Invalid regular expression");
 
        /* expr uses an anchored pattern match, so check that there was a
         * match and that the match starts at offset 0. */
-       if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
-                       re_regs[0].rm_so == 0) {
+       if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
+               re_regs[0].rm_so == 0) {
                /* Were \(...\) used? */
                if (re_buffer.re_nsub > 0) {
                        sv->u.s[re_regs[1].rm_eo] = '\0';
-                       v = str_value (sv->u.s + re_regs[1].rm_so);
-               }
-               else
-                       v = int_value (re_regs[0].rm_eo);
-       }
-       else {
+                       v = str_value(sv->u.s + re_regs[1].rm_so);
+               } else
+                       v = int_value(re_regs[0].rm_eo);
+       } else {
                /* Match failed -- return the right kind of null.  */
                if (re_buffer.re_nsub > 0)
-                       v = str_value ("");
+                       v = str_value("");
                else
-                       v = int_value (0);
+                       v = int_value(0);
        }
        return v;
 }
 
 /* Handle bare operands and ( expr ) syntax.  */
 
-static VALUE *eval7 (void)
+static VALUE *eval7(void)
 {
        VALUE *v;
 
        if (!*args)
-               bb_error_msg_and_die ( "syntax error");
+               bb_error_msg_and_die("syntax error");
 
-       if (nextarg ("(")) {
+       if (nextarg("(")) {
                args++;
-               v = eval ();
-               if (!nextarg (")"))
-                       bb_error_msg_and_die ( "syntax error");
-                       args++;
-                       return v;
-               }
+               v = eval();
+               if (!nextarg(")"))
+                       bb_error_msg_and_die("syntax error");
+               args++;
+               return v;
+       }
 
-       if (nextarg (")"))
-               bb_error_msg_and_die ( "syntax error");
+       if (nextarg(")"))
+               bb_error_msg_and_die("syntax error");
 
-       return str_value (*args++);
+       return str_value(*args++);
 }
 
 /* Handle match, substr, index, length, and quote keywords.  */
 
-static VALUE *eval6 (void)
+static VALUE *eval6(void)
 {
        VALUE *l, *r, *v, *i1, *i2;
 
-       if (nextarg ("quote")) {
+       if (nextarg("quote")) {
                args++;
                if (!*args)
-                       bb_error_msg_and_die ( "syntax error");
-               return str_value (*args++);
-       }
-       else if (nextarg ("length")) {
+                       bb_error_msg_and_die("syntax error");
+               return str_value(*args++);
+       } else if (nextarg("length")) {
                args++;
-               r = eval6 ();
-               tostring (r);
-               v = int_value (strlen (r->u.s));
-               freev (r);
+               r = eval6();
+               tostring(r);
+               v = int_value(strlen(r->u.s));
+               freev(r);
                return v;
-       }
-       else if (nextarg ("match")) {
+       } else if (nextarg("match")) {
                args++;
-               l = eval6 ();
-               r = eval6 ();
-               v = docolon (l, r);
-               freev (l);
-               freev (r);
+               l = eval6();
+               r = eval6();
+               v = docolon(l, r);
+               freev(l);
+               freev(r);
                return v;
-       }
-       else if (nextarg ("index")) {
+       } else if (nextarg("index")) {
                args++;
-               l = eval6 ();
-               r = eval6 ();
-               tostring (l);
-               tostring (r);
-               v = int_value (strcspn (l->u.s, r->u.s) + 1);
-               if (v->u.i == (arith_t) strlen (l->u.s) + 1)
+               l = eval6();
+               r = eval6();
+               tostring(l);
+               tostring(r);
+               v = int_value(strcspn(l->u.s, r->u.s) + 1);
+               if (v->u.i == (arith_t) strlen(l->u.s) + 1)
                        v->u.i = 0;
-               freev (l);
-               freev (r);
+               freev(l);
+               freev(r);
                return v;
-       }
-       else if (nextarg ("substr")) {
+       } else if (nextarg("substr")) {
                args++;
-               l = eval6 ();
-               i1 = eval6 ();
-               i2 = eval6 ();
-               tostring (l);
-               if (!toarith (i1) || !toarith (i2)
-                       || i1->u.i > (arith_t) strlen (l->u.s)
+               l = eval6();
+               i1 = eval6();
+               i2 = eval6();
+               tostring(l);
+               if (!toarith(i1) || !toarith(i2)
+                       || i1->u.i > (arith_t) strlen(l->u.s)
                        || i1->u.i <= 0 || i2->u.i <= 0)
-               v = str_value ("");
+                       v = str_value("");
                else {
-                       v = xmalloc (sizeof(VALUE));
+                       v = xmalloc(sizeof(VALUE));
                        v->type = string;
                        v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
                }
-               freev (l);
-               freev (i1);
-               freev (i2);
+               freev(l);
+               freev(i1);
+               freev(i2);
                return v;
-       }
-       else
-               return eval7 ();
+       } else
+               return eval7();
 }
 
 /* Handle : operator (pattern matching).
    Calls docolon to do the real work.  */
 
-static VALUE *eval5 (void)
+static VALUE *eval5(void)
 {
        VALUE *l, *r, *v;
 
-       l = eval6 ();
-       while (nextarg (":")) {
+       l = eval6();
+       while (nextarg(":")) {
                args++;
-               r = eval6 ();
-               v = docolon (l, r);
-               freev (l);
-               freev (r);
+               r = eval6();
+               v = docolon(l, r);
+               freev(l);
+               freev(r);
                l = v;
        }
        return l;
@@ -392,128 +378,126 @@ static VALUE *eval5 (void)
 
 /* Handle *, /, % operators.  */
 
-static VALUE *eval4 (void)
+static VALUE *eval4(void)
 {
        VALUE *l, *r;
        int op;
        arith_t val;
 
-       l = eval5 ();
+       l = eval5();
        while (1) {
-               if (nextarg ("*"))
+               if (nextarg("*"))
                        op = '*';
-               else if (nextarg ("/"))
+               else if (nextarg("/"))
                        op = '/';
-               else if (nextarg ("%"))
+               else if (nextarg("%"))
                        op = '%';
                else
                        return l;
                args++;
-               r = eval5 ();
-               val = arithmetic_common (l, r, op);
-               freev (l);
-               freev (r);
-               l = int_value (val);
+               r = eval5();
+               val = arithmetic_common(l, r, op);
+               freev(l);
+               freev(r);
+               l = int_value(val);
        }
 }
 
 /* Handle +, - operators.  */
 
-static VALUE *eval3 (void)
+static VALUE *eval3(void)
 {
        VALUE *l, *r;
        int op;
        arith_t val;
 
-       l = eval4 ();
+       l = eval4();
        while (1) {
-               if (nextarg ("+"))
+               if (nextarg("+"))
                        op = '+';
-               else if (nextarg ("-"))
+               else if (nextarg("-"))
                        op = '-';
                else
                        return l;
                args++;
-               r = eval4 ();
-               val = arithmetic_common (l, r, op);
-               freev (l);
-               freev (r);
-               l = int_value (val);
+               r = eval4();
+               val = arithmetic_common(l, r, op);
+               freev(l);
+               freev(r);
+               l = int_value(val);
        }
 }
 
 /* Handle comparisons.  */
 
-static VALUE *eval2 (void)
+static VALUE *eval2(void)
 {
        VALUE *l, *r;
        int op;
        arith_t val;
 
-       l = eval3 ();
+       l = eval3();
        while (1) {
-               if (nextarg ("<"))
+               if (nextarg("<"))
                        op = '<';
-               else if (nextarg ("<="))
-                       op = 'L'+'E';
-               else if (nextarg ("=") || nextarg ("=="))
+               else if (nextarg("<="))
+                       op = 'L' + 'E';
+               else if (nextarg("=") || nextarg("=="))
                        op = '=';
-               else if (nextarg ("!="))
+               else if (nextarg("!="))
                        op = '!';
-               else if (nextarg (">="))
-                       op = 'G'+'E';
-               else if (nextarg (">"))
+               else if (nextarg(">="))
+                       op = 'G' + 'E';
+               else if (nextarg(">"))
                        op = '>';
                else
                        return l;
                args++;
-               r = eval3 ();
-               toarith (l);
-               toarith (r);
-               val = cmp_common (l, r, op);
-               freev (l);
-               freev (r);
-               l = int_value (val);
+               r = eval3();
+               toarith(l);
+               toarith(r);
+               val = cmp_common(l, r, op);
+               freev(l);
+               freev(r);
+               l = int_value(val);
        }
 }
 
 /* Handle &.  */
 
-static VALUE *eval1 (void)
+static VALUE *eval1(void)
 {
        VALUE *l, *r;
 
-       l = eval2 ();
-       while (nextarg ("&")) {
+       l = eval2();
+       while (nextarg("&")) {
                args++;
-               r = eval2 ();
-               if (null (l) || null (r)) {
-                       freev (l);
-                       freev (r);
-                       l = int_value (0);
-               }
-               else
-                       freev (r);
+               r = eval2();
+               if (null(l) || null(r)) {
+                       freev(l);
+                       freev(r);
+                       l = int_value(0);
+               } else
+                       freev(r);
        }
        return l;
 }
 
 /* Handle |.  */
 
-static VALUE *eval (void)
+static VALUE *eval(void)
 {
        VALUE *l, *r;
 
-       l = eval1 ();
-       while (nextarg ("|")) {
+       l = eval1();
+       while (nextarg("|")) {
                args++;
-               r = eval1 ();
-               if (null (l)) {
-                       freev (l);
+               r = eval1();
+               if (null(l)) {
+                       freev(l);
                        l = r;
-               }
-               else
-                       freev (r);
+               } else
+                       freev(r);
        }
        return l;
 }
index 2edd920..d6a76db 100644 (file)
  * Licensed under the GPL v2, see the file LICENSE in this tarball.
  */
 
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
 #include "busybox.h"
 
 /* 1 if any of the files read were the standard input */
@@ -38,14 +32,15 @@ static int bsd_sum_file(const char *file, int print_name)
        int checksum = 0;          /* The checksum mod 2^16. */
        uintmax_t total_bytes = 0; /* The number of bytes. */
        int ch;                    /* Each character read. */
+       int ret = 0;
 
        if (IS_STDIN(file)) {
                fp = stdin;
-               have_read_stdin = 1;
+               have_read_stdin++;
        } else {
                fp = bb_wfopen(file, "r");
                if (fp == NULL)
-                       return 0;
+                       goto out;
        }
 
        while ((ch = getc(fp)) != EOF) {
@@ -58,21 +53,21 @@ static int bsd_sum_file(const char *file, int print_name)
        if (ferror(fp)) {
                bb_perror_msg(file);
                bb_fclose_nonstdin(fp);
-               return 0;
+               goto out;
        }
 
        if (bb_fclose_nonstdin(fp) == EOF) {
                bb_perror_msg(file);
-               return 0;
+               goto out;
        }
-
+       ret++;
        printf("%05d %5ju ", checksum, (total_bytes+1023)/1024);
        if (print_name > 1)
                puts(file);
        else
                printf("\n");
-
-       return 1;
+out:
+       return ret;
 }
 
 /* Calculate and print the checksum and the size in 512-byte blocks
index 80a66fb..49f1bcd 100644 (file)
@@ -42,20 +42,25 @@ static const struct suffix_mult tail_suffixes[] = {
 
 static int status;
 
-static void tail_xprint_header(const char *fmt, const char *filename)
+static void tail_xbb_full_write(const char *buf, size_t len)
 {
-       /* If we get an output error, there is really no sense in continuing. */
-       if (dprintf(STDOUT_FILENO, fmt, filename) < 0) {
+       /* If we get a write error, there is really no sense in continuing. */
+       if (full_write(STDOUT_FILENO, buf, len) < 0)
                bb_perror_nomsg_and_die();
-       }
 }
 
-/* len should probably be size_t */
-static void tail_xbb_full_write(const char *buf, size_t len)
+static void tail_xprint_header(const char *fmt, const char *filename)
 {
-       /* If we get a write error, there is really no sense in continuing. */
-       if (full_write(STDOUT_FILENO, buf, len) < 0)
+#if defined __GLIBC__
+       if (dprintf(STDOUT_FILENO, fmt, filename) < 0) {
                bb_perror_nomsg_and_die();
+       }
+#else
+       int hdr_len = strlen(fmt) + strlen(filename);
+       char *hdr = xzalloc(hdr_len);
+       sprintf(hdr, filename, filename);
+       tail_xbb_full_write(hdr, hdr_len);
+#endif
 }
 
 static ssize_t tail_read(int fd, char *buf, size_t count)
index 4d0e6ff..1f59f03 100644 (file)
@@ -11,6 +11,7 @@
 /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
 
 #include "busybox.h"
+#include <signal.h>
 
 int tee_main(int argc, char **argv)
 {
@@ -37,7 +38,7 @@ int tee_main(int argc, char **argv)
 
        /* gnu tee ignores SIGPIPE in case one of the output files is a pipe
         * that doesn't consume all its input.  Good idea... */
-       signal(SIGPIPE, SIG_IGN);               /* TODO - switch to sigaction.*/
+       signal(SIGPIPE, SIG_IGN);       /* TODO - switch to sigaction.*/
 
        /* Allocate an array of FILE *'s, with one extra for a sentinal. */
        p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2));
index c8b16b9..7b9c669 100644 (file)
@@ -3,6 +3,7 @@
  * Mini watch implementation for busybox
  *
  * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de>
+ * Copyrigjt (C) Mar 16, 2003 Manuel Novoa III   (mjn3@codepoet.org)
  *
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 /* BB_AUDIT SUSv3 N/A */
 /* BB_AUDIT GNU defects -- only option -n is supported. */
 
-/* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
- *
- * Removed dependency on date_main(), added proper error checking, and
- * reduced size.
- */
-
 #include "busybox.h"
 
+
 int watch_main(int argc, char **argv)
 {
        int width, len;
@@ -26,19 +22,18 @@ int watch_main(int argc, char **argv)
 
        if (argc < 2) bb_show_usage();
 
-       get_terminal_width_height(1, &width, 0);
+       get_terminal_width_height(STDOUT_FILENO, &width, 0);
        header = xzalloc(width--);
 
        /* don't use getopt, because it permutes the arguments */
        ++argv;
-       if ((argc > 3) && !strcmp(*argv, "-n")) {
+       if ((argc > 3) && argv[0][0] == '-' && argv[0][1] == 'n') {
                period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX);
                argv += 2;
        }
        watched_argv = argv;
 
        /* create header */
-
        len = snprintf(header, width, "Every %ds:", period);
        while (*argv && len<width)
                snprintf(header+len, width-len, " %s", *(argv++));
@@ -50,11 +45,13 @@ int watch_main(int argc, char **argv)
                time(&t);
                thyme = ctime(&t);
                len = strlen(thyme);
-               if (len < width) header[width-len] = 0;
-               
-               printf("\033[H\033[J%s %s\n", header, thyme);
+               if (len < width)
+                       header[width-len] = 0;
+               bb_printf("\033[H\033[J%s %s\n", header, thyme);
 
                waitpid(xspawn(watched_argv),0,0);
                sleep(period);
        }
+       if (ENABLE_FEATURE_CLEAN_UP)
+               free(header);
 }
index 3c563a9..b945861 100644 (file)
 #define  PATH_MAX         256
 #endif
 
-#ifdef DMALLOC
-#include <dmalloc.h>
-#endif
-
 /* Some useful definitions */
 #undef FALSE
 #define FALSE   ((int) 0)
@@ -211,7 +207,9 @@ extern int bb_fprintf(FILE * __restrict stream, const char * __restrict format,
 extern int bb_printf(const char * __restrict format, ...)
        __attribute__ ((format (printf, 1, 2)));
 
-//#warning rename to xferror_filename?
+#if ENABLE_NITPICK
+#warning rename to xferror_filename?
+#endif
 extern void xferror(FILE *fp, const char *fn);
 extern void xferror_stdout(void);
 extern void xfflush_stdout(void);
@@ -265,7 +263,9 @@ extern long bb_xgetlarg_bnd_sfx(const char *arg, int base,
 extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes);
 
 
-//#warning pitchable now?
+#if ENABLE_NITPICK
+#warning pitchable now?
+#endif
 extern unsigned long bb_xparse_number(const char *numstr,
                const struct suffix_mult *suffixes);
 
@@ -330,7 +330,9 @@ char *concat_path_file(const char *path, const char *filename);
 char *concat_subpath_file(const char *path, const char *filename);
 char *last_char_is(const char *s, int c);
 
-//#warning yuk!
+#if ENABLE_NITPICK
+#warning yuk!
+#endif
 char *fgets_str(FILE *file, const char *terminating_string);
 
 extern int uncompress(int fd_in, int fd_out);
@@ -344,7 +346,9 @@ extern int xconnect(struct sockaddr_in *s_addr);
 extern unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port);
 extern void bb_lookup_host(struct sockaddr_in *s_in, const char *host);
 
-//#warning wrap this?
+#if ENABLE_NITPICK
+#warning wrap this?
+#endif
 char *dirname (char *path);
 
 int bb_make_directory (char *path, long mode, int flags);
@@ -456,8 +460,10 @@ extern int bb_default_error_retval;
 # define FB_0 "/dev/fb0"
 #endif
 
-//#warning put these in .o files
 
+#if ENABLE_NITPICK
+#warning put these in .o files
+#endif
 /* The following devices are the same on devfs and non-devfs systems.  */
 #define CURRENT_TTY "/dev/tty"
 #define CONSOLE_DEV "/dev/console"
@@ -581,4 +587,8 @@ extern const char BB_BANNER[];
 #undef isupper
 #undef isxdigit
 
+#ifdef DMALLOC
+#include <dmalloc.h>
+#endif
+
 #endif /* __LIBBUSYBOX_H__ */
index 05ab0c1..1dbbc00 100644 (file)
@@ -10,8 +10,6 @@
 #define ARCHIVE_NOPRESERVE_OWN          32
 #define ARCHIVE_NOPRESERVE_PERM         64
 
-#include <sys/types.h>
-#include <stdio.h>
 #include "libbb.h"
 
 typedef struct file_headers_s {
index ced9f68..0f95708 100644 (file)
@@ -1426,12 +1426,12 @@ USE_FEATURE_DATE_ISOFMT( \
 #define ipcrm_trivial_usage \
        "[-[MQS] key] [-[mqs] id]"
 #define ipcrm_full_usage \
-       "The upper-case options MQS are used to remove a shared memory\n" \
-       "segment by an shmkey value. The lower-case options mqs are used\n" \
+       "The upper-case options MQS are used to remove a shared memory segment by a\n" \
+       "segment by a shmkey value. The lower-case options mqs are used\n" \
        "to remove a segment by shmid value.\n" \
-       "\t-m | -M\tRemove the memory segment after the last detach\n" \
-       "\t-q | -Q\tRemove the message queue\n" \
-       "\t-s | -S\tRemove the semaphore"
+       "\t-[mM]\tRemove the memory segment after the last detach\n" \
+       "\t-[qQ]\tRemove the message queue\n" \
+       "\t-[sS]\tRemove the semaphore"
 
 #define ipcs_trivial_usage \
        "[[-smq] -i shmid] | [[-asmq] [-tclup]]"
index 4d81fdc..b2b53a7 100644 (file)
  * succeeded. */
 
 #ifndef DMALLOC
+/* dmalloc provides variants of these that do abort() on failure.
+ * Since dmalloc's prototypes overwrite the impls here as they are
+ * included after these prototypes in libbb.h, all is well.
+ */
 #ifdef L_xmalloc
-// Die if we can't allocate size bytes of memory.
+/* Die if we can't allocate size bytes of memory. */
 void *xmalloc(size_t size)
 {
        void *ptr = malloc(size);
@@ -28,9 +32,9 @@ void *xmalloc(size_t size)
 #endif
 
 #ifdef L_xrealloc
-// Die if we can't resize previously allocated memory.  (This returns a pointer
-// to the new memory, which may or may not be the same as the old memory.
-// It'll copy the contents to a new chunk and free the old one if necessary.)
+/* Die if we can't resize previously allocated memory.  (This returns a pointer
+ * to the new memory, which may or may not be the same as the old memory.
+ * It'll copy the contents to a new chunk and free the old one if necessary.) */
 void *xrealloc(void *ptr, size_t size)
 {
        ptr = realloc(ptr, size);
@@ -39,9 +43,11 @@ void *xrealloc(void *ptr, size_t size)
        return ptr;
 }
 #endif
+#endif /* DMALLOC */
+
 
 #ifdef L_xzalloc
-// Die if we can't allocate and zero size bytes of memory.
+/* Die if we can't allocate and zero size bytes of memory. */
 void *xzalloc(size_t size)
 {
        void *ptr = xmalloc(size);
@@ -50,10 +56,8 @@ void *xzalloc(size_t size)
 }
 #endif
 
-#endif /* DMALLOC */
-
 #ifdef L_xstrdup
-// Die if we can't copy a string to freshly allocated memory.
+/* Die if we can't copy a string to freshly allocated memory. */
 char * xstrdup(const char *s)
 {
        char *t;
@@ -71,8 +75,9 @@ char * xstrdup(const char *s)
 #endif
 
 #ifdef L_xstrndup
-// Die if we can't allocate n+1 bytes (space for the null terminator) and copy
-// the (possibly truncated to length n) string into it.
+/* Die if we can't allocate n+1 bytes (space for the null terminator) and copy
+ * the (possibly truncated to length n) string into it.
+ */
 char * xstrndup(const char *s, int n)
 {
        char *t;
@@ -87,8 +92,9 @@ char * xstrndup(const char *s, int n)
 #endif
 
 #ifdef L_xfopen
-// Die if we can't open a file and return a FILE * to it.
-// Notice we haven't got xfread(), This is for use with fscanf() and friends.
+/* Die if we can't open a file and return a FILE * to it.
+ * Notice we haven't got xfread(), This is for use with fscanf() and friends.
+ */
 FILE *xfopen(const char *path, const char *mode)
 {
        FILE *fp;
@@ -99,7 +105,7 @@ FILE *xfopen(const char *path, const char *mode)
 #endif
 
 #ifdef L_xopen
-// Die if we can't open an existing file and return an fd.
+/* Die if we can't open an existing file and return an fd. */
 int xopen(const char *pathname, int flags)
 {
        if (ENABLE_DEBUG && (flags && O_CREAT))
@@ -110,7 +116,7 @@ int xopen(const char *pathname, int flags)
 #endif
 
 #ifdef L_xopen3
-// Die if we can't open a new file and return an fd.
+/* Die if we can't open a new file and return an fd. */
 int xopen3(const char *pathname, int flags, int mode)
 {
        int ret;
@@ -124,7 +130,7 @@ int xopen3(const char *pathname, int flags, int mode)
 #endif
 
 #ifdef L_xread
-// Die with an error message if we can't read the entire buffer.
+/* Die with an error message if we can't read the entire buffer. */
 void xread(int fd, void *buf, size_t count)
 {
        while (count) {
@@ -139,7 +145,7 @@ void xread(int fd, void *buf, size_t count)
 #endif
 
 #ifdef L_xwrite
-// Die with an error message if we can't write the entire buffer.
+/* Die with an error message if we can't write the entire buffer. */
 void xwrite(int fd, void *buf, size_t count)
 {
        while (count) {
@@ -154,7 +160,7 @@ void xwrite(int fd, void *buf, size_t count)
 #endif
 
 #ifdef L_xlseek
-// Die with an error message if we can't lseek to the right spot.
+/* Die with an error message if we can't lseek to the right spot. */
 void xlseek(int fd, off_t offset, int whence)
 {
        if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek");
@@ -162,7 +168,7 @@ void xlseek(int fd, off_t offset, int whence)
 #endif
 
 #ifdef L_xread_char
-// Die with an error message if we can't read one character.
+/* Die with an error message if we can't read one character. */
 unsigned char xread_char(int fd)
 {
        char tmp;
@@ -174,7 +180,7 @@ unsigned char xread_char(int fd)
 #endif
 
 #ifdef L_xferror
-// Die with supplied error message if this FILE * has ferror set.
+/* Die with supplied error message if this FILE * has ferror set. */
 void xferror(FILE *fp, const char *fn)
 {
        if (ferror(fp)) {
@@ -184,7 +190,7 @@ void xferror(FILE *fp, const char *fn)
 #endif
 
 #ifdef L_xferror_stdout
-// Die with an error message if stdout has ferror set.
+/* Die with an error message if stdout has ferror set. */
 void xferror_stdout(void)
 {
        xferror(stdout, bb_msg_standard_output);
@@ -192,7 +198,7 @@ void xferror_stdout(void)
 #endif
 
 #ifdef L_xfflush_stdout
-// Die with an error message if we have trouble flushing stdout.
+/* Die with an error message if we have trouble flushing stdout. */
 void xfflush_stdout(void)
 {
        if (fflush(stdout)) {
@@ -202,24 +208,25 @@ void xfflush_stdout(void)
 #endif
 
 #ifdef L_spawn
-// This does a fork/exec in one call, using vfork().  Return PID of new child,
-// -1 for failure.  Runs argv[0], searching path if that has no / in it.
+/* This does a fork/exec in one call, using vfork().  Return PID of new child,
+ * -1 for failure.  Runs argv[0], searching path if that has no / in it.
+ */
 pid_t spawn(char **argv)
 {
        static int failed;
        pid_t pid;
        void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
 
-       // Be nice to nommu machines.
+       /* Be nice to nommu machines. */
        failed = 0;
        pid = vfork();
        if (pid < 0) return pid;
        if (!pid) {
                execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
 
-               // We're sharing a stack with blocked parent, let parent know we failed
-               // and then exit to unblock parent (but don't run atexit() stuff, which
-               // would screw up parent.)
+               /* We're sharing a stack with blocked parent, let parent know we failed
+                * and then exit to unblock parent (but don't run atexit() stuff, which
+                  would screw up parent.) */
 
                failed = -1;
                _exit(0);
@@ -229,7 +236,7 @@ pid_t spawn(char **argv)
 #endif
 
 #ifdef L_xspawn
-// Die with an error message if we can't spawn a child process.
+/* Die with an error message if we can't spawn a child process. */
 pid_t xspawn(char **argv)
 {
        pid_t pid = spawn(argv);
@@ -239,7 +246,7 @@ pid_t xspawn(char **argv)
 #endif
 
 #ifdef L_wait4
-// Wait for the specified child PID to exit, returning child's error return.
+/* Wait for the specified child PID to exit, returning child's error return. */
 int wait4pid(int pid)
 {
        int status;
@@ -252,9 +259,9 @@ int wait4pid(int pid)
 #endif
 
 #ifdef L_itoa
-// Convert unsigned integer to ascii, writing into supplied buffer.  A
-// truncated result is always null terminated (unless buflen is 0), and
-// contains the first few digits of the result ala strncpy.
+/* Convert unsigned integer to ascii, writing into supplied buffer.  A
+ * truncated result is always null terminated (unless buflen is 0), and
+ * contains the first few digits of the result ala strncpy. */
 void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
 {
        int i, out = 0;
@@ -272,7 +279,7 @@ void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
        }
 }
 
-// Convert signed integer to ascii, like utoa_to_buf()
+/* Convert signed integer to ascii, like utoa_to_buf() */
 void itoa_to_buf(int n, char *buf, unsigned buflen)
 {
        if (buflen && n<0) {
@@ -283,16 +290,16 @@ void itoa_to_buf(int n, char *buf, unsigned buflen)
        utoa_to_buf((unsigned)n, buf, buflen);
 }
 
-// The following two functions use a static buffer, so calling either one a
-// second time will overwrite previous results.
-//
-// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
-// Int should always be 32 bits on any remotely Unix-like system, see
-// http://www.unix.org/whitepapers/64bit.html for the reasons why.
-
+/* The following two functions use a static buffer, so calling either one a
+ * second time will overwrite previous results.
+ *
+ * The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
+ * Int should always be 32 bits on any remotely Unix-like system, see
+ * http://www.unix.org/whitepapers/64bit.html for the reasons why.
+*/
 static char local_buf[12];
 
-// Convert unsigned integer to ascii using a static buffer (returned).
+/* Convert unsigned integer to ascii using a static buffer (returned). */
 char *utoa(unsigned n)
 {
        utoa_to_buf(n, local_buf, sizeof(local_buf));
@@ -300,7 +307,7 @@ char *utoa(unsigned n)
        return local_buf;
 }
 
-// Convert signed integer to ascii using a static buffer (returned).
+/* Convert signed integer to ascii using a static buffer (returned). */
 char *itoa(int n)
 {
        itoa_to_buf(n, local_buf, sizeof(local_buf));
@@ -310,15 +317,15 @@ char *itoa(int n)
 #endif
 
 #ifdef L_setuid
-// Die with an error message if we can't set gid.  (Because resource limits may
-// limit this user to a given number of processes, and if that fills up the
-// setgid() will fail and we'll _still_be_root_, which is bad.)
+/* Die with an error message if we can't set gid.  (Because resource limits may
+ * limit this user to a given number of processes, and if that fills up the
+ * setgid() will fail and we'll _still_be_root_, which is bad.) */
 void xsetgid(gid_t gid)
 {
        if (setgid(gid)) bb_error_msg_and_die("setgid");
 }
 
-// Die with an error message if we cant' set uid.  (See xsetgid() for why.)
+/* Die with an error message if we cant' set uid.  (See xsetgid() for why.) */
 void xsetuid(uid_t uid)
 {
        if (setuid(uid)) bb_error_msg_and_die("setuid");
@@ -326,31 +333,31 @@ void xsetuid(uid_t uid)
 #endif
 
 #ifdef L_fdlength
-// Return how long the file at fd is, if there's any way to determine it.
+/* Return how long the file at fd is, if there's any way to determine it. */
 off_t fdlength(int fd)
 {
        off_t bottom = 0, top = 0, pos;
        long size;
 
-       // If the ioctl works for this, return it.
+       /* If the ioctl works for this, return it. */
 
        if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
 
-       // If not, do a binary search for the last location we can read.  (Some
-       // block devices don't do BLKGETSIZE right.)
+       /* If not, do a binary search for the last location we can read.  (Some
+        * block devices don't do BLKGETSIZE right.) */
 
        do {
                char temp;
 
                pos = bottom + (top - bottom) / 2;;
 
-               // If we can read from the current location, it's bigger.
+               /* If we can read from the current location, it's bigger. */
 
                if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) {
                        if (bottom == top) bottom = top = (top+1) * 2;
                        else bottom = pos;
 
-               // If we can't, it's smaller.
+               /* If we can't, it's smaller. */
 
                } else {
                        if (bottom == top) {
@@ -366,8 +373,8 @@ off_t fdlength(int fd)
 #endif
 
 #ifdef L_xasprintf
-// Die with an error message if we can't malloc() enough space and do an
-// sprintf() into that space.
+/* Die with an error message if we can't malloc() enough space and do an
+ * sprintf() into that space. */
 char *xasprintf(const char *format, ...)
 {
        va_list p;
@@ -396,8 +403,8 @@ char *xasprintf(const char *format, ...)
 #endif
 
 #ifdef L_xprint_and_close_file
-// Die with an error message if we can't copy an entire FILE * to stdout, then
-// close that file.
+/* Die with an error message if we can't copy an entire FILE * to stdout, then
+ * close that file. */
 void xprint_and_close_file(FILE *file)
 {
        // copyfd outputs error messages for us.
@@ -408,7 +415,7 @@ void xprint_and_close_file(FILE *file)
 #endif
 
 #ifdef L_xchdir
-// Die if we can't chdir to a new path.
+/* Die if we can't chdir to a new path. */
 void xchdir(const char *path)
 {
        if (chdir(path))
@@ -417,7 +424,7 @@ void xchdir(const char *path)
 #endif
 
 #ifdef L_warn_opendir
-// Print a warning message if opendir() fails, but don't die.
+/* Print a warning message if opendir() fails, but don't die. */
 DIR *warn_opendir(const char *path)
 {
        DIR *dp;
@@ -431,7 +438,7 @@ DIR *warn_opendir(const char *path)
 #endif
 
 #ifdef L_xopendir
-// Die with an error message if opendir() fails.
+/* Die with an error message if opendir() fails. */
 DIR *xopendir(const char *path)
 {
        DIR *dp;
@@ -444,7 +451,7 @@ DIR *xopendir(const char *path)
 
 #ifdef L_xdaemon
 #ifndef BB_NOMMU
-// Die with an error message if we can't daemonize.
+/* Die with an error message if we can't daemonize. */
 void xdaemon(int nochdir, int noclose)
 {
            if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon");
@@ -453,7 +460,7 @@ void xdaemon(int nochdir, int noclose)
 #endif
 
 #ifdef L_xsocket
-// Die with an error message if we can't open a new socket.
+/* Die with an error message if we can't open a new socket. */
 int xsocket(int domain, int type, int protocol)
 {
        int r = socket(domain, type, protocol);
@@ -465,7 +472,7 @@ int xsocket(int domain, int type, int protocol)
 #endif
 
 #ifdef L_xbind
-// Die with an error message if we can't bind a socket to an address.
+/* Die with an error message if we can't bind a socket to an address. */
 void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
 {
        if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
@@ -473,7 +480,7 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
 #endif
 
 #ifdef L_xlisten
-// Die with an error message if we can't listen for connections on a socket.
+/* Die with an error message if we can't listen for connections on a socket. */
 void xlisten(int s, int backlog)
 {
        if (listen(s, backlog)) bb_perror_msg_and_die("listen");
index 42360eb..c115878 100755 (executable)
@@ -49,6 +49,7 @@ find $srcdir/../ \
                -e '\<algorithic\>' \
                -e '\<deamon\>' \
                -e '\<derefernce\>' \
+               -e '\<acomadate\>' \
                | sed -e "s:^$srcdir/\.\./::g" > src.typos
 testing "Common typos" "cat src.typos" "" "" ""
 rm -f src.typos
index 2e164b8..735a895 100644 (file)
@@ -1,56 +1,22 @@
 /* vi: set sw=4 ts=4: */
 /*
- * ipcrm.c -- utility to allow removal of IPC objects and data structures.
+ * ipcrm.c - utility to allow removal of IPC objects and data structures.
  *
  * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
  * Adapted for busybox from util-linux-2.12a.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * --- Pre-busybox history from util-linux-2.12a ------------------------
- *
- * 1999-04-02 frank zago
- * - can now remove several id's in the same call
- *
- * 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- *
- * Original author - krishna balasubramanian 1993
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
+#include "busybox.h"
 
-#include <sys/types.h>
+/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
+/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/msg.h>
 #include <sys/sem.h>
 
-/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
-/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
-/* for getopt */
-#include <unistd.h>
-
-/* for tolower and isupper */
-#include <ctype.h>
-
-#include "busybox.h"
-
 #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
 /* union semun is defined by including <sys/sem.h> */
 #else
@@ -63,164 +29,149 @@ union semun {
 };
 #endif
 
+#ifndef CONFIG_IPCRM_DROP_LEGACY
+
 typedef enum type_id {
        SHM,
        SEM,
        MSG
 } type_id;
 
-static int
-remove_ids(type_id type, int argc, char **argv) {
+static int remove_ids(type_id type, int argc, char **argv)
+{
        int id;
-       int ret = 0;            /* for gcc */
+       int ret = 0;            /* silence gcc */
        char *end;
        int nb_errors = 0;
        union semun arg;
 
        arg.val = 0;
 
-       while(argc) {
+       while (argc) {
 
                id = strtoul(argv[0], &end, 10);
 
                if (*end != 0) {
-                       bb_printf ("invalid id: %s\n", argv[0]);
-                       nb_errors ++;
+                       bb_error_msg("invalid id: %s", argv[0]);
+                       nb_errors++;
                } else {
-                       switch(type) {
-                       case SEM:
-                               ret = semctl (id, 0, IPC_RMID, arg);
-                               break;
-
-                       case MSG:
-                               ret = msgctl (id, IPC_RMID, NULL);
-                               break;
-
-                       case SHM:
-                               ret = shmctl (id, IPC_RMID, NULL);
-                               break;
-                       }
+                       if (type == SEM)
+                               ret = semctl(id, 0, IPC_RMID, arg);
+                       else if (type == MSG)
+                               ret = msgctl(id, IPC_RMID, NULL);
+                       else if (type ==  SHM)
+                               ret = shmctl(id, IPC_RMID, NULL);
 
                        if (ret) {
-                               bb_printf ("cannot remove id %s (%s)\n",
-                                       argv[0], strerror(errno));
-                               nb_errors ++;
+                               bb_perror_msg("cannot remove id %s", argv[0]);
+                               nb_errors++;
                        }
                }
                argc--;
                argv++;
        }
 
-       return(nb_errors);
-}
-
-static int deprecated_main(int argc, char **argv)
-{
-       if (argc < 3) {
-               bb_show_usage();
-               bb_fflush_stdout_and_exit(1);
-       }
-
-       if (!strcmp(argv[1], "shm")) {
-               if (remove_ids(SHM, argc-2, &argv[2]))
-                       bb_fflush_stdout_and_exit(1);
-       }
-       else if (!strcmp(argv[1], "msg")) {
-               if (remove_ids(MSG, argc-2, &argv[2]))
-                       bb_fflush_stdout_and_exit(1);
-       }
-       else if (!strcmp(argv[1], "sem")) {
-               if (remove_ids(SEM, argc-2, &argv[2]))
-                       bb_fflush_stdout_and_exit(1);
-       }
-       else {
-               bb_printf ("unknown resource type: %s\n", argv[1]);
-               bb_show_usage();
-               bb_fflush_stdout_and_exit(1);
-       }
-
-       bb_printf ("resource(s) deleted\n");
-       return 0;
+       return (nb_errors);
 }
+#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
 
 
 int ipcrm_main(int argc, char **argv)
 {
-       int   c;
-       int   error = 0;
-       char *prog = argv[0];
+       int c;
+       int error = 0;
 
        /* if the command is executed without parameters, do nothing */
        if (argc == 1)
                return 0;
-
+#ifndef CONFIG_IPCRM_DROP_LEGACY
        /* check to see if the command is being invoked in the old way if so
-          then run the old code */
-       if (strcmp(argv[1], "shm") == 0 ||
-               strcmp(argv[1], "msg") == 0 ||
-               strcmp(argv[1], "sem") == 0)
-               return deprecated_main(argc, argv);
+          then run the old code. Valid commands are msg, shm, sem. */
+       {
+               type_id what = 0; /* silence gcc */
+               char w;
+
+               if ((((w=argv[1][0]) == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
+                               || (argv[1][0] == 's'
+                                       && ((w=argv[1][1]) == 'h' || w == 'e')
+                                       && argv[1][2] == 'm'))
+                       && argv[1][3] == '\0')  {
+
+                       if (argc < 3)
+                               bb_show_usage();
+
+                       if (w == 'h')
+                               what = SHM;
+                       else if (w == 'm')
+                               what = MSG;
+                       else if (w == 'e')
+                               what = SEM;
+
+                       if (remove_ids(what, argc-2, &argv[2]))
+                               bb_fflush_stdout_and_exit(1);
+                       bb_printf("resource(s) deleted\n");
+                       return 0;
+               }
+       }
+#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */
 
        /* process new syntax to conform with SYSV ipcrm */
        while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
                int result;
                int id = 0;
-               int iskey = isupper(c);
+               int iskey = (isupper)(c);
 
                /* needed to delete semaphores */
                union semun arg;
+
                arg.val = 0;
 
-               if ((c == '?') || (c == 'h'))
-               {
+               if ((c == '?') || (c == 'h')) {
                        bb_show_usage();
-                       return 0;
                }
 
                /* we don't need case information any more */
                c = tolower(c);
 
-               /* make sure the option is in range */
+               /* make sure the option is in range: allowed are q, m, s */
                if (c != 'q' && c != 'm' && c != 's') {
                        bb_show_usage();
-                       error++;
-                       return error;
                }
 
                if (iskey) {
                        /* keys are in hex or decimal */
                        key_t key = strtoul(optarg, NULL, 0);
+
                        if (key == IPC_PRIVATE) {
                                error++;
-                               bb_fprintf(stderr, "%s: illegal key (%s)\n",
-                                       prog, optarg);
+                               bb_error_msg("illegal key (%s)", optarg);
                                continue;
                        }
 
                        /* convert key to id */
                        id = ((c == 'q') ? msgget(key, 0) :
-                                 (c == 'm') ? shmget(key, 0, 0) :
-                                 semget(key, 0, 0));
+                                 (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
 
                        if (id < 0) {
                                char *errmsg;
+                               const char * const what = "key";
+
                                error++;
-                               switch(errno) {
+                               switch (errno) {
                                case EACCES:
-                                       errmsg = "permission denied for key";
+                                       errmsg = "permission denied for";
                                        break;
                                case EIDRM:
-                                       errmsg = "already removed key";
+                                       errmsg = "already removed";
                                        break;
                                case ENOENT:
-                                       errmsg = "invalid key";
+                                       errmsg = "invalid";
                                        break;
                                default:
-                                       errmsg = "unknown error in key";
+                                       errmsg = "unknown error in";
                                        break;
                                }
-                               bb_fprintf(stderr, "%s: %s (%s)\n",
-                                       prog, errmsg, optarg);
+                               bb_error_msg("%s %s (%s)",  errmsg, what, optarg);
                                continue;
                        }
                } else {
@@ -229,37 +180,30 @@ int ipcrm_main(int argc, char **argv)
                }
 
                result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
-                         (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
-                         semctl(id, 0, IPC_RMID, arg));
+                                 (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
+                                 semctl(id, 0, IPC_RMID, arg));
 
-               if (result < 0) {
+               if (result) {
                        char *errmsg;
+                       const char * const what = iskey ? "key" : "id";
+
                        error++;
-                       switch(errno) {
+                       switch (errno) {
                        case EACCES:
                        case EPERM:
-                               errmsg = iskey
-                                       ? "permission denied for key"
-                                       : "permission denied for id";
+                               errmsg = "permission denied for";
                                break;
                        case EINVAL:
-                               errmsg = iskey
-                                       ? "invalid key"
-                                       : "invalid id";
+                               errmsg = "invalid";
                                break;
                        case EIDRM:
-                               errmsg = iskey
-                                       ? "already removed key"
-                                       : "already removed id";
+                               errmsg = "already removed";
                                break;
                        default:
-                               errmsg = iskey
-                                       ? "unknown error in key"
-                                       : "unknown error in id";
+                               errmsg = "unknown error in";
                                break;
                        }
-                       bb_fprintf(stderr, "%s: %s (%s)\n",
-                               prog, errmsg, optarg);
+                       bb_error_msg("%s %s (%s)", errmsg, what, optarg);
                        continue;
                }
        }
index fbc75cb..c7c8376 100644 (file)
@@ -8,9 +8,7 @@
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
+#include "busybox.h"
 #include <errno.h>
 #include <time.h>
 #include <pwd.h>
 #include <sys/msg.h>
 #include <sys/shm.h>
 
-#include "busybox.h"
+
 
 /*-------------------------------------------------------------------*/
 /* SHM_DEST and SHM_LOCKED are defined in kernel headers,
    but inside #ifdef __KERNEL__ ... #endif */
 #ifndef SHM_DEST
 /* shm_mode upper byte flags */
-#define SHM_DEST        01000   /* segment will be destroyed on last detach */
-#define SHM_LOCKED      02000   /* segment will not be swapped */
+#define SHM_DEST        01000  /* segment will be destroyed on last detach */
+#define SHM_LOCKED      02000  /* segment will not be swapped */
 #endif
 
 /* For older kernels the same holds for the defines below */
 #define SHM_STAT        13
 #define SHM_INFO        14
 struct shm_info {
-        int   used_ids;
-        ulong shm_tot; /* total allocated shm */
-        ulong shm_rss; /* total resident shm */
-        ulong shm_swp; /* total swapped shm */
-        ulong swap_attempts;
-        ulong swap_successes;
+       int used_ids;
+       ulong shm_tot;          /* total allocated shm */
+       ulong shm_rss;          /* total resident shm */
+       ulong shm_swp;          /* total swapped shm */
+       ulong swap_attempts;
+       ulong swap_successes;
 };
 #endif
 
@@ -98,12 +96,14 @@ union semun {
 #define TIME 4
 #define PID 5
 
+static char format;
 
-static void print_perms (int id, struct ipc_perm *ipcp) {
+static void print_perms(int id, struct ipc_perm *ipcp)
+{
        struct passwd *pw;
        struct group *gr;
 
-       bb_printf ("%-10d %-10o", id, ipcp->mode & 0777);
+       bb_printf("%-10d %-10o", id, ipcp->mode & 0777);
 
        if ((pw = getpwuid(ipcp->cuid)))
                bb_printf(" %-10s", pw->pw_name);
@@ -125,7 +125,7 @@ static void print_perms (int id, struct ipc_perm *ipcp) {
 }
 
 
-static void do_shm (char format)
+static void do_shm(void)
 {
        int maxid, shmid, id;
        struct shmid_ds shmseg;
@@ -134,127 +134,125 @@ static void do_shm (char format)
        struct ipc_perm *ipcp = &shmseg.shm_perm;
        struct passwd *pw;
 
-       maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
+       maxid = shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
        if (maxid < 0) {
-               bb_printf ("kernel not configured for shared memory\n");
+               bb_printf("kernel not configured for shared memory\n");
                return;
        }
 
        switch (format) {
        case LIMITS:
-               bb_printf ("------ Shared Memory Limits --------\n");
-               if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 )
+               bb_printf("------ Shared Memory Limits --------\n");
+               if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0)
                        return;
                /* glibc 2.1.3 and all earlier libc's have ints as fields
                   of struct shminfo; glibc 2.1.91 has unsigned long; ach */
-               bb_printf ("max number of segments = %lu\n"
-                       "max seg size (kbytes) = %lu\n"
-                       "max total shared memory (pages) = %lu\n"
-                       "min seg size (bytes) = %lu\n",
-                       (unsigned long) shminfo.shmmni,
-                       (unsigned long) (shminfo.shmmax >> 10),
-                       (unsigned long) shminfo.shmall,
-                       (unsigned long) shminfo.shmmin);
+               bb_printf("max number of segments = %lu\n"
+                                 "max seg size (kbytes) = %lu\n"
+                                 "max total shared memory (pages) = %lu\n"
+                                 "min seg size (bytes) = %lu\n",
+                                 (unsigned long) shminfo.shmmni,
+                                 (unsigned long) (shminfo.shmmax >> 10),
+                                 (unsigned long) shminfo.shmall,
+                                 (unsigned long) shminfo.shmmin);
                return;
 
        case STATUS:
-               bb_printf ("------ Shared Memory Status --------\n"
-                       "segments allocated %d\n"
-                       "pages allocated %ld\n"
-                       "pages resident  %ld\n"
-                       "pages swapped   %ld\n"
-                       "Swap performance: %ld attempts\t %ld successes\n",
-                       shm_info.used_ids,
-                       shm_info.shm_tot,
-                       shm_info.shm_rss,
-                       shm_info.shm_swp,
-                       shm_info.swap_attempts, shm_info.swap_successes);
+               bb_printf("------ Shared Memory Status --------\n"
+                                 "segments allocated %d\n"
+                                 "pages allocated %ld\n"
+                                 "pages resident  %ld\n"
+                                 "pages swapped   %ld\n"
+                                 "Swap performance: %ld attempts\t %ld successes\n",
+                                 shm_info.used_ids,
+                                 shm_info.shm_tot,
+                                 shm_info.shm_rss,
+                                 shm_info.shm_swp,
+                                 shm_info.swap_attempts, shm_info.swap_successes);
                return;
 
        case CREATOR:
-               bb_printf ("------ Shared Memory Segment Creators/Owners --------\n"
-                       "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-                       "shmid","perms","cuid","cgid","uid","gid");
+               bb_printf("------ Shared Memory Segment Creators/Owners --------\n"
+                                 "%-10s %-10s %-10s %-10s %-10s %-10s\n",
+                                 "shmid", "perms", "cuid", "cgid", "uid", "gid");
                break;
 
        case TIME:
-               bb_printf ("------ Shared Memory Attach/Detach/Change Times --------\n"
-                       "%-10s %-10s %-20s %-20s %-20s\n",
-                       "shmid","owner","attached","detached","changed");
+               bb_printf("------ Shared Memory Attach/Detach/Change Times --------\n"
+                                 "%-10s %-10s %-20s %-20s %-20s\n",
+                                 "shmid", "owner", "attached", "detached", "changed");
                break;
 
        case PID:
-               bb_printf ("------ Shared Memory Creator/Last-op --------\n"
-                       "%-10s %-10s %-10s %-10s\n",
-                       "shmid","owner","cpid","lpid");
+               bb_printf("------ Shared Memory Creator/Last-op --------\n"
+                                 "%-10s %-10s %-10s %-10s\n",
+                                 "shmid", "owner", "cpid", "lpid");
                break;
 
        default:
-               bb_printf ("------ Shared Memory Segments --------\n"
-                       "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
-                       "key","shmid","owner","perms","bytes","nattch","status");
+               bb_printf("------ Shared Memory Segments --------\n"
+                                 "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
+                                 "key", "shmid", "owner", "perms", "bytes", "nattch",
+                                 "status");
                break;
        }
 
        for (id = 0; id <= maxid; id++) {
-               shmid = shmctl (id, SHM_STAT, &shmseg);
+               shmid = shmctl(id, SHM_STAT, &shmseg);
                if (shmid < 0)
                        continue;
-               if (format == CREATOR)  {
-                       print_perms (shmid, ipcp);
+               if (format == CREATOR) {
+                       print_perms(shmid, ipcp);
                        continue;
                }
                pw = getpwuid(ipcp->uid);
                switch (format) {
                case TIME:
                        if (pw)
-                               bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
+                               bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
                        else
-                               bb_printf ("%-10d %-10d", shmid, ipcp->uid);
+                               bb_printf("%-10d %-10d", shmid, ipcp->uid);
                        /* ctime uses static buffer: use separate calls */
-                       bb_printf("  %-20.16s", shmseg.shm_atime
-                                  ? ctime(&shmseg.shm_atime) + 4 : "Not set");
+                       bb_printf(" %-20.16s", shmseg.shm_atime
+                                         ? ctime(&shmseg.shm_atime) + 4 : "Not set");
                        bb_printf(" %-20.16s", shmseg.shm_dtime
-                                  ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
+                                         ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
                        bb_printf(" %-20.16s\n", shmseg.shm_ctime
-                                  ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
+                                         ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
                        break;
                case PID:
                        if (pw)
-                               bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
+                               bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
                        else
-                               bb_printf ("%-10d %-10d", shmid, ipcp->uid);
-                       bb_printf (" %-10d %-10d\n",
-                               shmseg.shm_cpid, shmseg.shm_lpid);
+                               bb_printf("%-10d %-10d", shmid, ipcp->uid);
+                       bb_printf(" %-10d %-10d\n", shmseg.shm_cpid, shmseg.shm_lpid);
                        break;
 
                default:
-                               bb_printf("0x%08x ",ipcp->KEY );
+                       bb_printf("0x%08x ", ipcp->KEY);
                        if (pw)
-                               bb_printf ("%-10d %-10.10s", shmid, pw->pw_name);
+                               bb_printf("%-10d %-10.10s", shmid, pw->pw_name);
                        else
-                               bb_printf ("%-10d %-10d", shmid, ipcp->uid);
-                       bb_printf ("%-10o %-10lu %-10ld %-6s %-6s\n",
-                               ipcp->mode & 0777,
-                               /*
-                                * earlier: int, Austin has size_t
-                                */
-                               (unsigned long) shmseg.shm_segsz,
-                               /*
-                                * glibc-2.1.3 and earlier has unsigned short;
-                                * Austin has shmatt_t
-                                */
-                               (long) shmseg.shm_nattch,
-                               ipcp->mode & SHM_DEST ? "dest" : " ",
-                               ipcp->mode & SHM_LOCKED ? "locked" : " ");
+                               bb_printf("%-10d %-10d", shmid, ipcp->uid);
+                       bb_printf("%-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
+                                         /*
+                                          * earlier: int, Austin has size_t
+                                          */
+                                         (unsigned long) shmseg.shm_segsz,
+                                         /*
+                                          * glibc-2.1.3 and earlier has unsigned short;
+                                          * Austin has shmatt_t
+                                          */
+                                         (long) shmseg.shm_nattch,
+                                         ipcp->mode & SHM_DEST ? "dest" : " ",
+                                         ipcp->mode & SHM_LOCKED ? "locked" : " ");
                        break;
                }
        }
-       return;
 }
 
 
-static void do_sem (char format)
+static void do_sem(void)
 {
        int maxid, semid, id;
        struct semid_ds semary;
@@ -263,107 +261,104 @@ static void do_sem (char format)
        struct passwd *pw;
        union semun arg;
 
-       arg.array = (ushort *)  (void *) &seminfo;
-       maxid = semctl (0, 0, SEM_INFO, arg);
+       arg.array = (ushort *) (void *) &seminfo;
+       maxid = semctl(0, 0, SEM_INFO, arg);
        if (maxid < 0) {
-               bb_printf ("kernel not configured for semaphores\n");
+               bb_printf("kernel not configured for semaphores\n");
                return;
        }
 
        switch (format) {
        case LIMITS:
-               bb_printf ("------ Semaphore Limits --------\n");
-               arg.array = (ushort *) (void *) &seminfo; /* damn union */
-               if ((semctl (0, 0, IPC_INFO, arg)) < 0 )
+               bb_printf("------ Semaphore Limits --------\n");
+               arg.array = (ushort *) (void *) &seminfo;       /* damn union */
+               if ((semctl(0, 0, IPC_INFO, arg)) < 0)
                        return;
-               bb_printf ("max number of arrays = %d\n"
-                       "max semaphores per array = %d\n"
-                       "max semaphores system wide = %d\n"
-                       "max ops per semop call = %d\n"
-                       "semaphore max value = %d\n",
-                       seminfo.semmni,
-                       seminfo.semmsl,
-                       seminfo.semmns,
-                       seminfo.semopm,
-                       seminfo.semvmx);
+               bb_printf("max number of arrays = %d\n"
+                                 "max semaphores per array = %d\n"
+                                 "max semaphores system wide = %d\n"
+                                 "max ops per semop call = %d\n"
+                                 "semaphore max value = %d\n",
+                                 seminfo.semmni,
+                                 seminfo.semmsl,
+                                 seminfo.semmns, seminfo.semopm, seminfo.semvmx);
                return;
 
        case STATUS:
-               bb_printf ("------ Semaphore Status --------\n"
-                       "used arrays = %d\n"
-                       "allocated semaphores = %d\n",
-                       seminfo.semusz,
-                       seminfo.semaem);
+               bb_printf("------ Semaphore Status --------\n"
+                                 "used arrays = %d\n"
+                                 "allocated semaphores = %d\n",
+                                 seminfo.semusz, seminfo.semaem);
                return;
 
        case CREATOR:
-               bb_printf ("------ Semaphore Arrays Creators/Owners --------\n"
-                       "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-                       "semid","perms","cuid","cgid","uid","gid");
+               bb_printf("------ Semaphore Arrays Creators/Owners --------\n"
+                                 "%-10s %-10s %-10s %-10s %-10s %-10s\n",
+                                 "semid", "perms", "cuid", "cgid", "uid", "gid");
                break;
 
        case TIME:
-               bb_printf ("------ Shared Memory Operation/Change Times --------\n"
-                       "%-8s %-10s %-26.24s %-26.24s\n",
-                       "shmid","owner","last-op","last-changed");
+               bb_printf("------ Shared Memory Operation/Change Times --------\n"
+                                 "%-8s %-10s %-26.24s %-26.24s\n",
+                                 "shmid", "owner", "last-op", "last-changed");
                break;
 
        case PID:
                break;
 
        default:
-               bb_printf ("------ Semaphore Arrays --------\n"
-                       "%-10s %-10s %-10s %-10s %-10s\n",
-                       "key","semid","owner","perms","nsems");
+               bb_printf("------ Semaphore Arrays --------\n"
+                                 "%-10s %-10s %-10s %-10s %-10s\n",
+                                 "key", "semid", "owner", "perms", "nsems");
                break;
        }
 
        for (id = 0; id <= maxid; id++) {
                arg.buf = (struct semid_ds *) &semary;
-               semid = semctl (id, 0, SEM_STAT, arg);
+               semid = semctl(id, 0, SEM_STAT, arg);
                if (semid < 0)
                        continue;
-               if (format == CREATOR)  {
-                       print_perms (semid, ipcp);
+               if (format == CREATOR) {
+                       print_perms(semid, ipcp);
                        continue;
                }
                pw = getpwuid(ipcp->uid);
                switch (format) {
                case TIME:
                        if (pw)
-                               bb_printf ("%-8d %-10.10s", semid, pw->pw_name);
+                               bb_printf("%-8d %-10.10s", semid, pw->pw_name);
                        else
-                               bb_printf ("%-8d %-10d", semid, ipcp->uid);
-                       bb_printf ("  %-26.24s", semary.sem_otime
-                               ? ctime(&semary.sem_otime) : "Not set");
-                       bb_printf (" %-26.24s\n", semary.sem_ctime
-                               ? ctime(&semary.sem_ctime) : "Not set");
+                               bb_printf("%-8d %-10d", semid, ipcp->uid);
+                       /* ctime uses static buffer: use separate calls */
+                       bb_printf("  %-26.24s", semary.sem_otime
+                                         ? ctime(&semary.sem_otime) : "Not set");
+                       bb_printf(" %-26.24s\n", semary.sem_ctime
+                                         ? ctime(&semary.sem_ctime) : "Not set");
                        break;
                case PID:
                        break;
 
                default:
-                               bb_printf("0x%08x ", ipcp->KEY);
+                       bb_printf("0x%08x ", ipcp->KEY);
                        if (pw)
-                               bb_printf ("%-10d %-10.9s", semid, pw->pw_name);
+                               bb_printf("%-10d %-10.9s", semid, pw->pw_name);
                        else
-                               bb_printf ("%-10d %-9d", semid, ipcp->uid);
-                                       bb_printf ("%-10o %-10ld\n",
-                               ipcp->mode & 0777,
-                               /*
-                                * glibc-2.1.3 and earlier has unsigned short;
-                                * glibc-2.1.91 has variation between
-                                * unsigned short and unsigned long
-                                * Austin prescribes unsigned short.
-                                */
-                               (long) semary.sem_nsems);
+                               bb_printf("%-10d %-9d", semid, ipcp->uid);
+                       bb_printf("%-10o %-10ld\n", ipcp->mode & 0777,
+                                         /*
+                                          * glibc-2.1.3 and earlier has unsigned short;
+                                          * glibc-2.1.91 has variation between
+                                          * unsigned short and unsigned long
+                                          * Austin prescribes unsigned short.
+                                          */
+                                         (long) semary.sem_nsems);
                        break;
                }
        }
 }
 
 
-static void do_msg (char format)
+static void do_msg(void)
 {
        int maxid, msqid, id;
        struct msqid_ds msgque;
@@ -371,178 +366,165 @@ static void do_msg (char format)
        struct ipc_perm *ipcp = &msgque.msg_perm;
        struct passwd *pw;
 
-       maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
+       maxid = msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
        if (maxid < 0) {
-               bb_printf ("kernel not configured for message queues\n");
+               bb_printf("kernel not configured for message queues\n");
                return;
        }
 
        switch (format) {
        case LIMITS:
-               if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 )
+               if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0)
                        return;
-               bb_printf ("------ Messages: Limits --------\n"
-                       "max queues system wide = %d\n"
-                       "max size of message (bytes) = %d\n"
-                       "default max size of queue (bytes) = %d\n",
-                       msginfo.msgmni,
-                       msginfo.msgmax,
-                       msginfo.msgmnb);
+               bb_printf("------ Messages: Limits --------\n"
+                                 "max queues system wide = %d\n"
+                                 "max size of message (bytes) = %d\n"
+                                 "default max size of queue (bytes) = %d\n",
+                                 msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
                return;
 
        case STATUS:
-               bb_printf ("------ Messages: Status --------\n"
-                       "allocated queues = %d\n"
-                       "used headers = %d\n"
-                       "used space = %d bytes\n",
-                       msginfo.msgpool,
-                       msginfo.msgmap,
-                       msginfo.msgtql);
+               bb_printf("------ Messages: Status --------\n"
+                                 "allocated queues = %d\n"
+                                 "used headers = %d\n"
+                                 "used space = %d bytes\n",
+                                 msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
                return;
 
        case CREATOR:
-               bb_printf ("------ Message Queues: Creators/Owners --------\n"
-                       "%-10s %-10s %-10s %-10s %-10s %-10s\n",
-                       "msqid","perms","cuid","cgid","uid","gid");
+               bb_printf("------ Message Queues: Creators/Owners --------\n"
+                                 "%-10s %-10s %-10s %-10s %-10s %-10s\n",
+                                 "msqid", "perms", "cuid", "cgid", "uid", "gid");
                break;
 
        case TIME:
-               bb_printf ("------ Message Queues Send/Recv/Change Times --------\n"
-                       "%-8s %-10s %-20s %-20s %-20s\n",
-                       "msqid","owner","send","recv","change");
+               bb_printf("------ Message Queues Send/Recv/Change Times --------\n"
+                                 "%-8s %-10s %-20s %-20s %-20s\n",
+                                 "msqid", "owner", "send", "recv", "change");
                break;
 
        case PID:
-               bb_printf ("------ Message Queues PIDs --------\n"
-                       "%-10s %-10s %-10s %-10s\n",
-                       "msqid","owner","lspid","lrpid");
+               bb_printf("------ Message Queues PIDs --------\n"
+                                 "%-10s %-10s %-10s %-10s\n",
+                                 "msqid", "owner", "lspid", "lrpid");
                break;
 
        default:
-               bb_printf ("------ Message Queues --------\n"
-                       "%-10s %-10s %-10s %-10s %-12s %-12s\n",
-                       "key","msqid","owner","perms","used-bytes","messages");
+               bb_printf("------ Message Queues --------\n"
+                                 "%-10s %-10s %-10s %-10s %-12s %-12s\n",
+                                 "key", "msqid", "owner", "perms", "used-bytes", "messages");
                break;
        }
 
        for (id = 0; id <= maxid; id++) {
-               msqid = msgctl (id, MSG_STAT, &msgque);
+               msqid = msgctl(id, MSG_STAT, &msgque);
                if (msqid < 0)
                        continue;
-               if (format == CREATOR)  {
-                       print_perms (msqid, ipcp);
+               if (format == CREATOR) {
+                       print_perms(msqid, ipcp);
                        continue;
                }
                pw = getpwuid(ipcp->uid);
                switch (format) {
                case TIME:
                        if (pw)
-                               bb_printf ("%-8d %-10.10s", msqid, pw->pw_name);
+                               bb_printf("%-8d %-10.10s", msqid, pw->pw_name);
                        else
-                               bb_printf ("%-8d %-10d", msqid, ipcp->uid);
-                       bb_printf (" %-20.16s", msgque.msg_stime
-                               ? ctime(&msgque.msg_stime) + 4 : "Not set");
-                       bb_printf (" %-20.16s", msgque.msg_rtime
-                               ? ctime(&msgque.msg_rtime) + 4 : "Not set");
-                       bb_printf (" %-20.16s\n", msgque.msg_ctime
-                               ? ctime(&msgque.msg_ctime) + 4 : "Not set");
+                               bb_printf("%-8d %-10d", msqid, ipcp->uid);
+                       bb_printf(" %-20.16s", msgque.msg_stime
+                                         ? ctime(&msgque.msg_stime) + 4 : "Not set");
+                       bb_printf(" %-20.16s", msgque.msg_rtime
+                                         ? ctime(&msgque.msg_rtime) + 4 : "Not set");
+                       bb_printf(" %-20.16s\n", msgque.msg_ctime
+                                         ? ctime(&msgque.msg_ctime) + 4 : "Not set");
                        break;
                case PID:
                        if (pw)
-                               bb_printf ("%-8d %-10.10s", msqid, pw->pw_name);
+                               bb_printf("%-8d %-10.10s", msqid, pw->pw_name);
                        else
-                               bb_printf ("%-8d %-10d", msqid, ipcp->uid);
-                       bb_printf ("  %5d     %5d\n",
-                               msgque.msg_lspid, msgque.msg_lrpid);
+                               bb_printf("%-8d %-10d", msqid, ipcp->uid);
+                       bb_printf("  %5d     %5d\n", msgque.msg_lspid, msgque.msg_lrpid);
                        break;
 
                default:
-                               bb_printf( "0x%08x ",ipcp->KEY );
+                       bb_printf("0x%08x ", ipcp->KEY);
                        if (pw)
-                               bb_printf ("%-10d %-10.10s", msqid, pw->pw_name);
+                               bb_printf("%-10d %-10.10s", msqid, pw->pw_name);
                        else
-                               bb_printf ("%-10d %-10d", msqid, ipcp->uid);
-                                       bb_printf (" %-10o %-12ld %-12ld\n",
-                               ipcp->mode & 0777,
-                               /*
-                                * glibc-2.1.3 and earlier has unsigned short;
-                                * glibc-2.1.91 has variation between
-                                * unsigned short, unsigned long
-                                * Austin has msgqnum_t
-                                */
-                               (long) msgque.msg_cbytes,
-                               (long) msgque.msg_qnum);
+                               bb_printf("%-10d %-10d", msqid, ipcp->uid);
+                       bb_printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
+                                         /*
+                                          * glibc-2.1.3 and earlier has unsigned short;
+                                          * glibc-2.1.91 has variation between
+                                          * unsigned short, unsigned long
+                                          * Austin has msgqnum_t
+                                          */
+                                         (long) msgque.msg_cbytes, (long) msgque.msg_qnum);
                        break;
                }
        }
-       return;
 }
 
 
-static void print_shm (int shmid)
+static void print_shm(int shmid)
 {
        struct shmid_ds shmds;
        struct ipc_perm *ipcp = &shmds.shm_perm;
 
-       if (shmctl (shmid, IPC_STAT, &shmds) == -1) {
-               perror ("shmctl ");
+       if (shmctl(shmid, IPC_STAT, &shmds) == -1) {
+               bb_perror_msg("shmctl");
                return;
        }
 
-       bb_printf ("\nShared memory Segment shmid=%d\n"
-               "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
-               "mode=%#o\taccess_perms=%#o\n"
-               "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n"
-               "att_time=%-26.24s\n"
-               "det_time=%-26.24s\n"
-               "change_time=%-26.24s\n"
-               "\n",
-               shmid,
-               ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
-               ipcp->mode, ipcp->mode & 0777,
-               (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
-               (long) shmds.shm_nattch,
-               shmds.shm_atime ? ctime (&shmds.shm_atime) : "Not set",
-               shmds.shm_dtime ? ctime (&shmds.shm_dtime) : "Not set",
-               ctime (&shmds.shm_ctime));
-       return;
+       bb_printf("\nShared memory Segment shmid=%d\n"
+                         "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
+                         "mode=%#o\taccess_perms=%#o\n"
+                         "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
+                         shmid,
+                         ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+                         ipcp->mode, ipcp->mode & 0777,
+                         (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
+                         (long) shmds.shm_nattch);
+       bb_printf("att_time=%-26.24s\n",
+                         shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
+       bb_printf("det_time=%-26.24s\n",
+                         shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
+       bb_printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
 }
 
 
-static void print_msg (int msqid)
+static void print_msg(int msqid)
 {
        struct msqid_ds buf;
        struct ipc_perm *ipcp = &buf.msg_perm;
 
-       if (msgctl (msqid, IPC_STAT, &buf) == -1) {
-               perror ("msgctl ");
+       if (msgctl(msqid, IPC_STAT, &buf) == -1) {
+               bb_perror_msg("msgctl");
                return;
        }
 
-       bb_printf ("\nMessage Queue msqid=%d\n"
-               "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
-               "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n"
-               "send_time=%-26.24s\n"
-               "rcv_time=%-26.24s\n"
-               "change_time=%-26.24s\n"
-               "\n",
-               msqid,
-               ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
-               /*
-                * glibc-2.1.3 and earlier has unsigned short;
-                * glibc-2.1.91 has variation between
-                * unsigned short, unsigned long
-                * Austin has msgqnum_t (for msg_qbytes)
-                */
-               (long) buf.msg_cbytes, (long) buf.msg_qbytes,
-               (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid,
-               buf.msg_stime ? ctime (&buf.msg_stime) : "Not set",
-               buf.msg_rtime ? ctime (&buf.msg_rtime) : "Not set",
-               buf.msg_ctime ? ctime (&buf.msg_ctime) : "Not set");
-       return;
+       bb_printf("\nMessage Queue msqid=%d\n"
+                         "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
+                         "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
+                         msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
+                         /*
+                          * glibc-2.1.3 and earlier has unsigned short;
+                          * glibc-2.1.91 has variation between
+                          * unsigned short, unsigned long
+                          * Austin has msgqnum_t (for msg_qbytes)
+                          */
+                         (long) buf.msg_cbytes, (long) buf.msg_qbytes,
+                         (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
+
+       bb_printf("send_time=%-26.24s\n",
+                         buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
+       bb_printf("rcv_time=%-26.24s\n",
+                         buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
+       bb_printf("change_time=%-26.24s\n\n",
+                         buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
 }
 
-static void print_sem (int semid)
+static void print_sem(int semid)
 {
        struct semid_ds semds;
        struct ipc_perm *ipcp = &semds.sem_perm;
@@ -550,66 +532,69 @@ static void print_sem (int semid)
        unsigned int i;
 
        arg.buf = &semds;
-       if (semctl (semid, 0, IPC_STAT, arg) < 0) {
-               perror ("semctl ");
+       if (semctl(semid, 0, IPC_STAT, arg)) {
+               bb_perror_msg("semctl");
                return;
        }
 
-       bb_printf ("\nSemaphore Array semid=%d\n"
-               "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
-               "mode=%#o, access_perms=%#o\n"
-               "nsems = %ld\n"
-               "otime = %-26.24s\n"
-               "ctime = %-26.24s\n"
-               "%-10s %-10s %-10s %-10s %-10s\n",
-               semid,
-               ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
-               ipcp->mode, ipcp->mode & 0777,
-               (long) semds.sem_nsems,
-               semds.sem_otime ? ctime (&semds.sem_otime) : "Not set",
-               ctime (&semds.sem_ctime),
-               "semnum","value","ncount","zcount","pid");
+       bb_printf("\nSemaphore Array semid=%d\n"
+                         "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
+                         "mode=%#o, access_perms=%#o\n"
+                         "nsems = %ld\n"
+                         "otime = %-26.24s\n",
+                         semid,
+                         ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+                         ipcp->mode, ipcp->mode & 0777,
+                         (long) semds.sem_nsems,
+                         semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
+       bb_printf("ctime = %-26.24s\n"
+                         "%-10s %-10s %-10s %-10s %-10s\n",
+                         ctime(&semds.sem_ctime),
+                         "semnum", "value", "ncount", "zcount", "pid");
 
        arg.val = 0;
-       for (i=0; i < semds.sem_nsems; i++) {
+       for (i = 0; i < semds.sem_nsems; i++) {
                int val, ncnt, zcnt, pid;
-               val = semctl (semid, i, GETVAL, arg);
-               ncnt = semctl (semid, i, GETNCNT, arg);
-               zcnt = semctl (semid, i, GETZCNT, arg);
-               pid = semctl (semid, i, GETPID, arg);
+
+               val = semctl(semid, i, GETVAL, arg);
+               ncnt = semctl(semid, i, GETNCNT, arg);
+               zcnt = semctl(semid, i, GETZCNT, arg);
+               pid = semctl(semid, i, GETPID, arg);
                if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
-                       perror ("semctl ");
-                       bb_fflush_stdout_and_exit (1);
+                       bb_perror_msg_and_die("semctl");
                }
-               bb_printf ("%-10d %-10d %-10d %-10d %-10d\n",
-                       i, val, ncnt, zcnt, pid);
+               bb_printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid);
        }
-       bb_printf ("\n");
-       return;
+       bb_printf("\n");
 }
 
-int ipcs_main (int argc, char **argv) {
-       int opt, msg = 0, sem = 0, shm = 0, id=0, print=0;
-       char format = 0;
-       char options[] = "atclupsmqi:ih?";
-
-       while ((opt = getopt (argc, argv, options)) != -1) {
+int ipcs_main(int argc, char **argv)
+{
+       int opt, id = 0;
+       unsigned flags = 0;
+#define flag_print     (1<<0)
+#define flag_msg       (1<<1)
+#define flag_sem       (1<<2)
+#define flag_shm       (1<<3)
+       const char *const options = "atclupsmqi:ih?";
+
+       while ((opt = getopt(argc, argv, options)) != -1) {
                switch (opt) {
                case 'i':
-                       id = atoi (optarg);
-                       print = 1;
+                       id = atoi(optarg);
+                       flags |= flag_print;
                        break;
                case 'a':
-                       msg = shm = sem = 1;
+                       flags |= flag_msg | flag_sem | flag_shm;
                        break;
                case 'q':
-                       msg = 1;
+                       flags |= flag_msg;
                        break;
                case 's':
-                       sem = 1;
+                       flags |= flag_sem;
                        break;
                case 'm':
-                       shm = 1;
+                       flags |= flag_shm;
                        break;
                case 't':
                        format = TIME;
@@ -629,43 +614,40 @@ int ipcs_main (int argc, char **argv) {
                case 'h':
                case '?':
                        bb_show_usage();
-                       bb_fflush_stdout_and_exit (0);
                }
        }
 
-       if  (print) {
-               if (shm) {
-                       print_shm (id);
-                       bb_fflush_stdout_and_exit (0);
+       if (flags & flag_print) {
+               if (flags & flag_shm) {
+                       print_shm(id);
+                       bb_fflush_stdout_and_exit(0);
                }
-               if (sem) {
-                       print_sem (id);
-                       bb_fflush_stdout_and_exit (0);
+               if (flags & flag_sem) {
+                       print_sem(id);
+                       bb_fflush_stdout_and_exit(0);
                }
-               if (msg) {
-                       print_msg (id);
-                       bb_fflush_stdout_and_exit (0);
+               if (flags & flag_msg) {
+                       print_msg(id);
+                       bb_fflush_stdout_and_exit(0);
                }
                bb_show_usage();
-               bb_fflush_stdout_and_exit (0);
        }
 
-       if ( !shm && !msg && !sem)
-               msg = sem = shm = 1;
-       bb_printf ("\n");
+       if (!(flags & (flag_shm | flag_msg | flag_sem)))
+               flags |= flag_msg | flag_shm | flag_sem;
+       bb_printf("\n");
 
-       if (shm) {
-               do_shm (format);
-               bb_printf ("\n");
+       if (flags & flag_shm) {
+               do_shm();
+               bb_printf("\n");
        }
-       if (sem) {
-               do_sem (format);
-               bb_printf ("\n");
+       if (flags & flag_sem) {
+               do_sem();
+               bb_printf("\n");
        }
-       if (msg) {
-               do_msg (format);
-               bb_printf ("\n");
+       if (flags & flag_msg) {
+               do_msg();
+               bb_printf("\n");
        }
-       return 0;
+       return EXIT_SUCCESS;
 }
-