Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/coreutils


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
Location:
branches/3.2/mindi-busybox/coreutils
Files:
74 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/coreutils/Config.src

    r2725 r3232  
    270270      This enables the head options (-c, -q, and -v).
    271271
    272 config HOSTID
    273     bool "hostid"
    274     default y
    275     help
    276       hostid prints the numeric identifier (in hexadecimal) for
    277       the current host.
    278 
    279 config ID
    280     bool "id"
    281     default y
    282     help
    283       id displays the current user and group ID names.
    284 
    285272config INSTALL
    286273    bool "install"
     
    296283      Support long options for the install applet.
    297284
    298 config LENGTH
    299     bool "length"
    300     default y
    301     help
    302       length is used to print out the length of a specified string.
     285####config LENGTH
     286####    bool "length"
     287####    default y
     288####    help
     289####      length is used to print out the length of a specified string.
    303290
    304291config LN
     
    527514    help
    528515      Compute and check SHA512 message digest
     516
     517config SHA3SUM
     518    bool "sha3sum"
     519    default y
     520    help
     521      Compute and check SHA3 (512-bit) message digest
    529522
    530523config SLEEP
     
    592585    bool "stat"
    593586    default y
    594     depends on PLATFORM_LINUX # statfs()
     587    select PLATFORM_LINUX # statfs()
    595588    help
    596589      display file or filesystem status.
     
    662655      Enable this option for a faster tee, at expense of size.
    663656
    664 config TOUCH
    665     bool "touch"
    666     default y
    667     help
    668       touch is used to create or change the access and/or
    669       modification timestamp of specified files.
    670 
    671657config TRUE
    672658    bool "true"
     
    738724    help
    739725      Use "unsigned long long" in wc for counter variables.
    740 
    741 config WHO
    742     bool "who"
    743     default y
    744     depends on FEATURE_UTMP
    745     help
    746       who is used to show who is logged on.
    747726
    748727config WHOAMI
     
    794773      Allow df, du, and ls to have human readable output.
    795774
    796 comment "Common options for md5sum, sha1sum, sha256sum, sha512sum"
    797     depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM
     775comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
     776    depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
    798777
    799778config FEATURE_MD5_SHA1_SUM_CHECK
    800779    bool "Enable -c, -s and -w options"
    801780    default y
    802     depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM
     781    depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
    803782    help
    804783      Enabling the -c options allows files to be checked
  • branches/3.2/mindi-busybox/coreutils/Kbuild.src

    r2725 r3232  
    3737lib-$(CONFIG_FSYNC)     += fsync.o
    3838lib-$(CONFIG_HEAD)      += head.o
    39 lib-$(CONFIG_HOSTID)    += hostid.o
    40 lib-$(CONFIG_ID)        += id.o
    4139lib-$(CONFIG_INSTALL)   += install.o
    42 lib-$(CONFIG_LENGTH)    += length.o
     40#lib-$(CONFIG_LENGTH)    += length.o
    4341lib-$(CONFIG_LN)        += ln.o
    4442lib-$(CONFIG_LOGNAME)   += logname.o
     
    6563lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
    6664lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
     65lib-$(CONFIG_SHA3SUM)   += md5_sha1_sum.o
    6766lib-$(CONFIG_SLEEP)     += sleep.o
    6867lib-$(CONFIG_SPLIT)     += split.o
     
    7574lib-$(CONFIG_TAIL)      += tail.o
    7675lib-$(CONFIG_TEE)       += tee.o
    77 lib-$(CONFIG_TOUCH)     += touch.o
    7876lib-$(CONFIG_TRUE)      += true.o
    7977lib-$(CONFIG_TTY)       += tty.o
     
    8583lib-$(CONFIG_UUENCODE)  += uuencode.o
    8684lib-$(CONFIG_WC)        += wc.o
    87 lib-$(CONFIG_WHO)       += who.o
    8885lib-$(CONFIG_WHOAMI)    += whoami.o
    8986lib-$(CONFIG_YES)       += yes.o
  • branches/3.2/mindi-busybox/coreutils/basename.c

    r2725 r3232  
    2929//config:     to enable the 'basename' utility.
    3030
     31//usage:#define basename_trivial_usage
     32//usage:       "FILE [SUFFIX]"
     33//usage:#define basename_full_usage "\n\n"
     34//usage:       "Strip directory path and .SUFFIX from FILE\n"
     35//usage:
     36//usage:#define basename_example_usage
     37//usage:       "$ basename /usr/local/bin/foo\n"
     38//usage:       "foo\n"
     39//usage:       "$ basename /usr/local/bin/\n"
     40//usage:       "bin\n"
     41//usage:       "$ basename /foo/bar.txt .txt\n"
     42//usage:       "bar"
     43
    3144#include "libbb.h"
    3245
     
    3851    size_t m, n;
    3952    char *s;
     53
     54    if (argv[1] && strcmp(argv[1], "--") == 0) {
     55        argv++;
     56        argc--;
     57    }
    4058
    4159    if ((unsigned)(argc-2) >= 2) {
  • branches/3.2/mindi-busybox/coreutils/cal.c

    r2725 r3232  
    1717 * Major size reduction... over 50% (>1.5k) on i386.
    1818 */
     19
     20//usage:#define cal_trivial_usage
     21//usage:       "[-jy] [[MONTH] YEAR]"
     22//usage:#define cal_full_usage "\n\n"
     23//usage:       "Display a calendar\n"
     24//usage:     "\n    -j  Use julian dates"
     25//usage:     "\n    -y  Display the entire year"
     26
    1927#include "libbb.h"
    2028#include "unicode.h"
     
    3644
    3745static const unsigned char sep1752[] ALIGN1 = {
    38          1, 2,  14, 15, 16,
     46        1,  2,  14, 15, 16,
    3947    17, 18, 19, 20, 21, 22, 23,
    4048    24, 25, 26, 27, 28, 29, 30
     
    139147                *hp++ = ' ';
    140148            {
    141                 char *two_wchars = unicode_conv_to_printable_fixedwidth(NULL, buf, 2);
     149                char *two_wchars = unicode_conv_to_printable_fixedwidth(/*NULL,*/ buf, 2);
    142150                strcpy(hp, two_wchars);
    143151                free(two_wchars);
     
    160168        len = sprintf(lineout, "%s %d", month_names[month - 1], year);
    161169        printf("%*s%s\n%s\n",
    162                ((7*julian + WEEK_LEN) - len) / 2, "",
    163                lineout, day_headings);
     170                ((7*julian + WEEK_LEN) - len) / 2, "",
     171                lineout, day_headings);
    164172        for (row = 0; row < 6; row++) {
    165173            build_row(lineout, dp)[0] = '\0';
     
    174182        sprintf(lineout, "%u", year);
    175183        center(lineout,
    176                (WEEK_LEN * 3 + HEAD_SEP * 2)
    177                + julian * (J_WEEK_LEN * 2 + HEAD_SEP
    178                            - (WEEK_LEN * 3 + HEAD_SEP * 2)),
    179                0);
     184                (WEEK_LEN * 3 + HEAD_SEP * 2)
     185                + julian * (J_WEEK_LEN * 2 + HEAD_SEP
     186                        - (WEEK_LEN * 3 + HEAD_SEP * 2)),
     187                0
     188        );
    180189        puts("\n");     /* two \n's */
    181190        for (i = 0; i < 12; i++) {
  • branches/3.2/mindi-busybox/coreutils/cat.c

    r2725 r3232  
    2222//config:     cat is used to concatenate files and print them to the standard
    2323//config:     output. Enable this option if you wish to enable the 'cat' utility.
     24
     25//usage:#define cat_trivial_usage
     26//usage:       "[FILE]..."
     27//usage:#define cat_full_usage "\n\n"
     28//usage:       "Concatenate FILEs and print them to stdout"
     29//usage:
     30//usage:#define cat_example_usage
     31//usage:       "$ cat /proc/uptime\n"
     32//usage:       "110716.72 17.67"
    2433
    2534#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/catv.c

    r2725 r3232  
    1010/* See "Cat -v considered harmful" at
    1111 * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */
     12
     13//usage:#define catv_trivial_usage
     14//usage:       "[-etv] [FILE]..."
     15//usage:#define catv_full_usage "\n\n"
     16//usage:       "Display nonprinting characters as ^x or M-x\n"
     17//usage:     "\n    -e  End each line with $"
     18//usage:     "\n    -t  Show tabs as ^I"
     19//usage:     "\n    -v  Don't use ^x or M-x escapes"
    1220
    1321#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/chgrp.c

    r2725 r3232  
    1111/* BB_AUDIT GNU defects - unsupported long options. */
    1212/* http://www.opengroup.org/onlinepubs/007904975/utilities/chgrp.html */
     13
     14//usage:#define chgrp_trivial_usage
     15//usage:       "[-RhLHP"IF_DESKTOP("cvf")"]... GROUP FILE..."
     16//usage:#define chgrp_full_usage "\n\n"
     17//usage:       "Change the group membership of each FILE to GROUP\n"
     18//usage:     "\n    -R  Recurse"
     19//usage:     "\n    -h  Affect symlinks instead of symlink targets"
     20//usage:     "\n    -L  Traverse all symlinks to directories"
     21//usage:     "\n    -H  Traverse symlinks on command line only"
     22//usage:     "\n    -P  Don't traverse symlinks (default)"
     23//usage:    IF_DESKTOP(
     24//usage:     "\n    -c  List changed files"
     25//usage:     "\n    -v  Verbose"
     26//usage:     "\n    -f  Hide errors"
     27//usage:    )
     28//usage:
     29//usage:#define chgrp_example_usage
     30//usage:       "$ ls -l /tmp/foo\n"
     31//usage:       "-r--r--r--    1 andersen andersen        0 Apr 12 18:25 /tmp/foo\n"
     32//usage:       "$ chgrp root /tmp/foo\n"
     33//usage:       "$ ls -l /tmp/foo\n"
     34//usage:       "-r--r--r--    1 andersen root            0 Apr 12 18:25 /tmp/foo\n"
    1335
    1436#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/chmod.c

    r2725 r3232  
    1414/* BB_AUDIT GNU defects - unsupported long options. */
    1515/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
     16
     17//usage:#define chmod_trivial_usage
     18//usage:       "[-R"IF_DESKTOP("cvf")"] MODE[,MODE]... FILE..."
     19//usage:#define chmod_full_usage "\n\n"
     20//usage:       "Each MODE is one or more of the letters ugoa, one of the\n"
     21//usage:       "symbols +-= and one or more of the letters rwxst\n"
     22//usage:     "\n    -R  Recurse"
     23//usage:    IF_DESKTOP(
     24//usage:     "\n    -c  List changed files"
     25//usage:     "\n    -v  List all files"
     26//usage:     "\n    -f  Hide errors"
     27//usage:    )
     28//usage:
     29//usage:#define chmod_example_usage
     30//usage:       "$ ls -l /tmp/foo\n"
     31//usage:       "-rw-rw-r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n"
     32//usage:       "$ chmod u+x /tmp/foo\n"
     33//usage:       "$ ls -l /tmp/foo\n"
     34//usage:       "-rwxrw-r--    1 root     root            0 Apr 12 18:25 /tmp/foo*\n"
     35//usage:       "$ chmod 444 /tmp/foo\n"
     36//usage:       "$ ls -l /tmp/foo\n"
     37//usage:       "-r--r--r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n"
    1638
    1739#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/chown.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv3 defects - none? */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
     12
     13//usage:#define chown_trivial_usage
     14//usage:       "[-RhLHP"IF_DESKTOP("cvf")"]... OWNER[<.|:>[GROUP]] FILE..."
     15//usage:#define chown_full_usage "\n\n"
     16//usage:       "Change the owner and/or group of each FILE to OWNER and/or GROUP\n"
     17//usage:     "\n    -R  Recurse"
     18//usage:     "\n    -h  Affect symlinks instead of symlink targets"
     19//usage:     "\n    -L  Traverse all symlinks to directories"
     20//usage:     "\n    -H  Traverse symlinks on command line only"
     21//usage:     "\n    -P  Don't traverse symlinks (default)"
     22//usage:    IF_DESKTOP(
     23//usage:     "\n    -c  List changed files"
     24//usage:     "\n    -v  List all files"
     25//usage:     "\n    -f  Hide errors"
     26//usage:    )
     27//usage:
     28//usage:#define chown_example_usage
     29//usage:       "$ ls -l /tmp/foo\n"
     30//usage:       "-r--r--r--    1 andersen andersen        0 Apr 12 18:25 /tmp/foo\n"
     31//usage:       "$ chown root /tmp/foo\n"
     32//usage:       "$ ls -l /tmp/foo\n"
     33//usage:       "-r--r--r--    1 root     andersen        0 Apr 12 18:25 /tmp/foo\n"
     34//usage:       "$ chown root.root /tmp/foo\n"
     35//usage:       "ls -l /tmp/foo\n"
     36//usage:       "-r--r--r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n"
    1237
    1338#include "libbb.h"
     
    102127    param.chown_func = chown;
    103128    if (OPT_NODEREF
    104         /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
    105         IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
     129    /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
     130    IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
    106131    ) {
    107132        param.chown_func = lchown;
  • branches/3.2/mindi-busybox/coreutils/chroot.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    1111
     12//usage:#define chroot_trivial_usage
     13//usage:       "NEWROOT [PROG ARGS]"
     14//usage:#define chroot_full_usage "\n\n"
     15//usage:       "Run PROG with root directory set to NEWROOT"
     16//usage:
     17//usage:#define chroot_example_usage
     18//usage:       "$ ls -l /bin/ls\n"
     19//usage:       "lrwxrwxrwx    1 root     root          12 Apr 13 00:46 /bin/ls -> /BusyBox\n"
     20//usage:       "# mount /dev/hdc1 /mnt -t minix\n"
     21//usage:       "# chroot /mnt\n"
     22//usage:       "# ls -l /bin/ls\n"
     23//usage:       "-rwxr-xr-x    1 root     root        40816 Feb  5 07:45 /bin/ls*\n"
     24
    1225#include "libbb.h"
    1326
     
    1932        bb_show_usage();
    2033    xchroot(*argv);
    21     xchdir("/");
    2234
    2335    ++argv;
    2436    if (!*argv) { /* no 2nd param (PROG), use shell */
    2537        argv -= 2;
    26         argv[0] = getenv("SHELL");
    27         if (!argv[0]) {
    28             argv[0] = (char *) DEFAULT_SHELL;
    29         }
    30         argv[1] = (char *) "-i";
     38        argv[0] = (char *) get_shell_name();
     39        argv[1] = (char *) "-i"; /* GNU coreutils 8.4 compat */
     40        /*argv[2] = NULL; - already is */
    3141    }
    3242
  • branches/3.2/mindi-busybox/coreutils/cksum.c

    r2859 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define cksum_trivial_usage
     11//usage:       "FILES..."
     12//usage:#define cksum_full_usage "\n\n"
     13//usage:       "Calculate the CRC32 checksums of FILES"
     14
    915#include "libbb.h"
    1016
  • branches/3.2/mindi-busybox/coreutils/comm.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define comm_trivial_usage
     11//usage:       "[-123] FILE1 FILE2"
     12//usage:#define comm_full_usage "\n\n"
     13//usage:       "Compare FILE1 with FILE2\n"
     14//usage:     "\n    -1  Suppress lines unique to FILE1"
     15//usage:     "\n    -2  Suppress lines unique to FILE2"
     16//usage:     "\n    -3  Suppress lines common to both files"
    917
    1018#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/cp.c

    r2725 r3232  
    1515 * Size reduction.
    1616 */
     17
     18//usage:#define cp_trivial_usage
     19//usage:       "[OPTIONS] SOURCE... DEST"
     20//usage:#define cp_full_usage "\n\n"
     21//usage:       "Copy SOURCE(s) to DEST\n"
     22//usage:     "\n    -a  Same as -dpR"
     23//usage:    IF_SELINUX(
     24//usage:     "\n    -c  Preserve security context"
     25//usage:    )
     26//usage:     "\n    -R,-r   Recurse"
     27//usage:     "\n    -d,-P   Preserve symlinks (default if -R)"
     28//usage:     "\n    -L  Follow all symlinks"
     29//usage:     "\n    -H  Follow symlinks on command line"
     30//usage:     "\n    -p  Preserve file attributes if possible"
     31//usage:     "\n    -f  Overwrite"
     32//usage:     "\n    -i  Prompt before overwrite"
     33//usage:     "\n    -l,-s   Create (sym)links"
    1734
    1835#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/cut.c

    r2725 r3232  
    99 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1010 */
     11
     12//usage:#define cut_trivial_usage
     13//usage:       "[OPTIONS] [FILE]..."
     14//usage:#define cut_full_usage "\n\n"
     15//usage:       "Print selected fields from each input FILE to stdout\n"
     16//usage:     "\n    -b LIST Output only bytes from LIST"
     17//usage:     "\n    -c LIST Output only characters from LIST"
     18//usage:     "\n    -d CHAR Use CHAR instead of tab as the field delimiter"
     19//usage:     "\n    -s  Output only the lines containing delimiter"
     20//usage:     "\n    -f N    Print only these fields"
     21//usage:     "\n    -n  Ignored"
     22//usage:
     23//usage:#define cut_example_usage
     24//usage:       "$ echo \"Hello world\" | cut -f 1 -d ' '\n"
     25//usage:       "Hello\n"
     26//usage:       "$ echo \"Hello world\" | cut -f 2 -d ' '\n"
     27//usage:       "world\n"
    1128
    1229#include "libbb.h"
     
    196213            bb_error_msg_and_die
    197214                ("suppressing non-delimited lines makes sense%s",
    198                  _op_on_field);
     215                _op_on_field);
    199216        }
    200217        if (delim != '\t') {
  • branches/3.2/mindi-busybox/coreutils/date.c

    r2725 r3232  
    2020   much as possible, missed out a lot of bounds checking */
    2121
    22 //applet:IF_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_DROP))
     22//applet:IF_DATE(APPLET(date, BB_DIR_BIN, BB_SUID_DROP))
    2323
    2424//kbuild:lib-$(CONFIG_DATE) += date.o
     
    4343//config:   bool "Support %[num]N nanosecond format specifier"
    4444//config:   default n
    45 //config:   depends on DATE && PLATFORM_LINUX # syscall(__NR_clock_gettime)
     45//config:   depends on DATE  # syscall(__NR_clock_gettime)
     46//config:   select PLATFORM_LINUX
    4647//config:   help
    4748//config:     Support %[num]N format specifier. Adds ~250 bytes of code.
     
    9899//usage:#define date_full_usage "\n\n"
    99100//usage:       "Display time (using +FMT), or set time\n"
    100 //usage:     "\nOptions:"
    101101//usage:    IF_NOT_LONG_OPTS(
    102102//usage:     "\n    [-s] TIME   Set time to TIME"
     
    130130//usage:     "\n    YYYY-MM-DD hh:mm[:ss]"
    131131//usage:     "\n    [[[[[YY]YY]MM]DD]hh]mm[.ss]"
     132//usage:    IF_FEATURE_DATE_COMPAT(
     133//usage:     "\n    'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead"
     134//usage:    )
    132135//usage:
    133136//usage:#define date_example_usage
     
    251254#if ENABLE_FEATURE_DATE_NANO
    252255        ts.tv_nsec = statbuf.st_mtim.tv_nsec;
    253         /* some toolchains use .st_mtimensec instead of st_mtim.tv_nsec */
     256        /* Some toolchains use .st_mtimensec instead of st_mtim.tv_nsec.
     257         * If you need #define _SVID_SOURCE 1 to enable st_mtim.tv_nsec,
     258         * drop a mail to project mailing list please
     259         */
    254260#endif
    255261    } else {
     
    280286
    281287        /* Correct any day of week and day of year etc. fields */
    282         tm_time.tm_isdst = -1;  /* Be sure to recheck dst */
     288        /* Be sure to recheck dst (but not if date is time_t format) */
     289        if (date_str[0] != '@')
     290            tm_time.tm_isdst = -1;
    283291        ts.tv_sec = validate_tm_time(date_str, &tm_time);
    284292
  • branches/3.2/mindi-busybox/coreutils/dd.c

    r2725 r3232  
    88 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 */
     10
     11//usage:#define dd_trivial_usage
     12//usage:       "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
     13//usage:       "    [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]")
     14//usage:#define dd_full_usage "\n\n"
     15//usage:       "Copy a file with converting and formatting\n"
     16//usage:     "\n    if=FILE     Read from FILE instead of stdin"
     17//usage:     "\n    of=FILE     Write to FILE instead of stdout"
     18//usage:     "\n    bs=N        Read and write N bytes at a time"
     19//usage:    IF_FEATURE_DD_IBS_OBS(
     20//usage:     "\n    ibs=N       Read N bytes at a time"
     21//usage:    )
     22//usage:    IF_FEATURE_DD_IBS_OBS(
     23//usage:     "\n    obs=N       Write N bytes at a time"
     24//usage:    )
     25//usage:     "\n    count=N     Copy only N input blocks"
     26//usage:     "\n    skip=N      Skip N input blocks"
     27//usage:     "\n    seek=N      Skip N output blocks"
     28//usage:    IF_FEATURE_DD_IBS_OBS(
     29//usage:     "\n    conv=notrunc    Don't truncate output file"
     30//usage:     "\n    conv=noerror    Continue after read errors"
     31//usage:     "\n    conv=sync   Pad blocks with zeros"
     32//usage:     "\n    conv=fsync  Physically write data out before finishing"
     33//usage:    )
     34//usage:     "\n"
     35//usage:     "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),"
     36//usage:     "\nMD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
     37//usage:
     38//usage:#define dd_example_usage
     39//usage:       "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n"
     40//usage:       "4+0 records in\n"
     41//usage:       "4+0 records out\n"
    1042
    1143#include "libbb.h"
     
    398430    dd_output_status(0);
    399431
     432    if (ENABLE_FEATURE_CLEAN_UP) {
     433        free(obuf);
     434        if (flags & FLAG_TWOBUFS)
     435            free(ibuf);
     436    }
     437
    400438    return exitcode;
    401439}
  • branches/3.2/mindi-busybox/coreutils/df.c

    r2725 r3232  
    2222 * Implement -P and -B; better coreutils compat; cleanup
    2323 */
     24
     25//usage:#define df_trivial_usage
     26//usage:    "[-Pk"
     27//usage:    IF_FEATURE_HUMAN_READABLE("mh")
     28//usage:    IF_FEATURE_DF_FANCY("ai] [-B SIZE")
     29//usage:    "] [FILESYSTEM]..."
     30//usage:#define df_full_usage "\n\n"
     31//usage:       "Print filesystem usage statistics\n"
     32//usage:     "\n    -P  POSIX output format"
     33//usage:     "\n    -k  1024-byte blocks (default)"
     34//usage:    IF_FEATURE_HUMAN_READABLE(
     35//usage:     "\n    -m  1M-byte blocks"
     36//usage:     "\n    -h  Human readable (e.g. 1K 243M 2G)"
     37//usage:    )
     38//usage:    IF_FEATURE_DF_FANCY(
     39//usage:     "\n    -a  Show all filesystems"
     40//usage:     "\n    -i  Inodes"
     41//usage:     "\n    -B SIZE Blocksize"
     42//usage:    )
     43//usage:
     44//usage:#define df_example_usage
     45//usage:       "$ df\n"
     46//usage:       "Filesystem           1K-blocks      Used Available Use% Mounted on\n"
     47//usage:       "/dev/sda3              8690864   8553540    137324  98% /\n"
     48//usage:       "/dev/sda1                64216     36364     27852  57% /boot\n"
     49//usage:       "$ df /dev/sda3\n"
     50//usage:       "Filesystem           1K-blocks      Used Available Use% Mounted on\n"
     51//usage:       "/dev/sda3              8690864   8553540    137324  98% /\n"
     52//usage:       "$ POSIXLY_CORRECT=sure df /dev/sda3\n"
     53//usage:       "Filesystem         512B-blocks      Used Available Use% Mounted on\n"
     54//usage:       "/dev/sda3             17381728  17107080    274648  98% /\n"
     55//usage:       "$ POSIXLY_CORRECT=yep df -P /dev/sda3\n"
     56//usage:       "Filesystem          512-blocks      Used Available Capacity Mounted on\n"
     57//usage:       "/dev/sda3             17381728  17107080    274648      98% /\n"
    2458
    2559#include <mntent.h>
     
    77111
    78112    /* From the manpage of df from coreutils-6.10:
    79        Disk space is shown in 1K blocks by default, unless the environment
    80        variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
    81     */
     113     * Disk space is shown in 1K blocks by default, unless the environment
     114     * variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
     115     */
    82116    if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
    83117        df_disp_hr = 512;
     
    161195
    162196            /* GNU coreutils 6.10 skips certain mounts, try to be compatible.  */
    163             if (strcmp(device, "rootfs") == 0)
     197            if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(device, "rootfs") == 0)
    164198                continue;
    165199
     
    179213                uni_stat_t uni_stat;
    180214                char *uni_dev = unicode_conv_to_printable(&uni_stat, device);
    181                 if (uni_stat.unicode_width > 20) {
     215                if (uni_stat.unicode_width > 20 && !(opt & OPT_POSIX)) {
    182216                    printf("%s\n%20s", uni_dev, "");
    183217                } else {
     
    187221            }
    188222#else
    189             if (printf("\n%-20s" + 1, device) > 20)
    190                     printf("\n%-20s", "");
     223            if (printf("\n%-20s" + 1, device) > 20 && !(opt & OPT_POSIX))
     224                printf("\n%-20s", "");
    191225#endif
    192226
  • branches/3.2/mindi-busybox/coreutils/dirname.c

    r2725 r3232  
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */
    1212
     13//usage:#define dirname_trivial_usage
     14//usage:       "FILENAME"
     15//usage:#define dirname_full_usage "\n\n"
     16//usage:       "Strip non-directory suffix from FILENAME"
     17//usage:
     18//usage:#define dirname_example_usage
     19//usage:       "$ dirname /tmp/foo\n"
     20//usage:       "/tmp\n"
     21//usage:       "$ dirname /tmp/foo/\n"
     22//usage:       "/tmp\n"
     23
    1324#include "libbb.h"
    1425
  • branches/3.2/mindi-busybox/coreutils/dos2unix.c

    r2725 r3232  
    1212 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1313*/
     14
     15//usage:#define dos2unix_trivial_usage
     16//usage:       "[-ud] [FILE]"
     17//usage:#define dos2unix_full_usage "\n\n"
     18//usage:       "Convert FILE in-place from DOS to Unix format.\n"
     19//usage:       "When no file is given, use stdin/stdout.\n"
     20//usage:     "\n    -u  dos2unix"
     21//usage:     "\n    -d  unix2dos"
     22//usage:
     23//usage:#define unix2dos_trivial_usage
     24//usage:       "[-ud] [FILE]"
     25//usage:#define unix2dos_full_usage "\n\n"
     26//usage:       "Convert FILE in-place from Unix to DOS format.\n"
     27//usage:       "When no file is given, use stdin/stdout.\n"
     28//usage:     "\n    -u  dos2unix"
     29//usage:     "\n    -d  unix2dos"
    1430
    1531#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/du.c

    r2725 r3232  
    2323 * 4) Fixed busybox bug #1284 involving long overflow with human_readable.
    2424 */
     25
     26//usage:#define du_trivial_usage
     27//usage:       "[-aHLdclsx" IF_FEATURE_HUMAN_READABLE("hm") "k] [FILE]..."
     28//usage:#define du_full_usage "\n\n"
     29//usage:       "Summarize disk space used for each FILE and/or directory\n"
     30//usage:     "\n    -a  Show file sizes too"
     31//usage:     "\n    -L  Follow all symlinks"
     32//usage:     "\n    -H  Follow symlinks on command line"
     33//usage:     "\n    -d N    Limit output to directories (and files with -a) of depth < N"
     34//usage:     "\n    -c  Show grand total"
     35//usage:     "\n    -l  Count sizes many times if hard linked"
     36//usage:     "\n    -s  Display only a total for each argument"
     37//usage:     "\n    -x  Skip directories on different filesystems"
     38//usage:    IF_FEATURE_HUMAN_READABLE(
     39//usage:     "\n    -h  Sizes in human readable format (e.g., 1K 243M 2G)"
     40//usage:     "\n    -m  Sizes in megabytes"
     41//usage:    )
     42//usage:     "\n    -k  Sizes in kilobytes" IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(" (default)")
     43//usage:    IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(
     44//usage:     "\n        Default unit is 512 bytes"
     45//usage:    )
     46//usage:
     47//usage:#define du_example_usage
     48//usage:       "$ du\n"
     49//usage:       "16      ./CVS\n"
     50//usage:       "12      ./kernel-patches/CVS\n"
     51//usage:       "80      ./kernel-patches\n"
     52//usage:       "12      ./tests/CVS\n"
     53//usage:       "36      ./tests\n"
     54//usage:       "12      ./scripts/CVS\n"
     55//usage:       "16      ./scripts\n"
     56//usage:       "12      ./docs/CVS\n"
     57//usage:       "104     ./docs\n"
     58//usage:       "2417    .\n"
    2559
    2660#include "libbb.h"
     
    5387} FIX_ALIASING;
    5488#define G (*(struct globals*)&bb_common_bufsiz1)
    55 
    56 
    57 static void print(unsigned long size, const char *filename)
     89#define INIT_G() do { } while (0)
     90
     91
     92/* FIXME? coreutils' du rounds sizes up:
     93 * for example,  1025k file is shown as "2" by du -m.
     94 * We round to nearest.
     95 */
     96static void print(unsigned long long size, const char *filename)
    5897{
    5998    /* TODO - May not want to defer error checking here. */
     
    69108        size >>= 1;
    70109    }
    71     printf("%lu\t%s\n", size, filename);
     110    printf("%llu\t%s\n", size, filename);
    72111#endif
    73112}
    74113
    75114/* tiny recursive du */
    76 static unsigned long du(const char *filename)
     115static unsigned long long du(const char *filename)
    77116{
    78117    struct stat statbuf;
    79     unsigned long sum;
     118    unsigned long long sum;
    80119
    81120    if (lstat(filename, &statbuf) != 0) {
     
    154193int du_main(int argc UNUSED_PARAM, char **argv)
    155194{
    156     unsigned long total;
     195    unsigned long long total;
    157196    int slink_depth_save;
    158197    unsigned opt;
     198
     199    INIT_G();
    159200
    160201#if ENABLE_FEATURE_HUMAN_READABLE
  • branches/3.2/mindi-busybox/coreutils/echo.c

    r2725 r3232  
    2424 */
    2525
     26//usage:#define echo_trivial_usage
     27//usage:    IF_FEATURE_FANCY_ECHO("[-neE] ") "[ARG]..."
     28//usage:#define echo_full_usage "\n\n"
     29//usage:       "Print the specified ARGs to stdout"
     30//usage:    IF_FEATURE_FANCY_ECHO( "\n"
     31//usage:     "\n    -n  Suppress trailing newline"
     32//usage:     "\n    -e  Interpret backslash escapes (i.e., \\t=tab)"
     33//usage:     "\n    -E  Don't interpret backslash escapes (default)"
     34//usage:    )
     35//usage:
     36//usage:#define echo_example_usage
     37//usage:       "$ echo \"Erik is cool\"\n"
     38//usage:       "Erik is cool\n"
     39//usage:    IF_FEATURE_FANCY_ECHO("$ echo -e \"Erik\\nis\\ncool\"\n"
     40//usage:       "Erik\n"
     41//usage:       "is\n"
     42//usage:       "cool\n"
     43//usage:       "$ echo \"Erik\\nis\\ncool\"\n"
     44//usage:       "Erik\\nis\\ncool\n")
     45
    2646#include "libbb.h"
    2747
     
    2949
    3050/* NB: can be used by shell even if not enabled as applet */
     51
     52/*
     53 * NB2: we don't use stdio, we need better error handing.
     54 * Examples include writing into non-opened stdout and error on write.
     55 *
     56 * With stdio, output gets shoveled into stdout buffer, and even
     57 * fflush cannot clear it out. It seems that even if libc receives
     58 * EBADF on write attempts, it feels determined to output data no matter what.
     59 * If echo is called by shell, it will try writing again later, and possibly
     60 * will clobber future output. Not good.
     61 *
     62 * Solaris has fpurge which discards buffered input. glibc has __fpurge.
     63 * But this function is not standard.
     64 */
    3165
    3266int echo_main(int argc UNUSED_PARAM, char **argv)
    3367{
     68    char **pp;
    3469    const char *arg;
     70    char *out;
     71    char *buffer;
     72    unsigned buflen;
    3573#if !ENABLE_FEATURE_FANCY_ECHO
    3674    enum {
     
    3977    };
    4078
    41     /* We must check that stdout is not closed.
    42      * The reason for this is highly non-obvious.
    43      * echo_main is used from shell. Shell must correctly handle "echo foo"
    44      * if stdout is closed. With stdio, output gets shoveled into
    45      * stdout buffer, and even fflush cannot clear it out. It seems that
    46      * even if libc receives EBADF on write attempts, it feels determined
    47      * to output data no matter what. So it will try later,
    48      * and possibly will clobber future output. Not good. */
    49 // TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
    50     if (fcntl(1, F_GETFL) == -1)
    51         return 1; /* match coreutils 6.10 (sans error msg to stderr) */
    52     //if (dup2(1, 1) != 1) - old way
    53     //  return 1;
    54 
    55     arg = *++argv;
    56     if (!arg)
    57         goto newline_ret;
     79    argv++;
    5880#else
    59     const char *p;
    6081    char nflag = 1;
    6182    char eflag = 0;
    6283
    63     /* We must check that stdout is not closed. */
    64     if (fcntl(1, F_GETFL) == -1)
    65         return 1;
    66 
    67     while (1) {
    68         arg = *++argv;
    69         if (!arg)
    70             goto newline_ret;
    71         if (*arg != '-')
    72             break;
     84    while ((arg = *++argv) != NULL) {
     85        char n, e;
     86
     87        if (arg[0] != '-')
     88            break; /* not an option arg, echo it */
    7389
    7490        /* If it appears that we are handling options, then make sure
     
    7692         * Otherwise, the string should just be echoed.
    7793         */
    78         p = arg + 1;
    79         if (!*p)    /* A single '-', so echo it. */
    80             goto just_echo;
    81 
     94        arg++;
     95        n = nflag;
     96        e = eflag;
    8297        do {
    83             if (!strrchr("neE", *p))
     98            if (*arg == 'n')
     99                n = 0;
     100            else if (*arg == 'e')
     101                e = '\\';
     102            else if (*arg != 'E') {
     103                /* "-ccc" arg with one of c's invalid, echo it */
     104                /* arg consisting from just "-" also handled here */
    84105                goto just_echo;
    85         } while (*++p);
    86 
    87         /* All of the options in this arg are valid, so handle them. */
    88         p = arg + 1;
    89         do {
    90             if (*p == 'n')
    91                 nflag = 0;
    92             if (*p == 'e')
    93                 eflag = '\\';
    94         } while (*++p);
     106            }
     107        } while (*++arg);
     108        nflag = n;
     109        eflag = e;
    95110    }
    96111 just_echo:
    97112#endif
    98     while (1) {
    99         /* arg is already == *argv and isn't NULL */
     113
     114    buflen = 0;
     115    pp = argv;
     116    while ((arg = *pp) != NULL) {
     117        buflen += strlen(arg) + 1;
     118        pp++;
     119    }
     120    out = buffer = xmalloc(buflen + 1); /* +1 is needed for "no args" case */
     121
     122    while ((arg = *argv) != NULL) {
    100123        int c;
    101124
    102125        if (!eflag) {
    103126            /* optimization for very common case */
    104             fputs(arg, stdout);
    105         } else while ((c = *arg++)) {
    106             if (c == eflag) {   /* Check for escape seq. */
     127            out = stpcpy(out, arg);
     128        } else
     129        while ((c = *arg++) != '\0') {
     130            if (c == eflag) {
     131                /* This is an "\x" sequence */
     132
    107133                if (*arg == 'c') {
    108                     /* '\c' means cancel newline and
     134                    /* "\c" means cancel newline and
    109135                     * ignore all subsequent chars. */
    110                     goto ret;
    111                 }
    112 #if !ENABLE_FEATURE_FANCY_ECHO
    113                 /* SUSv3 specifies that octal escapes must begin with '0'. */
    114                 if ( ((int)(unsigned char)(*arg) - '0') >= 8) /* '8' or bigger */
    115 #endif
     136                    goto do_write;
     137                }
     138                /* Since SUSv3 mandates a first digit of 0, 4-digit octals
     139                * of the form \0### are accepted. */
     140                if (*arg == '0') {
     141                    if ((unsigned char)(arg[1] - '0') < 8) {
     142                        /* 2nd char is 0..7: skip leading '0' */
     143                        arg++;
     144                    }
     145                }
     146                /* bb_process_escape_sequence handles NUL correctly
     147                 * ("...\" case). */
    116148                {
    117                     /* Since SUSv3 mandates a first digit of 0, 4-digit octals
    118                     * of the form \0### are accepted. */
    119                     if (*arg == '0') {
    120                         /* NB: don't turn "...\0" into "...\" */
    121                         if (arg[1] && ((unsigned char)(arg[1]) - '0') < 8) {
    122                             arg++;
    123                         }
    124                     }
    125                     /* bb_process_escape_sequence handles NUL correctly
    126                      * ("...\" case). */
    127                     c = bb_process_escape_sequence(&arg);
     149                    /* optimization: don't force arg to be on-stack,
     150                     * use another variable for that. ~30 bytes win */
     151                    const char *z = arg;
     152                    c = bb_process_escape_sequence(&z);
     153                    arg = z;
    128154                }
    129155            }
    130             bb_putchar(c);
     156            *out++ = c;
    131157        }
    132158
    133         arg = *++argv;
    134         if (!arg)
     159        if (!*++argv)
    135160            break;
    136         bb_putchar(' ');
    137     }
    138 
    139  newline_ret:
     161        *out++ = ' ';
     162    }
     163
    140164    if (nflag) {
    141         bb_putchar('\n');
    142     }
    143  ret:
    144     return fflush_all();
     165        *out++ = '\n';
     166    }
     167
     168 do_write:
     169    /* Careful to error out on partial writes too (think ENOSPC!) */
     170    errno = 0;
     171    /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer);
     172    free(buffer);
     173    if (/*WRONG:r < 0*/ errno) {
     174        bb_perror_msg(bb_msg_write_error);
     175        return 1;
     176    }
     177    return 0;
    145178}
    146179
    147 /*-
     180/*
    148181 * Copyright (c) 1991, 1993
    149182 *  The Regents of the University of California.  All rights reserved.
     
    231264
    232265        do {
    233             if (!strrchr("neE", *p))
     266            if (!strchr("neE", *p))
    234267                goto just_echo;
    235268        } while (*++p);
     
    257290            p += strlen(arg);
    258291        } else while ((c = *arg++)) {
    259             if (c == eflag) {   /* Check for escape seq. */
     292            if (c == eflag) {
     293                /* This is an "\x" sequence */
     294
    260295                if (*arg == 'c') {
    261                     /* '\c' means cancel newline and
     296                    /* "\c" means cancel newline and
    262297                     * ignore all subsequent chars. */
    263298                    cur_io->iov_len = p - (char*)cur_io->iov_base;
     
    265300                    goto ret;
    266301                }
    267 #if !ENABLE_FEATURE_FANCY_ECHO
    268                 /* SUSv3 specifies that octal escapes must begin with '0'. */
    269                 if ( (((unsigned char)*arg) - '1') >= 7)
    270 #endif
    271                 {
    272                     /* Since SUSv3 mandates a first digit of 0, 4-digit octals
    273                     * of the form \0### are accepted. */
    274                     if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) {
    275                         arg++;
    276                     }
    277                     /* bb_process_escape_sequence can handle nul correctly */
    278                     c = bb_process_escape_sequence( (void*) &arg);
    279                 }
     302                /* Since SUSv3 mandates a first digit of 0, 4-digit octals
     303                * of the form \0### are accepted. */
     304                if (*arg == '0' && (unsigned char)(arg[1] - '0') < 8) {
     305                    arg++;
     306                }
     307                /* bb_process_escape_sequence can handle nul correctly */
     308                c = bb_process_escape_sequence( (void*) &arg);
    280309            }
    281310            *p++ = c;
  • branches/3.2/mindi-busybox/coreutils/env.c

    r2725 r3232  
    3131
    3232/* This is a NOEXEC applet. Be very careful! */
     33
     34//usage:#define env_trivial_usage
     35//usage:       "[-iu] [-] [name=value]... [PROG ARGS]"
     36//usage:#define env_full_usage "\n\n"
     37//usage:       "Print the current environment or run PROG after setting up\n"
     38//usage:       "the specified environment\n"
     39//usage:     "\n    -, -i   Start with an empty environment"
     40//usage:     "\n    -u  Remove variable from the environment"
    3341
    3442#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/expand.c

    r2725 r3232  
    2121 *  Caveat: this versions of expand and unexpand don't accept tab lists.
    2222 */
     23
     24//usage:#define expand_trivial_usage
     25//usage:       "[-i] [-t N] [FILE]..."
     26//usage:#define expand_full_usage "\n\n"
     27//usage:       "Convert tabs to spaces, writing to stdout\n"
     28//usage:    IF_FEATURE_EXPAND_LONG_OPTIONS(
     29//usage:     "\n    -i,--initial    Don't convert tabs after non blanks"
     30//usage:     "\n    -t,--tabs=N Tabstops every N chars"
     31//usage:    )
     32//usage:    IF_NOT_FEATURE_EXPAND_LONG_OPTIONS(
     33//usage:     "\n    -i  Don't convert tabs after non blanks"
     34//usage:     "\n    -t  Tabstops every N chars"
     35//usage:    )
     36
     37//usage:#define unexpand_trivial_usage
     38//usage:       "[-fa][-t N] [FILE]..."
     39//usage:#define unexpand_full_usage "\n\n"
     40//usage:       "Convert spaces to tabs, writing to stdout\n"
     41//usage:    IF_FEATURE_UNEXPAND_LONG_OPTIONS(
     42//usage:     "\n    -a,--all    Convert all blanks"
     43//usage:     "\n    -f,--first-only Convert only leading blanks"
     44//usage:     "\n    -t,--tabs=N Tabstops every N chars"
     45//usage:    )
     46//usage:    IF_NOT_FEATURE_UNEXPAND_LONG_OPTIONS(
     47//usage:     "\n    -a  Convert all blanks"
     48//usage:     "\n    -f  Convert only leading blanks"
     49//usage:     "\n    -t N    Tabstops every N chars"
     50//usage:    )
     51
    2352#include "libbb.h"
    2453#include "unicode.h"
  • branches/3.2/mindi-busybox/coreutils/expr.c

    r2725 r3232  
    2626/* no getopt needed */
    2727
     28//usage:#define expr_trivial_usage
     29//usage:       "EXPRESSION"
     30//usage:#define expr_full_usage "\n\n"
     31//usage:       "Print the value of EXPRESSION to stdout\n"
     32//usage:    "\n"
     33//usage:       "EXPRESSION may be:\n"
     34//usage:       "    ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n"
     35//usage:       "    ARG1 & ARG2 ARG1 if neither argument is null or 0, otherwise 0\n"
     36//usage:       "    ARG1 < ARG2 1 if ARG1 is less than ARG2, else 0. Similarly:\n"
     37//usage:       "    ARG1 <= ARG2\n"
     38//usage:       "    ARG1 = ARG2\n"
     39//usage:       "    ARG1 != ARG2\n"
     40//usage:       "    ARG1 >= ARG2\n"
     41//usage:       "    ARG1 > ARG2\n"
     42//usage:       "    ARG1 + ARG2 Sum of ARG1 and ARG2. Similarly:\n"
     43//usage:       "    ARG1 - ARG2\n"
     44//usage:       "    ARG1 * ARG2\n"
     45//usage:       "    ARG1 / ARG2\n"
     46//usage:       "    ARG1 % ARG2\n"
     47//usage:       "    STRING : REGEXP     Anchored pattern match of REGEXP in STRING\n"
     48//usage:       "    match STRING REGEXP Same as STRING : REGEXP\n"
     49//usage:       "    substr STRING POS LENGTH Substring of STRING, POS counted from 1\n"
     50//usage:       "    index STRING CHARS  Index in STRING where any CHARS is found, or 0\n"
     51//usage:       "    length STRING       Length of STRING\n"
     52//usage:       "    quote TOKEN     Interpret TOKEN as a string, even if\n"
     53//usage:       "                it is a keyword like 'match' or an\n"
     54//usage:       "                operator like '/'\n"
     55//usage:       "    (EXPRESSION)        Value of EXPRESSION\n"
     56//usage:       "\n"
     57//usage:       "Beware that many operators need to be escaped or quoted for shells.\n"
     58//usage:       "Comparisons are arithmetic if both ARGs are numbers, else\n"
     59//usage:       "lexicographical. Pattern matches return the string matched between\n"
     60//usage:       "\\( and \\) or null; if \\( and \\) are not used, they return the number\n"
     61//usage:       "of characters matched or 0."
     62
    2863#include "libbb.h"
    2964#include "xregex.h"
     
    66101} FIX_ALIASING;
    67102#define G (*(struct globals*)&bb_common_bufsiz1)
     103#define INIT_G() do { } while (0)
    68104
    69105/* forward declarations */
     
    485521    VALUE *v;
    486522
     523    INIT_G();
     524
    487525    xfunc_error_retval = 2; /* coreutils compat */
    488526    G.args = argv + 1;
  • branches/3.2/mindi-busybox/coreutils/false.c

    r2725 r3232  
    1111/* http://www.opengroup.org/onlinepubs/000095399/utilities/false.html */
    1212
     13//usage:#define false_trivial_usage
     14//usage:       ""
     15//usage:#define false_full_usage "\n\n"
     16//usage:       "Return an exit code of FALSE (1)"
     17//usage:
     18//usage:#define false_example_usage
     19//usage:       "$ false\n"
     20//usage:       "$ echo $?\n"
     21//usage:       "1\n"
     22
    1323#include "libbb.h"
    1424
  • branches/3.2/mindi-busybox/coreutils/fold.c

    r2725 r3232  
    1010   Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1111*/
     12
     13//usage:#define fold_trivial_usage
     14//usage:       "[-bs] [-w WIDTH] [FILE]..."
     15//usage:#define fold_full_usage "\n\n"
     16//usage:       "Wrap input lines in each FILE (or stdin), writing to stdout\n"
     17//usage:     "\n    -b  Count bytes rather than columns"
     18//usage:     "\n    -s  Break at spaces"
     19//usage:     "\n    -w  Use WIDTH columns instead of 80"
     20
    1221#include "libbb.h"
    1322#include "unicode.h"
  • branches/3.2/mindi-busybox/coreutils/fsync.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define fsync_trivial_usage
     11//usage:       "[-d] FILE..."
     12//usage:#define fsync_full_usage "\n\n"
     13//usage:       "Write files' buffered blocks to disk\n"
     14//usage:     "\n    -d  Avoid syncing metadata"
     15
    916#include "libbb.h"
    1017#ifndef O_NOATIME
  • branches/3.2/mindi-busybox/coreutils/head.c

    r2725 r3232  
    1111/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
    1212/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
     13
     14//usage:#define head_trivial_usage
     15//usage:       "[OPTIONS] [FILE]..."
     16//usage:#define head_full_usage "\n\n"
     17//usage:       "Print first 10 lines of each FILE (or stdin) to stdout.\n"
     18//usage:       "With more than one FILE, precede each with a filename header.\n"
     19//usage:     "\n    -n N[kbm]   Print first N lines"
     20//usage:    IF_FEATURE_FANCY_HEAD(
     21//usage:     "\n    -c N[kbm]   Print first N bytes"
     22//usage:     "\n    -q      Never print headers"
     23//usage:     "\n    -v      Always print headers"
     24//usage:    )
     25//usage:     "\n"
     26//usage:     "\nN may be suffixed by k (x1024), b (x512), or m (x1024^2)."
     27//usage:
     28//usage:#define head_example_usage
     29//usage:       "$ head -n 2 /etc/passwd\n"
     30//usage:       "root:x:0:0:root:/root:/bin/bash\n"
     31//usage:       "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n"
    1332
    1433#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/hostid.c

    r2725 r3232  
    99
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
     11
     12//config:config HOSTID
     13//config:   bool "hostid"
     14//config:   default y
     15//config:   help
     16//config:     hostid prints the numeric identifier (in hexadecimal) for
     17//config:     the current host.
     18
     19//applet:IF_HOSTID(APPLET_NOFORK(hostid, hostid, BB_DIR_USR_BIN, BB_SUID_DROP, hostid))
     20
     21//kbuild:lib-$(CONFIG_HOSTID) += hostid.o
     22
     23//usage:#define hostid_trivial_usage
     24//usage:       ""
     25//usage:#define hostid_full_usage "\n\n"
     26//usage:       "Print out a unique 32-bit identifier for the machine"
    1127
    1228#include "libbb.h"
     
    2137    }
    2238
    23     printf("%lx\n", gethostid());
     39    printf("%08lx\n", gethostid());
    2440
    2541    return fflush_all();
  • branches/3.2/mindi-busybox/coreutils/id.c

    r2725 r3232  
    1515 * Added -G option Tito Ragusa (C) 2008 for SUSv3.
    1616 */
     17
     18//config:config ID
     19//config:   bool "id"
     20//config:   default y
     21//config:   help
     22//config:     id displays the current user and group ID names.
     23
     24//config:config GROUPS
     25//config:   bool "groups"
     26//config:   default y
     27//config:   help
     28//config:     Print the group names associated with current user id.
     29
     30//kbuild:lib-$(CONFIG_GROUPS) += id.o
     31//kbuild:lib-$(CONFIG_ID)     += id.o
     32
     33//applet:IF_GROUPS(APPLET_NOEXEC(groups, id, BB_DIR_USR_BIN, BB_SUID_DROP, groups))
     34//applet:IF_ID(    APPLET_NOEXEC(id,     id, BB_DIR_USR_BIN, BB_SUID_DROP, id    ))
     35
     36//usage:#define id_trivial_usage
     37//usage:       "[OPTIONS] [USER]"
     38//usage:#define id_full_usage "\n\n"
     39//usage:       "Print information about USER or the current user\n"
     40//usage:    IF_SELINUX(
     41//usage:     "\n    -Z  Security context"
     42//usage:    )
     43//usage:     "\n    -u  User ID"
     44//usage:     "\n    -g  Group ID"
     45//usage:     "\n    -G  Supplementary group IDs"
     46//usage:     "\n    -n  Print names instead of numbers"
     47//usage:     "\n    -r  Print real ID instead of effective ID"
     48//usage:
     49//usage:#define id_example_usage
     50//usage:       "$ id\n"
     51//usage:       "uid=1000(andersen) gid=1000(andersen)\n"
     52
     53//usage:#define groups_trivial_usage
     54//usage:       "[USER]"
     55//usage:#define groups_full_usage "\n\n"
     56//usage:       "Print the group memberships of USER or for the current process"
     57//usage:
     58//usage:#define groups_example_usage
     59//usage:       "$ groups\n"
     60//usage:       "andersen lp dialout cdrom floppy\n"
    1761
    1862#include "libbb.h"
     
    74118/* On error set *n < 0 and return >= 0
    75119 * If *n is too small, update it and return < 0
    76  *  (ok to trash groups[] in both cases)
     120 * (ok to trash groups[] in both cases)
    77121 * Otherwise fill in groups[] and return >= 0
    78122 */
     
    88132        /* I guess *n < 0 might indicate error. Anyway,
    89133         * malloc'ing -1 bytes won't be good, so: */
    90         //if (*n < 0)
    91         //  return 0;
    92         //return m;
    93         //commented out here, happens below anyway
    94     } else {
    95         /* On error -1 is returned, which ends up in *n */
    96         int nn = getgroups(*n, groups);
    97         /* 0: nn <= *n, groups[] was big enough; -1 otherwise */
    98         m = - (nn > *n);
    99         *n = nn;
    100     }
    101     if (*n < 0)
    102         return 0; /* error, don't return < 0! */
    103     return m;
     134        if (*n < 0)
     135            return 0;
     136        return m;
     137    }
     138
     139    *n = getgroups(*n, groups);
     140    if (*n >= 0)
     141        return *n;
     142    /* Error */
     143    if (errno == EINVAL) /* *n is too small? */
     144        *n = getgroups(0, groups); /* get needed *n */
     145    /* if *n >= 0, return -1 (got new *n), else return 0 (error): */
     146    return -(*n >= 0);
    104147}
    105148
     
    119162    security_context_t scontext = NULL;
    120163#endif
    121     /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
    122     /* Don't allow more than one username */
    123     opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
    124              IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G");
    125     opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
     164
     165    if (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 'g')) {
     166        /* TODO: coreutils groups prepend "USER : " prefix,
     167         * and accept many usernames. Example:
     168         * # groups root root
     169         * root : root
     170         * root : root
     171         */
     172        opt = option_mask32 = getopt32(argv, "") | JUST_ALL_GROUPS | NAME_NOT_NUMBER;
     173    } else {
     174        /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
     175        /* Don't allow more than one username */
     176        opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
     177            IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G");
     178        opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
     179    }
    126180
    127181    username = argv[optind];
     
    160214         * to not run get_groups() twice. That might be slow
    161215         * ("user database in remote SQL server" case) */
    162         groups = xmalloc(64 * sizeof(gid_t));
     216        groups = xmalloc(64 * sizeof(groups[0]));
    163217        n = 64;
    164218        if (get_groups(username, rgid, groups, &n) < 0) {
    165219            /* Need bigger buffer after all */
    166             groups = xrealloc(groups, n * sizeof(gid_t));
     220            groups = xrealloc(groups, n * sizeof(groups[0]));
    167221            get_groups(username, rgid, groups, &n);
    168222        }
     
    177231            }
    178232        } else if (n < 0) { /* error in get_groups() */
    179             if (!ENABLE_DESKTOP)
     233            if (ENABLE_DESKTOP)
    180234                bb_error_msg_and_die("can't get groups");
    181             else
    182                 return EXIT_FAILURE;
     235            return EXIT_FAILURE;
    183236        }
    184237        if (ENABLE_FEATURE_CLEAN_UP)
  • branches/3.2/mindi-busybox/coreutils/install.c

    r2725 r3232  
    66 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    77 */
     8
     9/* -v, -b, -c are ignored */
     10//usage:#define install_trivial_usage
     11//usage:    "[-cdDsp] [-o USER] [-g GRP] [-m MODE] [SOURCE]... DEST"
     12//usage:#define install_full_usage "\n\n"
     13//usage:       "Copy files and set attributes\n"
     14//usage:     "\n    -c  Just copy (default)"
     15//usage:     "\n    -d  Create directories"
     16//usage:     "\n    -D  Create leading target directories"
     17//usage:     "\n    -s  Strip symbol table"
     18//usage:     "\n    -p  Preserve date"
     19//usage:     "\n    -o USER Set ownership"
     20//usage:     "\n    -g GRP  Set group ownership"
     21//usage:     "\n    -m MODE Set permissions"
     22//usage:    IF_SELINUX(
     23//usage:     "\n    -Z  Set security context"
     24//usage:    )
    825
    926#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/ln.c

    r2725 r3232  
    1212/* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
    1313
     14//usage:#define ln_trivial_usage
     15//usage:       "[OPTIONS] TARGET... LINK|DIR"
     16//usage:#define ln_full_usage "\n\n"
     17//usage:       "Create a link LINK or DIR/TARGET to the specified TARGET(s)\n"
     18//usage:     "\n    -s  Make symlinks instead of hardlinks"
     19//usage:     "\n    -f  Remove existing destinations"
     20//usage:     "\n    -n  Don't dereference symlinks - treat like normal file"
     21//usage:     "\n    -b  Make a backup of the target (if exists) before link operation"
     22//usage:     "\n    -S suf  Use suffix instead of ~ when making backup files"
     23//usage:     "\n    -T  2nd arg must be a DIR"
     24//usage:     "\n    -v  Verbose"
     25//usage:
     26//usage:#define ln_example_usage
     27//usage:       "$ ln -s BusyBox /tmp/ls\n"
     28//usage:       "$ ls -l /tmp/ls\n"
     29//usage:       "lrwxrwxrwx    1 root     root            7 Apr 12 18:39 ls -> BusyBox*\n"
     30
    1431#include "libbb.h"
    1532
     
    1734
    1835
    19 #define LN_SYMLINK          1
    20 #define LN_FORCE            2
    21 #define LN_NODEREFERENCE    4
    22 #define LN_BACKUP           8
    23 #define LN_SUFFIX           16
     36#define LN_SYMLINK          (1 << 0)
     37#define LN_FORCE            (1 << 1)
     38#define LN_NODEREFERENCE    (1 << 2)
     39#define LN_BACKUP           (1 << 3)
     40#define LN_SUFFIX           (1 << 4)
     41#define LN_VERBOSE          (1 << 5)
     42#define LN_LINKFILE         (1 << 6)
    2443
    2544int ln_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     
    3655
    3756    opt_complementary = "-1"; /* min one arg */
    38     opts = getopt32(argv, "sfnbS:", &suffix);
     57    opts = getopt32(argv, "sfnbS:vT", &suffix);
    3958
    4059    last = argv[argc - 1];
    4160    argv += optind;
     61    argc -= optind;
    4262
    43     if (argc == optind + 1) {
     63    if ((opts & LN_LINKFILE) && argc > 2) {
     64        bb_error_msg_and_die("-T accepts 2 args max");
     65    }
     66
     67    if (!argv[1]) {
     68        /* "ln PATH/TO/FILE" -> "ln PATH/TO/FILE FILE" */
    4469        *--argv = last;
     70        /* xstrdup is needed: "ln -s PATH/TO/FILE/" is equivalent to
     71         * "ln -s PATH/TO/FILE/ FILE", not "ln -s PATH/TO/FILE FILE"
     72         */
    4573        last = bb_get_last_path_component_strip(xstrdup(last));
    4674    }
     
    5179
    5280        if (is_directory(src,
    53                         (opts & LN_NODEREFERENCE) ^ LN_NODEREFERENCE,
    54                         NULL)
     81                        (opts & LN_NODEREFERENCE) ^ LN_NODEREFERENCE
     82                        )
    5583        ) {
     84            if (opts & LN_LINKFILE) {
     85                bb_error_msg_and_die("'%s' is a directory", src);
     86            }
    5687            src_name = xstrdup(*argv);
    5788            src = concat_path_file(src, bb_get_last_path_component_strip(src_name));
     
    94125        }
    95126
     127        if (opts & LN_VERBOSE) {
     128            printf("'%s' -> '%s'\n", src, *argv);
     129        }
     130
    96131        if (link_func(*argv, src) != 0) {
    97132            bb_simple_perror_msg(src);
  • branches/3.2/mindi-busybox/coreutils/logname.c

    r2725 r3232  
    2121 */
    2222
     23//usage:#define logname_trivial_usage
     24//usage:       ""
     25//usage:#define logname_full_usage "\n\n"
     26//usage:       "Print the name of the current user"
     27//usage:
     28//usage:#define logname_example_usage
     29//usage:       "$ logname\n"
     30//usage:       "root\n"
     31
    2332#include "libbb.h"
    2433
  • branches/3.2/mindi-busybox/coreutils/ls.c

    r2725 r3232  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * tiny-ls.c version 0.1.0: A minimalist 'ls'
    43 * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com>
    54 *
     
    3029 * ls sorts listing now, and supports almost all options.
    3130 */
     31
     32//usage:#define ls_trivial_usage
     33//usage:    "[-1AaCxd"
     34//usage:    IF_FEATURE_LS_FOLLOWLINKS("LH")
     35//usage:    IF_FEATURE_LS_RECURSIVE("R")
     36//usage:    IF_FEATURE_LS_FILETYPES("Fp") "lins"
     37//usage:    IF_FEATURE_LS_TIMESTAMPS("e")
     38//usage:    IF_FEATURE_HUMAN_READABLE("h")
     39//usage:    IF_FEATURE_LS_SORTFILES("rSXv")
     40//usage:    IF_FEATURE_LS_TIMESTAMPS("ctu")
     41//usage:    IF_SELINUX("kKZ") "]"
     42//usage:    IF_FEATURE_AUTOWIDTH(" [-w WIDTH]") " [FILE]..."
     43//usage:#define ls_full_usage "\n\n"
     44//usage:       "List directory contents\n"
     45//usage:     "\n    -1  One column output"
     46//usage:     "\n    -a  Include entries which start with ."
     47//usage:     "\n    -A  Like -a, but exclude . and .."
     48//usage:     "\n    -C  List by columns"
     49//usage:     "\n    -x  List by lines"
     50//usage:     "\n    -d  List directory entries instead of contents"
     51//usage:    IF_FEATURE_LS_FOLLOWLINKS(
     52//usage:     "\n    -L  Follow symlinks"
     53//usage:     "\n    -H  Follow symlinks on command line"
     54//usage:    )
     55//usage:    IF_FEATURE_LS_RECURSIVE(
     56//usage:     "\n    -R  Recurse"
     57//usage:    )
     58//usage:    IF_FEATURE_LS_FILETYPES(
     59//usage:     "\n    -p  Append / to dir entries"
     60//usage:     "\n    -F  Append indicator (one of */=@|) to entries"
     61//usage:    )
     62//usage:     "\n    -l  Long listing format"
     63//usage:     "\n    -i  List inode numbers"
     64//usage:     "\n    -n  List numeric UIDs and GIDs instead of names"
     65//usage:     "\n    -s  List allocated blocks"
     66//usage:    IF_FEATURE_LS_TIMESTAMPS(
     67//usage:     "\n    -e  List full date and time"
     68//usage:    )
     69//usage:    IF_FEATURE_HUMAN_READABLE(
     70//usage:     "\n    -h  List sizes in human readable format (1K 243M 2G)"
     71//usage:    )
     72//usage:    IF_FEATURE_LS_SORTFILES(
     73//usage:     "\n    -r  Sort in reverse order"
     74//usage:     "\n    -S  Sort by size"
     75//usage:     "\n    -X  Sort by extension"
     76//usage:     "\n    -v  Sort by version"
     77//usage:    )
     78//usage:    IF_FEATURE_LS_TIMESTAMPS(
     79//usage:     "\n    -c  With -l: sort by ctime"
     80//usage:     "\n    -t  With -l: sort by mtime"
     81//usage:     "\n    -u  With -l: sort by atime"
     82//usage:    )
     83//usage:    IF_SELINUX(
     84//usage:     "\n    -k  List security context"
     85//usage:     "\n    -K  List security context in long format"
     86//usage:     "\n    -Z  List security context and permission"
     87//usage:    )
     88//usage:    IF_FEATURE_AUTOWIDTH(
     89//usage:     "\n    -w N    Assume the terminal is N columns wide"
     90//usage:    )
     91//usage:    IF_FEATURE_LS_COLOR(
     92//usage:     "\n    --color[={always,never,auto}]   Control coloring"
     93//usage:    )
     94
    3295#include "libbb.h"
    3396#include "unicode.h"
     
    54117enum {
    55118TERMINAL_WIDTH  = 80,           /* use 79 if terminal has linefold bug */
    56 COLUMN_GAP      = 2,            /* includes the file type char */
    57 
    58 /* what is the overall style of the listing */
    59 STYLE_COLUMNS   = 1 << 21,      /* fill columns */
    60 STYLE_LONG      = 2 << 21,      /* one record per line, extended info */
    61 STYLE_SINGLE    = 3 << 21,      /* one record per line */
    62 STYLE_MASK      = STYLE_SINGLE,
     119
     120SPLIT_FILE      = 0,
     121SPLIT_DIR       = 1,
     122SPLIT_SUBDIR    = 2,
     123
     124/* Bits in G.all_fmt: */
    63125
    64126/* 51306 lrwxrwxrwx  1 root     root         2 May 11 01:43 /bin/view -> vi* */
     
    72134LIST_CONTEXT    = 1 << 6,
    73135LIST_SIZE       = 1 << 7,
    74 //LIST_DEV        = 1 << 8, - unused, synonym to LIST_SIZE
    75 LIST_DATE_TIME  = 1 << 9,
    76 LIST_FULLTIME   = 1 << 10,
    77 LIST_FILENAME   = 1 << 11,
    78 LIST_SYMLINK    = 1 << 12,
    79 LIST_FILETYPE   = 1 << 13,
    80 LIST_EXEC       = 1 << 14,
    81 LIST_MASK       = (LIST_EXEC << 1) - 1,
     136LIST_DATE_TIME  = 1 << 8,
     137LIST_FULLTIME   = 1 << 9,
     138LIST_SYMLINK    = 1 << 10,
     139LIST_FILETYPE   = 1 << 11, /* show / suffix for dirs */
     140LIST_CLASSIFY   = 1 << 12, /* requires LIST_FILETYPE, also show *,|,@,= suffixes */
     141LIST_MASK       = (LIST_CLASSIFY << 1) - 1,
    82142
    83143/* what files will be displayed */
    84 DISP_DIRNAME    = 1 << 15,      /* 2 or more items? label directories */
    85 DISP_HIDDEN     = 1 << 16,      /* show filenames starting with . */
    86 DISP_DOT        = 1 << 17,      /* show . and .. */
    87 DISP_NOLIST     = 1 << 18,      /* show directory as itself, not contents */
    88 DISP_RECURSIVE  = 1 << 19,      /* show directory and everything below it */
    89 DISP_ROWS       = 1 << 20,      /* print across rows */
     144DISP_DIRNAME    = 1 << 13,      /* 2 or more items? label directories */
     145DISP_HIDDEN     = 1 << 14,      /* show filenames starting with . */
     146DISP_DOT        = 1 << 15,      /* show . and .. */
     147DISP_NOLIST     = 1 << 16,      /* show directory as itself, not contents */
     148DISP_RECURSIVE  = 1 << 17,      /* show directory and everything below it */
     149DISP_ROWS       = 1 << 18,      /* print across rows */
    90150DISP_MASK       = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1),
    91151
     152/* what is the overall style of the listing */
     153STYLE_COLUMNAR  = 1 << 19,      /* many records per line */
     154STYLE_LONG      = 2 << 19,      /* one record per line, extended info */
     155STYLE_SINGLE    = 3 << 19,      /* one record per line */
     156STYLE_MASK      = STYLE_SINGLE,
     157
     158/* which of the three times will be used */
     159TIME_CHANGE     = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
     160TIME_ACCESS     = (2 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
     161TIME_MASK       = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
     162
    92163/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
    93 SORT_FORWARD    = 0,            /* sort in reverse order */
    94 SORT_REVERSE    = 1 << 27,      /* sort in reverse order */
     164SORT_REVERSE    = 1 << 23,
    95165
    96166SORT_NAME       = 0,            /* sort by file name */
    97 SORT_SIZE       = 1 << 28,      /* sort by file size */
    98 SORT_ATIME      = 2 << 28,      /* sort by last access time */
    99 SORT_CTIME      = 3 << 28,      /* sort by last change time */
    100 SORT_MTIME      = 4 << 28,      /* sort by last modification time */
    101 SORT_VERSION    = 5 << 28,      /* sort by version */
    102 SORT_EXT        = 6 << 28,      /* sort by file name extension */
    103 SORT_DIR        = 7 << 28,      /* sort by file or directory */
    104 SORT_MASK       = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES,
    105 
    106 /* which of the three times will be used */
    107 TIME_CHANGE     = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
    108 TIME_ACCESS     = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS,
    109 TIME_MASK       = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
    110 
    111 FOLLOW_LINKS    = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS,
    112 
    113 LS_DISP_HR      = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE,
    114 
    115 LIST_SHORT      = LIST_FILENAME,
     167SORT_SIZE       = 1 << 24,      /* sort by file size */
     168SORT_ATIME      = 2 << 24,      /* sort by last access time */
     169SORT_CTIME      = 3 << 24,      /* sort by last change time */
     170SORT_MTIME      = 4 << 24,      /* sort by last modification time */
     171SORT_VERSION    = 5 << 24,      /* sort by version */
     172SORT_EXT        = 6 << 24,      /* sort by file name extension */
     173SORT_DIR        = 7 << 24,      /* sort by file or directory */
     174SORT_MASK       = (7 << 24) * ENABLE_FEATURE_LS_SORTFILES,
     175
    116176LIST_LONG       = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
    117                   LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK,
    118 
    119 SPLIT_DIR       = 1,
    120 SPLIT_FILE      = 0,
    121 SPLIT_SUBDIR    = 2,
     177                  LIST_DATE_TIME | LIST_SYMLINK,
    122178};
    123179
    124 /* "[-]Cadil1", POSIX mandated options, busybox always supports */
    125 /* "[-]gnsx", POSIX non-mandated options, busybox always supports */
    126 /* "[-]Q" GNU option? busybox always supports */
    127 /* "[-]Ak" GNU options, busybox always supports */
    128 /* "[-]FLRctur", POSIX mandated options, busybox optionally supports */
    129 /* "[-]p", POSIX non-mandated options, busybox optionally supports */
    130 /* "[-]SXvThw", GNU options, busybox optionally supports */
    131 /* "[-]K", SELinux mandated options, busybox optionally supports */
    132 /* "[-]e", I think we made this one up */
     180/* -Cadil1  Std options, busybox always supports */
     181/* -gnsxA   Std options, busybox always supports */
     182/* -Q       GNU option, busybox always supports */
     183/* -k       SELinux option, busybox always supports (ignores if !SELinux) */
     184/*          Std has -k which means "show sizes in kbytes" */
     185/* -LHRctur Std options, busybox optionally supports */
     186/* -Fp      Std options, busybox optionally supports */
     187/* -SXvhTw  GNU options, busybox optionally supports */
     188/* -T WIDTH Ignored (we don't use tabs on output) */
     189/* -KZ      SELinux mandated options, busybox optionally supports */
     190/*          (coreutils 8.4 has no -K, remove it?) */
     191/* -e       I think we made this one up (looks similar to GNU --full-time) */
     192/* We already used up all 32 bits, if we need to add more, candidates for removal: */
     193/* -K, -T, -e (add --full-time instead) */
    133194static const char ls_options[] ALIGN1 =
    134     "Cadil1gnsxQAk" /* 13 opts, total 13 */
     195    "Cadil1gnsxQAk"      /* 13 opts, total 13 */
    135196    IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */
    136197    IF_FEATURE_LS_SORTFILES("SXrv")  /* 4, 21 */
    137198    IF_FEATURE_LS_FILETYPES("Fp")    /* 2, 23 */
    138     IF_FEATURE_LS_FOLLOWLINKS("L")   /* 1, 24 */
    139     IF_FEATURE_LS_RECURSIVE("R")     /* 1, 25 */
    140     IF_FEATURE_HUMAN_READABLE("h")   /* 1, 26 */
    141     IF_SELINUX("KZ") /* 2, 28 */
    142     IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 30 */
    143     ;
     199    IF_FEATURE_LS_RECURSIVE("R")     /* 1, 24 */
     200    IF_SELINUX("KZ")                 /* 2, 26 */
     201    IF_FEATURE_LS_FOLLOWLINKS("LH")  /* 2, 28 */
     202    IF_FEATURE_HUMAN_READABLE("h")   /* 1, 29 */
     203    IF_FEATURE_AUTOWIDTH("T:w:")     /* 2, 31 */
     204    /* with --color, we use all 32 bits */;
    144205enum {
    145206    //OPT_C = (1 << 0),
     
    156217    //OPT_A = (1 << 11),
    157218    //OPT_k = (1 << 12),
    158     OPTBIT_color = 13
    159         + 4 * ENABLE_FEATURE_LS_TIMESTAMPS
    160         + 4 * ENABLE_FEATURE_LS_SORTFILES
    161         + 2 * ENABLE_FEATURE_LS_FILETYPES
    162         + 1 * ENABLE_FEATURE_LS_FOLLOWLINKS
    163         + 1 * ENABLE_FEATURE_LS_RECURSIVE
    164         + 1 * ENABLE_FEATURE_HUMAN_READABLE
    165         + 2 * ENABLE_SELINUX
    166         + 2 * ENABLE_FEATURE_AUTOWIDTH,
    167     OPT_color = 1 << OPTBIT_color,
     219
     220    OPTBIT_c = 13,
     221    OPTBIT_e,
     222    OPTBIT_t,
     223    OPTBIT_u,
     224    OPTBIT_S = OPTBIT_c + 4 * ENABLE_FEATURE_LS_TIMESTAMPS,
     225    OPTBIT_X, /* 18 */
     226    OPTBIT_r,
     227    OPTBIT_v,
     228    OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES,
     229    OPTBIT_p, /* 22 */
     230    OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES,
     231    OPTBIT_K = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE,
     232    OPTBIT_Z, /* 25 */
     233    OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX,
     234    OPTBIT_H, /* 27 */
     235    OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS,
     236    OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE,
     237    OPTBIT_w, /* 30 */
     238    OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH,
     239
     240    OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS,
     241    OPT_e = (1 << OPTBIT_e) * ENABLE_FEATURE_LS_TIMESTAMPS,
     242    OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS,
     243    OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS,
     244    OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES,
     245    OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES,
     246    OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES,
     247    OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES,
     248    OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES,
     249    OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES,
     250    OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE,
     251    OPT_K = (1 << OPTBIT_K) * ENABLE_SELINUX,
     252    OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX,
     253    OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS,
     254    OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS,
     255    OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE,
     256    OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_AUTOWIDTH,
     257    OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_AUTOWIDTH,
     258    OPT_color = (1 << OPTBIT_color) * ENABLE_FEATURE_LS_COLOR,
    168259};
    169260
    170 enum {
    171     LIST_MASK_TRIGGER   = 0,
    172     STYLE_MASK_TRIGGER  = STYLE_MASK,
    173     DISP_MASK_TRIGGER   = DISP_ROWS,
    174     SORT_MASK_TRIGGER   = SORT_MASK,
     261/* TODO: simple toggles may be stored as OPT_xxx bits instead */
     262static const uint32_t opt_flags[] = {
     263    STYLE_COLUMNAR,              /* C */
     264    DISP_HIDDEN | DISP_DOT,      /* a */
     265    DISP_NOLIST,                 /* d */
     266    LIST_INO,                    /* i */
     267    LIST_LONG | STYLE_LONG,      /* l */
     268    STYLE_SINGLE,                /* 1 */
     269    LIST_LONG | STYLE_LONG,      /* g (don't show owner) - handled via OPT_g. assumes l */
     270    LIST_ID_NUMERIC | LIST_LONG | STYLE_LONG, /* n (assumes l) */
     271    LIST_BLOCKS,                 /* s */
     272    DISP_ROWS | STYLE_COLUMNAR,  /* x */
     273    0,                           /* Q (quote filename) - handled via OPT_Q */
     274    DISP_HIDDEN,                 /* A */
     275    ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */
     276#if ENABLE_FEATURE_LS_TIMESTAMPS
     277    TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
     278    LIST_FULLTIME,               /* e */
     279    ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */
     280    TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */
     281#endif
     282#if ENABLE_FEATURE_LS_SORTFILES
     283    SORT_SIZE,                   /* S */
     284    SORT_EXT,                    /* X */
     285    SORT_REVERSE,                /* r */
     286    SORT_VERSION,                /* v */
     287#endif
     288#if ENABLE_FEATURE_LS_FILETYPES
     289    LIST_FILETYPE | LIST_CLASSIFY, /* F */
     290    LIST_FILETYPE,               /* p */
     291#endif
     292#if ENABLE_FEATURE_LS_RECURSIVE
     293    DISP_RECURSIVE,              /* R */
     294#endif
     295#if ENABLE_SELINUX
     296    LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */
     297    LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */
     298#endif
     299    (1U << 31)
     300    /* options after Z are not processed through opt_flags */
    175301};
    176302
    177 /* TODO: simple toggles may be stored as OPT_xxx bits instead */
    178 static const unsigned opt_flags[] = {
    179     LIST_SHORT | STYLE_COLUMNS, /* C */
    180     DISP_HIDDEN | DISP_DOT,     /* a */
    181     DISP_NOLIST,                /* d */
    182     LIST_INO,                   /* i */
    183     LIST_LONG | STYLE_LONG,     /* l - remember LS_DISP_HR in mask! */
    184     LIST_SHORT | STYLE_SINGLE,  /* 1 */
    185     0,                          /* g (don't show owner) - handled via OPT_g */
    186     LIST_ID_NUMERIC,            /* n */
    187     LIST_BLOCKS,                /* s */
    188     DISP_ROWS,                  /* x */
    189     0,                          /* Q (quote filename) - handled via OPT_Q */
    190     DISP_HIDDEN,                /* A */
    191     ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */
    192 #if ENABLE_FEATURE_LS_TIMESTAMPS
    193     TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME),   /* c */
    194     LIST_FULLTIME,              /* e */
    195     ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME,   /* t */
    196     TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME),   /* u */
    197 #endif
    198 #if ENABLE_FEATURE_LS_SORTFILES
    199     SORT_SIZE,                  /* S */
    200     SORT_EXT,                   /* X */
    201     SORT_REVERSE,               /* r */
    202     SORT_VERSION,               /* v */
    203 #endif
    204 #if ENABLE_FEATURE_LS_FILETYPES
    205     LIST_FILETYPE | LIST_EXEC,  /* F */
    206     LIST_FILETYPE,              /* p */
    207 #endif
    208 #if ENABLE_FEATURE_LS_FOLLOWLINKS
    209     FOLLOW_LINKS,               /* L */
    210 #endif
    211 #if ENABLE_FEATURE_LS_RECURSIVE
    212     DISP_RECURSIVE,             /* R */
    213 #endif
    214 #if ENABLE_FEATURE_HUMAN_READABLE
    215     LS_DISP_HR,                 /* h */
    216 #endif
    217 #if ENABLE_SELINUX
    218     LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */
    219 #endif
    220 #if ENABLE_SELINUX
    221     LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */
    222 #endif
    223     (1U<<31)
    224     /* options after Z are not processed through opt_flags:
    225      * T, w - ignored
    226      */
    227 };
    228 
    229303
    230304/*
    231  * a directory entry and its stat info are stored here
     305 * a directory entry and its stat info
    232306 */
    233307struct dnode {
    234     const char *name;       /* the dir entry name */
    235     const char *fullname;   /* the dir entry name */
    236     struct dnode *next;     /* point at the next node */
     308    const char *name;       /* usually basename, but think "ls -l dir/file" */
     309    const char *fullname;   /* full name (usable for stat etc) */
     310    struct dnode *dn_next;  /* for linked list */
     311    IF_SELINUX(security_context_t sid;)
    237312    smallint fname_allocated;
    238     struct stat dstat;      /* the file stat info */
    239     IF_SELINUX(security_context_t sid;)
     313
     314    /* Used to avoid re-doing [l]stat at printout stage
     315     * if we already collected needed data in scan stage:
     316     */
     317    mode_t    dn_mode_lstat;   /* obtained with lstat, or 0 */
     318    mode_t    dn_mode_stat;    /* obtained with stat, or 0 */
     319
     320//  struct stat dstat;
     321// struct stat is huge. We don't need it in full.
     322// At least we don't need st_dev and st_blksize,
     323// but there are invisible fields as well
     324// (such as nanosecond-resolution timespamps)
     325// and padding, which we also don't want to store.
     326// We also can pre-parse dev_t dn_rdev (in glibc, it's huge).
     327// On 32-bit uclibc: dnode size went from 112 to 84 bytes.
     328//
     329    /* Same names as in struct stat, but with dn_ instead of st_ pfx: */
     330    mode_t    dn_mode; /* obtained with lstat OR stat, depending on -L etc */
     331    off_t     dn_size;
     332#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
     333    time_t    dn_atime;
     334    time_t    dn_mtime;
     335    time_t    dn_ctime;
     336#endif
     337    ino_t     dn_ino;
     338    blkcnt_t  dn_blocks;
     339    nlink_t   dn_nlink;
     340    uid_t     dn_uid;
     341    gid_t     dn_gid;
     342    int       dn_rdev_maj;
     343    int       dn_rdev_min;
     344//  dev_t     dn_dev;
     345//  blksize_t dn_blksize;
    240346};
    241347
     
    243349#if ENABLE_FEATURE_LS_COLOR
    244350    smallint show_color;
     351# define G_show_color (G.show_color)
     352#else
     353# define G_show_color 0
    245354#endif
    246355    smallint exit_code;
    247356    unsigned all_fmt;
    248357#if ENABLE_FEATURE_AUTOWIDTH
    249     unsigned tabstops; // = COLUMN_GAP;
    250     unsigned terminal_width; // = TERMINAL_WIDTH;
     358    unsigned terminal_width;
     359# define G_terminal_width (G.terminal_width)
     360#else
     361# define G_terminal_width TERMINAL_WIDTH
    251362#endif
    252363#if ENABLE_FEATURE_LS_TIMESTAMPS
     
    256367} FIX_ALIASING;
    257368#define G (*(struct globals*)&bb_common_bufsiz1)
    258 #if ENABLE_FEATURE_LS_COLOR
    259 # define show_color     (G.show_color    )
    260 #else
    261 enum { show_color = 0 };
    262 #endif
    263 #define exit_code       (G.exit_code     )
    264 #define all_fmt         (G.all_fmt       )
    265 #if ENABLE_FEATURE_AUTOWIDTH
    266 # define tabstops       (G.tabstops      )
    267 # define terminal_width (G.terminal_width)
    268 #else
    269 enum {
    270     tabstops = COLUMN_GAP,
    271     terminal_width = TERMINAL_WIDTH,
    272 };
    273 #endif
    274 #define current_time_t (G.current_time_t)
    275369#define INIT_G() do { \
    276370    /* we have to zero it out because of NOEXEC */ \
    277371    memset(&G, 0, sizeof(G)); \
    278     IF_FEATURE_AUTOWIDTH(tabstops = COLUMN_GAP;) \
    279     IF_FEATURE_AUTOWIDTH(terminal_width = TERMINAL_WIDTH;) \
    280     IF_FEATURE_LS_TIMESTAMPS(time(&current_time_t);) \
     372    IF_FEATURE_AUTOWIDTH(G_terminal_width = TERMINAL_WIDTH;) \
     373    IF_FEATURE_LS_TIMESTAMPS(time(&G.current_time_t);) \
    281374} while (0)
    282375
    283376
    284 static struct dnode *my_stat(const char *fullname, const char *name, int force_follow)
    285 {
    286     struct stat dstat;
    287     struct dnode *cur;
    288     IF_SELINUX(security_context_t sid = NULL;)
    289 
    290     if ((all_fmt & FOLLOW_LINKS) || force_follow) {
    291 #if ENABLE_SELINUX
    292         if (is_selinux_enabled())  {
    293              getfilecon(fullname, &sid);
    294         }
    295 #endif
    296         if (stat(fullname, &dstat)) {
    297             bb_simple_perror_msg(fullname);
    298             exit_code = EXIT_FAILURE;
    299             return 0;
    300         }
    301     } else {
    302 #if ENABLE_SELINUX
    303         if (is_selinux_enabled()) {
    304             lgetfilecon(fullname, &sid);
    305         }
    306 #endif
    307         if (lstat(fullname, &dstat)) {
    308             bb_simple_perror_msg(fullname);
    309             exit_code = EXIT_FAILURE;
    310             return 0;
    311         }
    312     }
    313 
    314     cur = xmalloc(sizeof(*cur));
    315     cur->fullname = fullname;
    316     cur->name = name;
    317     cur->dstat = dstat;
    318     IF_SELINUX(cur->sid = sid;)
    319     return cur;
    320 }
     377/*** Output code ***/
     378
    321379
    322380/* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket
     
    325383 * and we use 0 for unknown and 15 for executables (see below) */
    326384#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
    327 #define TYPECHAR(mode)  ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
    328 #define APPCHAR(mode)   ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
     385/*                       un  fi chr -   dir -  blk  -  file -  link - sock -   - exe */
     386#define APPCHAR(mode)   ("\0""|""\0""\0""/""\0""\0""\0""\0""\0""@""\0""=""\0""\0""\0" [TYPEINDEX(mode)])
    329387/* 036 black foreground              050 black background
    330388   037 red foreground                051 red background
     
    337395*/
    338396#define COLOR(mode) ( \
    339     /*un  fi  chr     dir     blk     file    link    sock        exe */ \
     397    /*un  fi  chr  -  dir  -  blk  -  file -  link -  sock -   -  exe */ \
    340398    "\037\043\043\045\042\045\043\043\000\045\044\045\043\045\045\040" \
    341399    [TYPEINDEX(mode)])
     
    346404 */
    347405#define ATTR(mode) ( \
    348     /*un fi chr   dir   blk   file  link  sock     exe */ \
     406    /*un fi chr - dir - blk - file- link- sock- -  exe */ \
    349407    "\01\00\01\07\01\07\01\07\00\07\01\07\01\07\07\01" \
    350408    [TYPEINDEX(mode)])
     
    366424#endif
    367425
    368 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
     426#if ENABLE_FEATURE_LS_FILETYPES
    369427static char append_char(mode_t mode)
    370428{
    371     if (!(all_fmt & LIST_FILETYPE))
     429    if (!(G.all_fmt & LIST_FILETYPE))
    372430        return '\0';
    373431    if (S_ISDIR(mode))
    374432        return '/';
    375     if (!(all_fmt & LIST_EXEC))
     433    if (!(G.all_fmt & LIST_CLASSIFY))
    376434        return '\0';
    377435    if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
     
    381439#endif
    382440
    383 static unsigned count_dirs(struct dnode **dn, int which)
    384 {
    385     unsigned dirs, all;
    386 
    387     if (!dn)
    388         return 0;
    389 
    390     dirs = all = 0;
    391     for (; *dn; dn++) {
    392         const char *name;
    393 
    394         all++;
    395         if (!S_ISDIR((*dn)->dstat.st_mode))
    396             continue;
    397         name = (*dn)->name;
    398         if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */
    399          /* or if it's not . or .. */
    400          || name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))
    401         ) {
    402             dirs++;
    403         }
    404     }
    405     return which != SPLIT_FILE ? dirs : all - dirs;
    406 }
    407 
    408 /* get memory to hold an array of pointers */
    409 static struct dnode **dnalloc(unsigned num)
    410 {
    411     if (num < 1)
    412         return NULL;
    413 
    414     num++; /* so that we have terminating NULL */
    415     return xzalloc(num * sizeof(struct dnode *));
    416 }
    417 
    418 #if ENABLE_FEATURE_LS_RECURSIVE
    419 static void dfree(struct dnode **dnp)
    420 {
    421     unsigned i;
    422 
    423     if (dnp == NULL)
    424         return;
    425 
    426     for (i = 0; dnp[i]; i++) {
    427         struct dnode *cur = dnp[i];
    428         if (cur->fname_allocated)
    429             free((char*)cur->fullname);
    430         free(cur);
    431     }
    432     free(dnp);
    433 }
    434 #else
    435 #define dfree(...) ((void)0)
    436 #endif
    437 
    438 /* Returns NULL-terminated malloced vector of pointers (or NULL) */
    439 static struct dnode **splitdnarray(struct dnode **dn, int which)
    440 {
    441     unsigned dncnt, d;
    442     struct dnode **dnp;
    443 
    444     if (dn == NULL)
    445         return NULL;
    446 
    447     /* count how many dirs or files there are */
    448     dncnt = count_dirs(dn, which);
    449 
    450     /* allocate a file array and a dir array */
    451     dnp = dnalloc(dncnt);
    452 
    453     /* copy the entrys into the file or dir array */
    454     for (d = 0; *dn; dn++) {
    455         if (S_ISDIR((*dn)->dstat.st_mode)) {
    456             const char *name;
    457 
    458             if (!(which & (SPLIT_DIR|SPLIT_SUBDIR)))
    459                 continue;
    460             name = (*dn)->name;
    461             if ((which & SPLIT_DIR)
    462              || name[0]!='.' || (name[1] && (name[1]!='.' || name[2]))
    463             ) {
    464                 dnp[d++] = *dn;
    465             }
    466         } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) {
    467             dnp[d++] = *dn;
    468         }
    469     }
    470     return dnp;
    471 }
    472 
    473 #if ENABLE_FEATURE_LS_SORTFILES
    474 static int sortcmp(const void *a, const void *b)
    475 {
    476     struct dnode *d1 = *(struct dnode **)a;
    477     struct dnode *d2 = *(struct dnode **)b;
    478     unsigned sort_opts = all_fmt & SORT_MASK;
    479     off_t dif;
    480 
    481     dif = 0; /* assume SORT_NAME */
    482     // TODO: use pre-initialized function pointer
    483     // instead of branch forest
    484     if (sort_opts == SORT_SIZE) {
    485         dif = (d2->dstat.st_size - d1->dstat.st_size);
    486     } else if (sort_opts == SORT_ATIME) {
    487         dif = (d2->dstat.st_atime - d1->dstat.st_atime);
    488     } else if (sort_opts == SORT_CTIME) {
    489         dif = (d2->dstat.st_ctime - d1->dstat.st_ctime);
    490     } else if (sort_opts == SORT_MTIME) {
    491         dif = (d2->dstat.st_mtime - d1->dstat.st_mtime);
    492     } else if (sort_opts == SORT_DIR) {
    493         dif = S_ISDIR(d2->dstat.st_mode) - S_ISDIR(d1->dstat.st_mode);
    494         /* } else if (sort_opts == SORT_VERSION) { */
    495         /* } else if (sort_opts == SORT_EXT) { */
    496     }
    497     if (dif == 0) {
    498         /* sort by name, or tie_breaker for other sorts */
    499         if (ENABLE_LOCALE_SUPPORT)
    500             dif = strcoll(d1->name, d2->name);
    501         else
    502             dif = strcmp(d1->name, d2->name);
    503     }
    504 
    505     /* Make dif fit into an int */
    506     if (sizeof(dif) > sizeof(int)) {
    507         enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) };
    508         /* shift leaving only "int" worth of bits */
    509         if (dif != 0) {
    510             dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT);
    511         }
    512     }
    513 
    514     return (all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif;
    515 }
    516 
    517 static void dnsort(struct dnode **dn, int size)
    518 {
    519     qsort(dn, size, sizeof(*dn), sortcmp);
    520 }
    521 #else
    522 #define dnsort(dn, size) ((void)0)
    523 #endif
    524 
    525 
    526441static unsigned calc_name_len(const char *name)
    527442{
     
    546461}
    547462
    548 
    549463/* Return the number of used columns.
    550  * Note that only STYLE_COLUMNS uses return value.
     464 * Note that only STYLE_COLUMNAR uses return value.
    551465 * STYLE_SINGLE and STYLE_LONG don't care.
    552466 * coreutils 7.2 also supports:
     
    582496
    583497/* Return the number of used columns.
    584  * Note that only STYLE_COLUMNS uses return value,
     498 * Note that only STYLE_COLUMNAR uses return value,
    585499 * STYLE_SINGLE and STYLE_LONG don't care.
    586500 */
    587 static NOINLINE unsigned list_single(const struct dnode *dn)
     501static NOINLINE unsigned display_single(const struct dnode *dn)
    588502{
    589503    unsigned column = 0;
    590     char *lpath = lpath; /* for compiler */
     504    char *lpath;
    591505#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
    592     struct stat info;
     506    struct stat statbuf;
    593507    char append;
    594508#endif
    595509
    596     /* Never happens:
    597     if (dn->fullname == NULL)
    598         return 0;
    599     */
    600 
    601510#if ENABLE_FEATURE_LS_FILETYPES
    602     append = append_char(dn->dstat.st_mode);
     511    append = append_char(dn->dn_mode);
    603512#endif
    604513
    605514    /* Do readlink early, so that if it fails, error message
    606515     * does not appear *inside* the "ls -l" line */
    607     if (all_fmt & LIST_SYMLINK)
    608         if (S_ISLNK(dn->dstat.st_mode))
     516    lpath = NULL;
     517    if (G.all_fmt & LIST_SYMLINK)
     518        if (S_ISLNK(dn->dn_mode))
    609519            lpath = xmalloc_readlink_or_warn(dn->fullname);
    610520
    611     if (all_fmt & LIST_INO)
    612         column += printf("%7llu ", (long long) dn->dstat.st_ino);
    613     if (all_fmt & LIST_BLOCKS)
    614         column += printf("%4"OFF_FMT"u ", (off_t) (dn->dstat.st_blocks >> 1));
    615     if (all_fmt & LIST_MODEBITS)
    616         column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode));
    617     if (all_fmt & LIST_NLINKS)
    618         column += printf("%4lu ", (long) dn->dstat.st_nlink);
     521    if (G.all_fmt & LIST_INO)
     522        column += printf("%7llu ", (long long) dn->dn_ino);
     523//TODO: -h should affect -s too:
     524    if (G.all_fmt & LIST_BLOCKS)
     525        column += printf("%6"OFF_FMT"u ", (off_t) (dn->dn_blocks >> 1));
     526    if (G.all_fmt & LIST_MODEBITS)
     527        column += printf("%-10s ", (char *) bb_mode_string(dn->dn_mode));
     528    if (G.all_fmt & LIST_NLINKS)
     529        column += printf("%4lu ", (long) dn->dn_nlink);
     530    if (G.all_fmt & LIST_ID_NUMERIC) {
     531        if (option_mask32 & OPT_g)
     532            column += printf("%-8u ", (int) dn->dn_gid);
     533        else
     534            column += printf("%-8u %-8u ",
     535                    (int) dn->dn_uid,
     536                    (int) dn->dn_gid);
     537    }
    619538#if ENABLE_FEATURE_LS_USERNAME
    620     if (all_fmt & LIST_ID_NAME) {
     539    else if (G.all_fmt & LIST_ID_NAME) {
    621540        if (option_mask32 & OPT_g) {
    622541            column += printf("%-8.8s ",
    623                 get_cached_groupname(dn->dstat.st_gid));
     542                get_cached_groupname(dn->dn_gid));
    624543        } else {
    625544            column += printf("%-8.8s %-8.8s ",
    626                 get_cached_username(dn->dstat.st_uid),
    627                 get_cached_groupname(dn->dstat.st_gid));
    628         }
    629     }
    630 #endif
    631     if (all_fmt & LIST_ID_NUMERIC) {
    632         if (option_mask32 & OPT_g)
    633             column += printf("%-8u ", (int) dn->dstat.st_gid);
    634         else
    635             column += printf("%-8u %-8u ",
    636                     (int) dn->dstat.st_uid,
    637                     (int) dn->dstat.st_gid);
    638     }
    639     if (all_fmt & (LIST_SIZE /*|LIST_DEV*/ )) {
    640         if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
     545                get_cached_username(dn->dn_uid),
     546                get_cached_groupname(dn->dn_gid));
     547        }
     548    }
     549#endif
     550    if (G.all_fmt & LIST_SIZE) {
     551        if (S_ISBLK(dn->dn_mode) || S_ISCHR(dn->dn_mode)) {
    641552            column += printf("%4u, %3u ",
    642                     (int) major(dn->dstat.st_rdev),
    643                     (int) minor(dn->dstat.st_rdev));
     553                    dn->dn_rdev_maj,
     554                    dn->dn_rdev_min);
    644555        } else {
    645             if (all_fmt & LS_DISP_HR) {
     556            if (option_mask32 & OPT_h) {
    646557                column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ",
    647                     /* print st_size, show one fractional, use suffixes */
    648                     make_human_readable_str(dn->dstat.st_size, 1, 0)
     558                    /* print size, show one fractional, use suffixes */
     559                    make_human_readable_str(dn->dn_size, 1, 0)
    649560                );
    650561            } else {
    651                 column += printf("%9"OFF_FMT"u ", (off_t) dn->dstat.st_size);
     562                column += printf("%9"OFF_FMT"u ", dn->dn_size);
    652563            }
    653564        }
    654565    }
    655566#if ENABLE_FEATURE_LS_TIMESTAMPS
    656     if (all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) {
     567    if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) {
    657568        char *filetime;
    658         time_t ttime = dn->dstat.st_mtime;
    659         if (all_fmt & TIME_ACCESS)
    660             ttime = dn->dstat.st_atime;
    661         if (all_fmt & TIME_CHANGE)
    662             ttime = dn->dstat.st_ctime;
     569        time_t ttime = dn->dn_mtime;
     570        if (G.all_fmt & TIME_ACCESS)
     571            ttime = dn->dn_atime;
     572        if (G.all_fmt & TIME_CHANGE)
     573            ttime = dn->dn_ctime;
    663574        filetime = ctime(&ttime);
    664575        /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */
    665         if (all_fmt & LIST_FULLTIME)
     576        if (G.all_fmt & LIST_FULLTIME) { /* -e */
     577            /* Note: coreutils 8.4 ls --full-time prints:
     578             * 2009-07-13 17:49:27.000000000 +0200
     579             */
    666580            column += printf("%.24s ", filetime);
    667         else { /* LIST_DATE_TIME */
    668             /* current_time_t ~== time(NULL) */
    669             time_t age = current_time_t - ttime;
     581        } else { /* LIST_DATE_TIME */
     582            /* G.current_time_t ~== time(NULL) */
     583            time_t age = G.current_time_t - ttime;
    670584            printf("%.6s ", filetime + 4); /* "Jun 30" */
    671585            if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) {
     
    680594#endif
    681595#if ENABLE_SELINUX
    682     if (all_fmt & LIST_CONTEXT) {
     596    if (G.all_fmt & LIST_CONTEXT) {
    683597        column += printf("%-32s ", dn->sid ? dn->sid : "unknown");
    684598        freecon(dn->sid);
    685599    }
    686600#endif
    687     if (all_fmt & LIST_FILENAME) {
     601
    688602#if ENABLE_FEATURE_LS_COLOR
    689         if (show_color) {
    690             info.st_mode = 0; /* for fgcolor() */
    691             lstat(dn->fullname, &info);
    692             printf("\033[%u;%um", bold(info.st_mode),
    693                     fgcolor(info.st_mode));
    694         }
    695 #endif
    696         column += print_name(dn->name);
    697         if (show_color) {
     603    if (G_show_color) {
     604        mode_t mode = dn->dn_mode_lstat;
     605        if (!mode)
     606            if (lstat(dn->fullname, &statbuf) == 0)
     607                mode = statbuf.st_mode;
     608        printf("\033[%u;%um", bold(mode), fgcolor(mode));
     609    }
     610#endif
     611    column += print_name(dn->name);
     612    if (G_show_color) {
     613        printf("\033[0m");
     614    }
     615
     616    if (lpath) {
     617        printf(" -> ");
     618#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
     619        if ((G.all_fmt & LIST_FILETYPE) || G_show_color) {
     620            mode_t mode = dn->dn_mode_stat;
     621            if (!mode)
     622                if (stat(dn->fullname, &statbuf) == 0)
     623                    mode = statbuf.st_mode;
     624# if ENABLE_FEATURE_LS_FILETYPES
     625            append = append_char(mode);
     626# endif
     627# if ENABLE_FEATURE_LS_COLOR
     628            if (G_show_color) {
     629                printf("\033[%u;%um", bold(mode), fgcolor(mode));
     630            }
     631# endif
     632        }
     633#endif
     634        column += print_name(lpath) + 4;
     635        free(lpath);
     636        if (G_show_color) {
    698637            printf("\033[0m");
    699638        }
    700639    }
    701     if (all_fmt & LIST_SYMLINK) {
    702         if (S_ISLNK(dn->dstat.st_mode) && lpath) {
    703             printf(" -> ");
    704 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
    705 #if ENABLE_FEATURE_LS_COLOR
    706             info.st_mode = 0; /* for fgcolor() */
    707 #endif
    708             if (stat(dn->fullname, &info) == 0) {
    709                 append = append_char(info.st_mode);
    710             }
    711 #endif
    712 #if ENABLE_FEATURE_LS_COLOR
    713             if (show_color) {
    714                 printf("\033[%u;%um", bold(info.st_mode),
    715                        fgcolor(info.st_mode));
    716             }
    717 #endif
    718             column += print_name(lpath) + 4;
    719             if (show_color) {
    720                 printf("\033[0m");
    721             }
    722             free(lpath);
    723         }
    724     }
    725640#if ENABLE_FEATURE_LS_FILETYPES
    726     if (all_fmt & LIST_FILETYPE) {
     641    if (G.all_fmt & LIST_FILETYPE) {
    727642        if (append) {
    728643            putchar(append);
     
    735650}
    736651
    737 static void showfiles(struct dnode **dn, unsigned nfiles)
     652static void display_files(struct dnode **dn, unsigned nfiles)
    738653{
    739654    unsigned i, ncols, nrows, row, nc;
    740     unsigned column = 0;
    741     unsigned nexttab = 0;
    742     unsigned column_width = 0; /* used only by STYLE_COLUMNS */
    743 
    744     if (all_fmt & STYLE_LONG) { /* STYLE_LONG or STYLE_SINGLE */
     655    unsigned column;
     656    unsigned nexttab;
     657    unsigned column_width = 0; /* used only by STYLE_COLUMNAR */
     658
     659    if (G.all_fmt & STYLE_LONG) { /* STYLE_LONG or STYLE_SINGLE */
    745660        ncols = 1;
    746661    } else {
     
    751666                column_width = len;
    752667        }
    753         column_width += tabstops +
    754             IF_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + )
    755                 ((all_fmt & LIST_INO) ? 8 : 0) +
    756                 ((all_fmt & LIST_BLOCKS) ? 5 : 0);
    757         ncols = (int) (terminal_width / column_width);
     668        column_width += 1 +
     669            IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + )
     670                ((G.all_fmt & LIST_INO) ? 8 : 0) +
     671                ((G.all_fmt & LIST_BLOCKS) ? 5 : 0);
     672        ncols = (unsigned)G_terminal_width / column_width;
    758673    }
    759674
     
    767682    }
    768683
     684    column = 0;
     685    nexttab = 0;
    769686    for (row = 0; row < nrows; row++) {
    770687        for (nc = 0; nc < ncols; nc++) {
    771688            /* reach into the array based on the column and row */
    772             if (all_fmt & DISP_ROWS)
     689            if (G.all_fmt & DISP_ROWS)
    773690                i = (row * ncols) + nc; /* display across row */
    774691            else
     
    777694                if (column > 0) {
    778695                    nexttab -= column;
    779                     printf("%*s", nexttab, "");
    780                     column += nexttab;
     696                    printf("%*s ", nexttab, "");
     697                    column += nexttab + 1;
    781698                }
    782699                nexttab = column + column_width;
    783                 column += list_single(dn[i]);
     700                column += display_single(dn[i]);
    784701            }
    785702        }
     
    789706}
    790707
     708
     709/*** Dir scanning code ***/
     710
     711static struct dnode *my_stat(const char *fullname, const char *name, int force_follow)
     712{
     713    struct stat statbuf;
     714    struct dnode *cur;
     715
     716    cur = xzalloc(sizeof(*cur));
     717    cur->fullname = fullname;
     718    cur->name = name;
     719
     720    if ((option_mask32 & OPT_L) || force_follow) {
     721#if ENABLE_SELINUX
     722        if (is_selinux_enabled())  {
     723            getfilecon(fullname, &cur->sid);
     724        }
     725#endif
     726        if (stat(fullname, &statbuf)) {
     727            bb_simple_perror_msg(fullname);
     728            G.exit_code = EXIT_FAILURE;
     729            free(cur);
     730            return NULL;
     731        }
     732        cur->dn_mode_stat = statbuf.st_mode;
     733    } else {
     734#if ENABLE_SELINUX
     735        if (is_selinux_enabled()) {
     736            lgetfilecon(fullname, &cur->sid);
     737        }
     738#endif
     739        if (lstat(fullname, &statbuf)) {
     740            bb_simple_perror_msg(fullname);
     741            G.exit_code = EXIT_FAILURE;
     742            free(cur);
     743            return NULL;
     744        }
     745        cur->dn_mode_lstat = statbuf.st_mode;
     746    }
     747
     748    /* cur->dstat = statbuf: */
     749    cur->dn_mode   = statbuf.st_mode  ;
     750    cur->dn_size   = statbuf.st_size  ;
     751#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
     752    cur->dn_atime  = statbuf.st_atime ;
     753    cur->dn_mtime  = statbuf.st_mtime ;
     754    cur->dn_ctime  = statbuf.st_ctime ;
     755#endif
     756    cur->dn_ino    = statbuf.st_ino   ;
     757    cur->dn_blocks = statbuf.st_blocks;
     758    cur->dn_nlink  = statbuf.st_nlink ;
     759    cur->dn_uid    = statbuf.st_uid   ;
     760    cur->dn_gid    = statbuf.st_gid   ;
     761    cur->dn_rdev_maj = major(statbuf.st_rdev);
     762    cur->dn_rdev_min = minor(statbuf.st_rdev);
     763
     764    return cur;
     765}
     766
     767static unsigned count_dirs(struct dnode **dn, int which)
     768{
     769    unsigned dirs, all;
     770
     771    if (!dn)
     772        return 0;
     773
     774    dirs = all = 0;
     775    for (; *dn; dn++) {
     776        const char *name;
     777
     778        all++;
     779        if (!S_ISDIR((*dn)->dn_mode))
     780            continue;
     781
     782        name = (*dn)->name;
     783        if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */
     784         /* or if it's not . or .. */
     785         || name[0] != '.'
     786         || (name[1] && (name[1] != '.' || name[2]))
     787        ) {
     788            dirs++;
     789        }
     790    }
     791    return which != SPLIT_FILE ? dirs : all - dirs;
     792}
     793
     794/* get memory to hold an array of pointers */
     795static struct dnode **dnalloc(unsigned num)
     796{
     797    if (num < 1)
     798        return NULL;
     799
     800    num++; /* so that we have terminating NULL */
     801    return xzalloc(num * sizeof(struct dnode *));
     802}
     803
     804#if ENABLE_FEATURE_LS_RECURSIVE
     805static void dfree(struct dnode **dnp)
     806{
     807    unsigned i;
     808
     809    if (dnp == NULL)
     810        return;
     811
     812    for (i = 0; dnp[i]; i++) {
     813        struct dnode *cur = dnp[i];
     814        if (cur->fname_allocated)
     815            free((char*)cur->fullname);
     816        free(cur);
     817    }
     818    free(dnp);
     819}
     820#else
     821#define dfree(...) ((void)0)
     822#endif
     823
     824/* Returns NULL-terminated malloced vector of pointers (or NULL) */
     825static struct dnode **splitdnarray(struct dnode **dn, int which)
     826{
     827    unsigned dncnt, d;
     828    struct dnode **dnp;
     829
     830    if (dn == NULL)
     831        return NULL;
     832
     833    /* count how many dirs or files there are */
     834    dncnt = count_dirs(dn, which);
     835
     836    /* allocate a file array and a dir array */
     837    dnp = dnalloc(dncnt);
     838
     839    /* copy the entrys into the file or dir array */
     840    for (d = 0; *dn; dn++) {
     841        if (S_ISDIR((*dn)->dn_mode)) {
     842            const char *name;
     843
     844            if (which == SPLIT_FILE)
     845                continue;
     846
     847            name = (*dn)->name;
     848            if ((which & SPLIT_DIR) /* any dir... */
     849            /* ... or not . or .. */
     850             || name[0] != '.'
     851             || (name[1] && (name[1] != '.' || name[2]))
     852            ) {
     853                dnp[d++] = *dn;
     854            }
     855        } else
     856        if (which == SPLIT_FILE) {
     857            dnp[d++] = *dn;
     858        }
     859    }
     860    return dnp;
     861}
     862
     863#if ENABLE_FEATURE_LS_SORTFILES
     864static int sortcmp(const void *a, const void *b)
     865{
     866    struct dnode *d1 = *(struct dnode **)a;
     867    struct dnode *d2 = *(struct dnode **)b;
     868    unsigned sort_opts = G.all_fmt & SORT_MASK;
     869    off_t dif;
     870
     871    dif = 0; /* assume SORT_NAME */
     872    // TODO: use pre-initialized function pointer
     873    // instead of branch forest
     874    if (sort_opts == SORT_SIZE) {
     875        dif = (d2->dn_size - d1->dn_size);
     876    } else
     877    if (sort_opts == SORT_ATIME) {
     878        dif = (d2->dn_atime - d1->dn_atime);
     879    } else
     880    if (sort_opts == SORT_CTIME) {
     881        dif = (d2->dn_ctime - d1->dn_ctime);
     882    } else
     883    if (sort_opts == SORT_MTIME) {
     884        dif = (d2->dn_mtime - d1->dn_mtime);
     885    } else
     886    if (sort_opts == SORT_DIR) {
     887        dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode);
     888    } else
     889#if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1
     890    if (sort_opts == SORT_VERSION) {
     891        dif = strverscmp(d1->name, d2->name);
     892    } else
     893#endif
     894    if (sort_opts == SORT_EXT) {
     895        dif = strcmp(strchrnul(d1->name, '.'), strchrnul(d2->name, '.'));
     896    }
     897    if (dif == 0) {
     898        /* sort by name, use as tie breaker for other sorts */
     899        if (ENABLE_LOCALE_SUPPORT)
     900            dif = strcoll(d1->name, d2->name);
     901        else
     902            dif = strcmp(d1->name, d2->name);
     903    }
     904
     905    /* Make dif fit into an int */
     906    if (sizeof(dif) > sizeof(int)) {
     907        enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) };
     908        /* shift leaving only "int" worth of bits */
     909        if (dif != 0) {
     910            dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT);
     911        }
     912    }
     913
     914    return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif;
     915}
     916
     917static void dnsort(struct dnode **dn, int size)
     918{
     919    qsort(dn, size, sizeof(*dn), sortcmp);
     920}
     921
     922static void sort_and_display_files(struct dnode **dn, unsigned nfiles)
     923{
     924    dnsort(dn, nfiles);
     925    display_files(dn, nfiles);
     926}
     927#else
     928# define dnsort(dn, size) ((void)0)
     929# define sort_and_display_files(dn, nfiles) display_files(dn, nfiles)
     930#endif
     931
     932/* Returns NULL-terminated malloced vector of pointers (or NULL) */
     933static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
     934{
     935    struct dnode *dn, *cur, **dnp;
     936    struct dirent *entry;
     937    DIR *dir;
     938    unsigned i, nfiles;
     939
     940    *nfiles_p = 0;
     941    dir = warn_opendir(path);
     942    if (dir == NULL) {
     943        G.exit_code = EXIT_FAILURE;
     944        return NULL;    /* could not open the dir */
     945    }
     946    dn = NULL;
     947    nfiles = 0;
     948    while ((entry = readdir(dir)) != NULL) {
     949        char *fullname;
     950
     951        /* are we going to list the file- it may be . or .. or a hidden file */
     952        if (entry->d_name[0] == '.') {
     953            if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2]))
     954             && !(G.all_fmt & DISP_DOT)
     955            ) {
     956                continue;
     957            }
     958            if (!(G.all_fmt & DISP_HIDDEN))
     959                continue;
     960        }
     961        fullname = concat_path_file(path, entry->d_name);
     962        cur = my_stat(fullname, bb_basename(fullname), 0);
     963        if (!cur) {
     964            free(fullname);
     965            continue;
     966        }
     967        cur->fname_allocated = 1;
     968        cur->dn_next = dn;
     969        dn = cur;
     970        nfiles++;
     971    }
     972    closedir(dir);
     973
     974    if (dn == NULL)
     975        return NULL;
     976
     977    /* now that we know how many files there are
     978     * allocate memory for an array to hold dnode pointers
     979     */
     980    *nfiles_p = nfiles;
     981    dnp = dnalloc(nfiles);
     982    for (i = 0; /* i < nfiles - detected via !dn below */; i++) {
     983        dnp[i] = dn;    /* save pointer to node in array */
     984        dn = dn->dn_next;
     985        if (!dn)
     986            break;
     987    }
     988
     989    return dnp;
     990}
    791991
    792992#if ENABLE_DESKTOP
     
    8071007        while (*dn) {
    8081008            /* st_blocks is in 512 byte blocks */
    809             blocks += (*dn)->dstat.st_blocks;
     1009            blocks += (*dn)->dn_blocks;
    8101010            dn++;
    8111011        }
     
    8191019#endif
    8201020
    821 
    822 static struct dnode **list_dir(const char *, unsigned *);
    823 
    824 static void showdirs(struct dnode **dn, int first)
     1021static void scan_and_display_dirs_recur(struct dnode **dn, int first)
    8251022{
    8261023    unsigned nfiles;
    827     unsigned dndirs;
    8281024    struct dnode **subdnp;
    829     struct dnode **dnd;
    830 
    831     /* Never happens:
    832     if (dn == NULL || ndirs < 1) {
    833         return;
    834     }
    835     */
    8361025
    8371026    for (; *dn; dn++) {
    838         if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
     1027        if (G.all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
    8391028            if (!first)
    8401029                bb_putchar('\n');
     
    8421031            printf("%s:\n", (*dn)->fullname);
    8431032        }
    844         subdnp = list_dir((*dn)->fullname, &nfiles);
     1033        subdnp = scan_one_dir((*dn)->fullname, &nfiles);
    8451034#if ENABLE_DESKTOP
    846         if ((all_fmt & STYLE_MASK) == STYLE_LONG)
     1035        if ((G.all_fmt & STYLE_MASK) == STYLE_LONG)
    8471036            printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp));
    8481037#endif
    8491038        if (nfiles > 0) {
    8501039            /* list all files at this level */
    851             dnsort(subdnp, nfiles);
    852             showfiles(subdnp, nfiles);
     1040            sort_and_display_files(subdnp, nfiles);
     1041
    8531042            if (ENABLE_FEATURE_LS_RECURSIVE
    854              && (all_fmt & DISP_RECURSIVE)
     1043             && (G.all_fmt & DISP_RECURSIVE)
    8551044            ) {
     1045                struct dnode **dnd;
     1046                unsigned dndirs;
    8561047                /* recursive - list the sub-dirs */
    8571048                dnd = splitdnarray(subdnp, SPLIT_SUBDIR);
     
    8591050                if (dndirs > 0) {
    8601051                    dnsort(dnd, dndirs);
    861                     showdirs(dnd, 0);
     1052                    scan_and_display_dirs_recur(dnd, 0);
    8621053                    /* free the array of dnode pointers to the dirs */
    8631054                    free(dnd);
     
    8681059        }
    8691060    }
    870 }
    871 
    872 
    873 /* Returns NULL-terminated malloced vector of pointers (or NULL) */
    874 static struct dnode **list_dir(const char *path, unsigned *nfiles_p)
    875 {
    876     struct dnode *dn, *cur, **dnp;
    877     struct dirent *entry;
    878     DIR *dir;
    879     unsigned i, nfiles;
    880 
    881     /* Never happens:
    882     if (path == NULL)
    883         return NULL;
    884     */
    885 
    886     *nfiles_p = 0;
    887     dir = warn_opendir(path);
    888     if (dir == NULL) {
    889         exit_code = EXIT_FAILURE;
    890         return NULL;    /* could not open the dir */
    891     }
    892     dn = NULL;
    893     nfiles = 0;
    894     while ((entry = readdir(dir)) != NULL) {
    895         char *fullname;
    896 
    897         /* are we going to list the file- it may be . or .. or a hidden file */
    898         if (entry->d_name[0] == '.') {
    899             if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2]))
    900              && !(all_fmt & DISP_DOT)
    901             ) {
    902                 continue;
    903             }
    904             if (!(all_fmt & DISP_HIDDEN))
    905                 continue;
    906         }
    907         fullname = concat_path_file(path, entry->d_name);
    908         cur = my_stat(fullname, bb_basename(fullname), 0);
    909         if (!cur) {
    910             free(fullname);
    911             continue;
    912         }
    913         cur->fname_allocated = 1;
    914         cur->next = dn;
    915         dn = cur;
    916         nfiles++;
    917     }
    918     closedir(dir);
    919 
    920     if (dn == NULL)
    921         return NULL;
    922 
    923     /* now that we know how many files there are
    924      * allocate memory for an array to hold dnode pointers
    925      */
    926     *nfiles_p = nfiles;
    927     dnp = dnalloc(nfiles);
    928     for (i = 0; /* i < nfiles - detected via !dn below */; i++) {
    929         dnp[i] = dn;    /* save pointer to node in array */
    930         dn = dn->next;
    931         if (!dn)
    932             break;
    933     }
    934 
    935     return dnp;
    9361061}
    9371062
     
    9731098    init_unicode();
    9741099
    975     all_fmt = LIST_SHORT |
    976         (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD));
     1100    if (ENABLE_FEATURE_LS_SORTFILES)
     1101        G.all_fmt = SORT_NAME;
    9771102
    9781103#if ENABLE_FEATURE_AUTOWIDTH
    9791104    /* obtain the terminal width */
    980     get_terminal_width_height(STDIN_FILENO, &terminal_width, NULL);
     1105    get_terminal_width_height(STDIN_FILENO, &G_terminal_width, NULL);
    9811106    /* go one less... */
    982     terminal_width--;
     1107    G_terminal_width--;
    9831108#endif
    9841109
    9851110    /* process options */
    9861111    IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;)
    987 #if ENABLE_FEATURE_AUTOWIDTH
    988     opt_complementary = "T+:w+"; /* -T N, -w N */
    989     opt = getopt32(argv, ls_options, &tabstops, &terminal_width
    990                 IF_FEATURE_LS_COLOR(, &color_opt));
    991 #else
    992     opt = getopt32(argv, ls_options IF_FEATURE_LS_COLOR(, &color_opt));
    993 #endif
    994     for (i = 0; opt_flags[i] != (1U<<31); i++) {
     1112    opt_complementary =
     1113        /* -e implies -l */
     1114        IF_FEATURE_LS_TIMESTAMPS("el")
     1115        /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html:
     1116         * in some pairs of opts, only last one takes effect:
     1117         */
     1118        IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */
     1119        // ":m-l:l-m" - we don't have -m
     1120        IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H")
     1121        ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */
     1122        ":C-1:1-C" /* bycols/oneline */
     1123        ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */
     1124        IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */
     1125        /* -w NUM: */
     1126        IF_FEATURE_AUTOWIDTH(":w+");
     1127    opt = getopt32(argv, ls_options
     1128        IF_FEATURE_AUTOWIDTH(, NULL, &G_terminal_width)
     1129        IF_FEATURE_LS_COLOR(, &color_opt)
     1130    );
     1131    for (i = 0; opt_flags[i] != (1U << 31); i++) {
    9951132        if (opt & (1 << i)) {
    996             unsigned flags = opt_flags[i];
    997 
    998             if (flags & LIST_MASK_TRIGGER)
    999                 all_fmt &= ~LIST_MASK;
    1000             if (flags & STYLE_MASK_TRIGGER)
    1001                 all_fmt &= ~STYLE_MASK;
    1002             if (flags & SORT_MASK_TRIGGER)
    1003                 all_fmt &= ~SORT_MASK;
    1004             if (flags & DISP_MASK_TRIGGER)
    1005                 all_fmt &= ~DISP_MASK;
     1133            uint32_t flags = opt_flags[i];
     1134
     1135            if (flags & STYLE_MASK)
     1136                G.all_fmt &= ~STYLE_MASK;
     1137            if (flags & SORT_MASK)
     1138                G.all_fmt &= ~SORT_MASK;
    10061139            if (flags & TIME_MASK)
    1007                 all_fmt &= ~TIME_MASK;
    1008             if (flags & LIST_CONTEXT)
    1009                 all_fmt |= STYLE_SINGLE;
    1010             /* huh?? opt cannot be 'l' */
    1011             //if (LS_DISP_HR && opt == 'l')
    1012             //  all_fmt &= ~LS_DISP_HR;
    1013             all_fmt |= flags;
     1140                G.all_fmt &= ~TIME_MASK;
     1141
     1142            G.all_fmt |= flags;
    10141143        }
    10151144    }
    10161145
    10171146#if ENABLE_FEATURE_LS_COLOR
    1018     /* find color bit value - last position for short getopt */
     1147    /* set G_show_color = 1/0 */
    10191148    if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) {
    10201149        char *p = getenv("LS_COLORS");
    10211150        /* LS_COLORS is unset, or (not empty && not "none") ? */
    10221151        if (!p || (p[0] && strcmp(p, "none") != 0))
    1023             show_color = 1;
     1152            G_show_color = 1;
    10241153    }
    10251154    if (opt & OPT_color) {
    10261155        if (color_opt[0] == 'n')
    1027             show_color = 0;
     1156            G_show_color = 0;
    10281157        else switch (index_in_substrings(color_str, color_opt)) {
    10291158        case 3:
     
    10341163        case 1:
    10351164        case 2:
    1036                 show_color = 1;
     1165                G_show_color = 1;
    10371166            }
    10381167        }
     
    10411170
    10421171    /* sort out which command line options take precedence */
    1043     if (ENABLE_FEATURE_LS_RECURSIVE && (all_fmt & DISP_NOLIST))
    1044         all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
     1172    if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST))
     1173        G.all_fmt &= ~DISP_RECURSIVE;   /* no recurse if listing only dir */
    10451174    if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
    1046         if (all_fmt & TIME_CHANGE)
    1047             all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME;
    1048         if (all_fmt & TIME_ACCESS)
    1049             all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME;
    1050     }
    1051     if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */
    1052         all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC);
    1053     if (ENABLE_FEATURE_LS_USERNAME)
    1054         if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC))
    1055             all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */
    1056 
    1057     /* choose a display format */
    1058     if (!(all_fmt & STYLE_MASK))
    1059         all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE);
     1175        if (G.all_fmt & TIME_CHANGE)
     1176            G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_CTIME;
     1177        if (G.all_fmt & TIME_ACCESS)
     1178            G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_ATIME;
     1179    }
     1180    if ((G.all_fmt & STYLE_MASK) != STYLE_LONG) /* not -l? */
     1181        G.all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME);
     1182
     1183    /* choose a display format if one was not already specified by an option */
     1184    if (!(G.all_fmt & STYLE_MASK))
     1185        G.all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNAR : STYLE_SINGLE);
    10601186
    10611187    argv += optind;
     
    10641190
    10651191    if (argv[1])
    1066         all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */
     1192        G.all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */
    10671193
    10681194    /* stuff the command line file names into a dnode array */
     
    10701196    nfiles = 0;
    10711197    do {
    1072         /* NB: follow links on command line unless -l or -s */
    1073         cur = my_stat(*argv, *argv, !(all_fmt & (STYLE_LONG|LIST_BLOCKS)));
     1198        cur = my_stat(*argv, *argv,
     1199            /* follow links on command line unless -l, -s or -F: */
     1200            !((G.all_fmt & STYLE_MASK) == STYLE_LONG
     1201              || (G.all_fmt & LIST_BLOCKS)
     1202              || (option_mask32 & OPT_F)
     1203            )
     1204            /* ... or if -H: */
     1205            || (option_mask32 & OPT_H)
     1206            /* ... or if -L, but my_stat always follows links if -L */
     1207        );
    10741208        argv++;
    10751209        if (!cur)
    10761210            continue;
    1077         cur->fname_allocated = 0;
    1078         cur->next = dn;
     1211        /*cur->fname_allocated = 0; - already is */
     1212        cur->dn_next = dn;
    10791213        dn = cur;
    10801214        nfiles++;
     
    10831217    /* nfiles _may_ be 0 here - try "ls doesnt_exist" */
    10841218    if (nfiles == 0)
    1085         return exit_code;
     1219        return G.exit_code;
    10861220
    10871221    /* now that we know how many files there are
     
    10911225    for (i = 0; /* i < nfiles - detected via !dn below */; i++) {
    10921226        dnp[i] = dn;    /* save pointer to node in array */
    1093         dn = dn->next;
     1227        dn = dn->dn_next;
    10941228        if (!dn)
    10951229            break;
    10961230    }
    10971231
    1098     if (all_fmt & DISP_NOLIST) {
    1099         dnsort(dnp, nfiles);
    1100         showfiles(dnp, nfiles);
     1232    if (G.all_fmt & DISP_NOLIST) {
     1233        sort_and_display_files(dnp, nfiles);
    11011234    } else {
    11021235        dnd = splitdnarray(dnp, SPLIT_DIR);
     
    11051238        dnfiles = nfiles - dndirs;
    11061239        if (dnfiles > 0) {
    1107             dnsort(dnf, dnfiles);
    1108             showfiles(dnf, dnfiles);
     1240            sort_and_display_files(dnf, dnfiles);
    11091241            if (ENABLE_FEATURE_CLEAN_UP)
    11101242                free(dnf);
     
    11121244        if (dndirs > 0) {
    11131245            dnsort(dnd, dndirs);
    1114             showdirs(dnd, dnfiles == 0);
     1246            scan_and_display_dirs_recur(dnd, dnfiles == 0);
    11151247            if (ENABLE_FEATURE_CLEAN_UP)
    11161248                free(dnd);
    11171249        }
    11181250    }
     1251
    11191252    if (ENABLE_FEATURE_CLEAN_UP)
    11201253        dfree(dnp);
    1121     return exit_code;
    1122 }
     1254    return G.exit_code;
     1255}
  • branches/3.2/mindi-busybox/coreutils/md5_sha1_sum.c

    r2725 r3232  
    77 */
    88
     9//usage:#define md5sum_trivial_usage
     10//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
     11//usage:#define md5sum_full_usage "\n\n"
     12//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " MD5 checksums"
     13//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
     14//usage:     "\n    -c  Check sums against list in FILEs"
     15//usage:     "\n    -s  Don't output anything, status code shows success"
     16//usage:     "\n    -w  Warn about improperly formatted checksum lines"
     17//usage:    )
     18//usage:
     19//usage:#define md5sum_example_usage
     20//usage:       "$ md5sum < busybox\n"
     21//usage:       "6fd11e98b98a58f64ff3398d7b324003\n"
     22//usage:       "$ md5sum busybox\n"
     23//usage:       "6fd11e98b98a58f64ff3398d7b324003  busybox\n"
     24//usage:       "$ md5sum -c -\n"
     25//usage:       "6fd11e98b98a58f64ff3398d7b324003  busybox\n"
     26//usage:       "busybox: OK\n"
     27//usage:       "^D\n"
     28//usage:
     29//usage:#define sha1sum_trivial_usage
     30//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
     31//usage:#define sha1sum_full_usage "\n\n"
     32//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums"
     33//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
     34//usage:     "\n    -c  Check sums against list in FILEs"
     35//usage:     "\n    -s  Don't output anything, status code shows success"
     36//usage:     "\n    -w  Warn about improperly formatted checksum lines"
     37//usage:    )
     38//usage:
     39//usage:#define sha256sum_trivial_usage
     40//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
     41//usage:#define sha256sum_full_usage "\n\n"
     42//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA256 checksums"
     43//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
     44//usage:     "\n    -c  Check sums against list in FILEs"
     45//usage:     "\n    -s  Don't output anything, status code shows success"
     46//usage:     "\n    -w  Warn about improperly formatted checksum lines"
     47//usage:    )
     48//usage:
     49//usage:#define sha512sum_trivial_usage
     50//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
     51//usage:#define sha512sum_full_usage "\n\n"
     52//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA512 checksums"
     53//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
     54//usage:     "\n    -c  Check sums against list in FILEs"
     55//usage:     "\n    -s  Don't output anything, status code shows success"
     56//usage:     "\n    -w  Warn about improperly formatted checksum lines"
     57//usage:    )
     58//usage:
     59//usage:#define sha3sum_trivial_usage
     60//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
     61//usage:#define sha3sum_full_usage "\n\n"
     62//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums"
     63//usage:    IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
     64//usage:     "\n    -c  Check sums against list in FILEs"
     65//usage:     "\n    -s  Don't output anything, status code shows success"
     66//usage:     "\n    -w  Warn about improperly formatted checksum lines"
     67//usage:    )
     68
    969#include "libbb.h"
    1070
     
    1676    HASH_SHA1 = '1',
    1777    HASH_SHA256 = '2',
     78    HASH_SHA3 = '3',
    1879    HASH_SHA512 = '5',
    1980};
     
    3798    int src_fd, hash_len, count;
    3899    union _ctx_ {
     100        sha3_ctx_t sha3;
    39101        sha512_ctx_t sha512;
    40102        sha256_ctx_t sha256;
     
    42104        md5_ctx_t md5;
    43105    } context;
    44     uint8_t *hash_value = NULL;
    45     RESERVE_CONFIG_UBUFFER(in_buf, 4096);
     106    uint8_t *hash_value;
    46107    void FAST_FUNC (*update)(void*, const void*, size_t);
    47108    void FAST_FUNC (*final)(void*, void*);
     
    55116    hash_algo = applet_name[3];
    56117
    57     /* figure specific hash algorithims */
     118    /* figure specific hash algorithms */
    58119    if (ENABLE_MD5SUM && hash_algo == HASH_MD5) {
    59120        md5_begin(&context.md5);
     
    76137        final = (void*)sha512_end;
    77138        hash_len = 64;
     139    } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
     140        sha3_begin(&context.sha3);
     141        update = (void*)sha3_hash;
     142        final = (void*)sha3_end;
     143        hash_len = 64;
    78144    } else {
    79145        xfunc_die(); /* can't reach this */
    80146    }
    81147
    82     while ((count = safe_read(src_fd, in_buf, 4096)) > 0) {
    83         update(&context, in_buf, count);
    84     }
    85 
    86     if (count == 0) {
    87         final(&context, in_buf);
    88         hash_value = hash_bin_to_hex(in_buf, hash_len);
    89     }
    90 
    91     RELEASE_CONFIG_BUFFER(in_buf);
     148    {
     149        RESERVE_CONFIG_UBUFFER(in_buf, 4096);
     150        while ((count = safe_read(src_fd, in_buf, 4096)) > 0) {
     151            update(&context, in_buf, count);
     152        }
     153        hash_value = NULL;
     154        if (count == 0) {
     155            final(&context, in_buf);
     156            hash_value = hash_bin_to_hex(in_buf, hash_len);
     157        }
     158        RELEASE_CONFIG_BUFFER(in_buf);
     159    }
    92160
    93161    if (src_fd != STDIN_FILENO) {
     
    125193    }
    126194
    127     if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
    128         FILE *pre_computed_stream;
    129         int count_total = 0;
    130         int count_failed = 0;
    131         char *line;
    132 
    133         if (argv[1]) {
    134             bb_error_msg_and_die("only one argument may be specified with -c");
    135         }
    136 
    137         pre_computed_stream = xfopen_stdin(argv[0]);
    138 
    139         while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
    140             uint8_t *hash_value;
    141             char *filename_ptr;
    142 
    143             count_total++;
    144             filename_ptr = strstr(line, "  ");
    145             /* handle format for binary checksums */
    146             if (filename_ptr == NULL) {
    147                 filename_ptr = strstr(line, " *");
     195    do {
     196        if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
     197            FILE *pre_computed_stream;
     198            char *line;
     199            int count_total = 0;
     200            int count_failed = 0;
     201
     202            pre_computed_stream = xfopen_stdin(*argv);
     203
     204            while ((line = xmalloc_fgetline(pre_computed_stream)) != NULL) {
     205                uint8_t *hash_value;
     206                char *filename_ptr;
     207
     208                count_total++;
     209                filename_ptr = strstr(line, "  ");
     210                /* handle format for binary checksums */
     211                if (filename_ptr == NULL) {
     212                    filename_ptr = strstr(line, " *");
     213                }
     214                if (filename_ptr == NULL) {
     215                    if (flags & FLAG_WARN) {
     216                        bb_error_msg("invalid format");
     217                    }
     218                    count_failed++;
     219                    return_value = EXIT_FAILURE;
     220                    free(line);
     221                    continue;
     222                }
     223                *filename_ptr = '\0';
     224                filename_ptr += 2;
     225
     226                hash_value = hash_file(filename_ptr);
     227
     228                if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
     229                    if (!(flags & FLAG_SILENT))
     230                        printf("%s: OK\n", filename_ptr);
     231                } else {
     232                    if (!(flags & FLAG_SILENT))
     233                        printf("%s: FAILED\n", filename_ptr);
     234                    count_failed++;
     235                    return_value = EXIT_FAILURE;
     236                }
     237                /* possible free(NULL) */
     238                free(hash_value);
     239                free(line);
    148240            }
    149             if (filename_ptr == NULL) {
    150                 if (flags & FLAG_WARN) {
    151                     bb_error_msg("invalid format");
    152                 }
    153                 count_failed++;
    154                 return_value = EXIT_FAILURE;
    155                 free(line);
    156                 continue;
     241            if (count_failed && !(flags & FLAG_SILENT)) {
     242                bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
     243                        count_failed, count_total);
    157244            }
    158             *filename_ptr = '\0';
    159             filename_ptr += 2;
    160 
    161             hash_value = hash_file(filename_ptr);
    162 
    163             if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
    164                 if (!(flags & FLAG_SILENT))
    165                     printf("%s: OK\n", filename_ptr);
    166             } else {
    167                 if (!(flags & FLAG_SILENT))
    168                     printf("%s: FAILED\n", filename_ptr);
    169                 count_failed++;
    170                 return_value = EXIT_FAILURE;
    171             }
    172             /* possible free(NULL) */
    173             free(hash_value);
    174             free(line);
    175         }
    176         if (count_failed && !(flags & FLAG_SILENT)) {
    177             bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
    178                          count_failed, count_total);
    179         }
    180         /*
    181         if (fclose_if_not_stdin(pre_computed_stream) == EOF) {
    182             bb_perror_msg_and_die("can't close file %s", file_ptr);
    183         }
    184         */
    185     } else {
    186         do {
     245            fclose_if_not_stdin(pre_computed_stream);
     246        } else {
    187247            uint8_t *hash_value = hash_file(*argv);
    188248            if (hash_value == NULL) {
     
    192252                free(hash_value);
    193253            }
    194         } while (*++argv);
    195     }
     254        }
     255    } while (*++argv);
     256
    196257    return return_value;
    197258}
  • branches/3.2/mindi-busybox/coreutils/mkdir.c

    r2725 r3232  
    2020 */
    2121
     22//usage:#define mkdir_trivial_usage
     23//usage:       "[OPTIONS] DIRECTORY..."
     24//usage:#define mkdir_full_usage "\n\n"
     25//usage:       "Create DIRECTORY\n"
     26//usage:     "\n    -m MODE Mode"
     27//usage:     "\n    -p  No error if exists; make parent directories as needed"
     28//usage:    IF_SELINUX(
     29//usage:     "\n    -Z  Set security context"
     30//usage:    )
     31//usage:
     32//usage:#define mkdir_example_usage
     33//usage:       "$ mkdir /tmp/foo\n"
     34//usage:       "$ mkdir /tmp/foo\n"
     35//usage:       "/tmp/foo: File exists\n"
     36//usage:       "$ mkdir /tmp/foo/bar/baz\n"
     37//usage:       "/tmp/foo/bar/baz: No such file or directory\n"
     38//usage:       "$ mkdir -p /tmp/foo/bar/baz\n"
     39
    2240#include "libbb.h"
    2341
     
    3149    "context\0" Required_argument "Z"
    3250#endif
     51    "verbose\0" No_argument       "v"
    3352    ;
    3453#endif
     
    3756int mkdir_main(int argc UNUSED_PARAM, char **argv)
    3857{
    39     mode_t mode = (mode_t)(-1);
     58    long mode = -1;
    4059    int status = EXIT_SUCCESS;
    4160    int flags = 0;
     
    4968    applet_long_options = mkdir_longopts;
    5069#endif
    51     opt = getopt32(argv, "m:p" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext));
     70    opt = getopt32(argv, "m:p" IF_SELINUX("Z:") "v", &smode IF_SELINUX(,&scontext));
    5271    if (opt & 1) {
    53         mode = 0777;
    54         if (!bb_parse_mode(smode, &mode)) {
     72        mode_t mmode = 0777;
     73        if (!bb_parse_mode(smode, &mmode)) {
    5574            bb_error_msg_and_die("invalid mode '%s'", smode);
    5675        }
     76        mode = mmode;
    5777    }
    5878    if (opt & 2)
  • branches/3.2/mindi-busybox/coreutils/mkfifo.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv3 compliant */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */
     12
     13//usage:#define mkfifo_trivial_usage
     14//usage:       "[-m MODE] " IF_SELINUX("[-Z] ") "NAME"
     15//usage:#define mkfifo_full_usage "\n\n"
     16//usage:       "Create named pipe\n"
     17//usage:     "\n    -m MODE Mode (default a=rw)"
     18//usage:    IF_SELINUX(
     19//usage:     "\n    -Z  Set security context"
     20//usage:    )
    1221
    1322#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/mknod.c

    r2725 r3232  
    99
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
     11
     12//usage:#define mknod_trivial_usage
     13//usage:       "[-m MODE] " IF_SELINUX("[-Z] ") "NAME TYPE MAJOR MINOR"
     14//usage:#define mknod_full_usage "\n\n"
     15//usage:       "Create a special file (block, character, or pipe)\n"
     16//usage:     "\n    -m MODE Creation mode (default a=rw)"
     17//usage:    IF_SELINUX(
     18//usage:     "\n    -Z  Set security context"
     19//usage:    )
     20//usage:     "\nTYPE:"
     21//usage:     "\n    b   Block device"
     22//usage:     "\n    c or u  Character device"
     23//usage:     "\n    p   Named pipe (MAJOR and MINOR are ignored)"
     24//usage:
     25//usage:#define mknod_example_usage
     26//usage:       "$ mknod /dev/fd0 b 2 0\n"
     27//usage:       "$ mknod -m 644 /tmp/pipe p\n"
    1128
    1229#include <sys/sysmacros.h>  // For makedev
     
    4360                     * optimize out to two constants. */
    4461                    dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)),
    45                                   xatoul_range(argv[3], 0, minor(UINT_MAX)));
     62                            xatoul_range(argv[3], 0, minor(UINT_MAX)));
    4663                }
    4764            }
  • branches/3.2/mindi-busybox/coreutils/mv.c

    r2725 r3232  
    2222//usage:#define mv_full_usage "\n\n"
    2323//usage:       "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY\n"
    24 //usage:     "\nOptions:"
    2524//usage:     "\n    -f  Don't prompt before overwriting"
    2625//usage:     "\n    -i  Interactive, prompt before overwrite"
     
    3534    "force\0"       No_argument "f"
    3635    "no-clobber\0"  No_argument "n"
     36    "verbose\0"     No_argument "v"
    3737    ;
    3838#endif
    3939
    40 #define OPT_FILEUTILS_FORCE       1
    41 #define OPT_FILEUTILS_INTERACTIVE 2
    42 #define OPT_FILEUTILS_NOCLOBBER   4
     40#define OPT_FORCE       (1 << 0)
     41#define OPT_INTERACTIVE (1 << 1)
     42#define OPT_NOCLOBBER   (1 << 2)
    4343
    4444int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     
    5858    /* Need at least two arguments.
    5959     * If more than one of -f, -i, -n is specified , only the final one
    60      * takes effect (it unsets previous options). */
     60     * takes effect (it unsets previous options).
     61     * -v is accepted but ignored.
     62     */
    6163    opt_complementary = "-2:f-in:i-fn:n-fi";
    62     flags = getopt32(argv, "fin");
     64    flags = getopt32(argv, "finv");
    6365    argc -= optind;
    6466    argv += optind;
     
    8688 DO_MOVE:
    8789        if (dest_exists) {
    88             if (flags & OPT_FILEUTILS_NOCLOBBER)
     90            if (flags & OPT_NOCLOBBER)
    8991                goto RET_0;
    90             if (!(flags & OPT_FILEUTILS_FORCE)
     92            if (!(flags & OPT_FORCE)
    9193             && ((access(dest, W_OK) < 0 && isatty(0))
    92                 || (flags & OPT_FILEUTILS_INTERACTIVE))
     94                || (flags & OPT_INTERACTIVE))
    9395            ) {
    9496                if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) {
  • branches/3.2/mindi-busybox/coreutils/nice.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define nice_trivial_usage
     11//usage:       "[-n ADJUST] [PROG ARGS]"
     12//usage:#define nice_full_usage "\n\n"
     13//usage:       "Change scheduling priority, run PROG\n"
     14//usage:     "\n    -n ADJUST   Adjust priority by ADJUST"
    915
    1016#include <sys/resource.h>
  • branches/3.2/mindi-busybox/coreutils/nohup.c

    r2725 r3232  
    1010 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1111 */
     12
     13//usage:#define nohup_trivial_usage
     14//usage:       "PROG ARGS"
     15//usage:#define nohup_full_usage "\n\n"
     16//usage:       "Run PROG immune to hangups, with output to a non-tty"
     17//usage:
     18//usage:#define nohup_example_usage
     19//usage:       "$ nohup make &"
    1220
    1321#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/od.c

    r2725 r3232  
    1212 */
    1313
     14//usage:#if !ENABLE_DESKTOP
     15//usage:#define od_trivial_usage
     16//usage:       "[-aBbcDdeFfHhIiLlOovXx] [FILE]"
     17//usage:#define od_full_usage "\n\n"
     18//usage:       "Print FILE (or stdin) unambiguously, as octal bytes by default"
     19//usage:#endif
    1420
    1521#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/od_bloaty.c

    r2725 r3232  
    1414   You should have received a copy of the GNU General Public License
    1515   along with this program; if not, write to the Free Software Foundation,
    16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    17 
     16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     17 */
    1818/* Written by Jim Meyering.  */
    19 
    20 /* Busyboxed by Denys Vlasenko
    21 
    22 Based on od.c from coreutils-5.2.1
    23 Top bloat sources:
    24 
    25 00000073 t parse_old_offset
    26 0000007b t get_lcm
    27 00000090 r long_options
    28 00000092 t print_named_ascii
    29 000000bf t print_ascii
    30 00000168 t write_block
    31 00000366 t decode_format_string
    32 00000a71 T od_main
    33 
    34 Tested for compat with coreutils 6.3
    35 using this script. Minor differences fixed.
    36 
    37 #!/bin/sh
    38 echo STD
    39 time /path/to/coreutils/od \
    40 ...params... \
    41 >std
    42 echo Exit code $?
    43 echo BBOX
    44 time ./busybox od \
    45 ...params... \
    46 >bbox
    47 echo Exit code $?
    48 diff -u -a std bbox >bbox.diff || { echo Different!; sleep 1; }
    49 
    50 */
    51 
    52 #include "libbb.h"
    53 
     19/* Busyboxed by Denys Vlasenko, based on od.c from coreutils-5.2.1 */
     20
     21
     22/* #include "libbb.h" - done in od.c */
    5423#define assert(a) ((void)0)
    5524
     25
     26//usage:#if ENABLE_DESKTOP
     27//usage:#define od_trivial_usage
     28//usage:       "[-abcdfhilovxs] [-t TYPE] [-A RADIX] [-N SIZE] [-j SKIP] [-S MINSTR] [-w WIDTH] [FILE]..."
     29// We don't support:
     30// ... [FILE] [[+]OFFSET[.][b]]
     31// Support is buggy for:
     32// od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
     33
     34//usage:#define od_full_usage "\n\n"
     35//usage:       "Print FILEs (or stdin) unambiguously, as octal bytes by default"
     36//usage:#endif
     37
     38enum {
     39    OPT_A = 1 << 0,
     40    OPT_N = 1 << 1,
     41    OPT_a = 1 << 2,
     42    OPT_b = 1 << 3,
     43    OPT_c = 1 << 4,
     44    OPT_d = 1 << 5,
     45    OPT_f = 1 << 6,
     46    OPT_h = 1 << 7,
     47    OPT_i = 1 << 8,
     48    OPT_j = 1 << 9,
     49    OPT_l = 1 << 10,
     50    OPT_o = 1 << 11,
     51    OPT_t = 1 << 12,
     52    /* When zero and two or more consecutive blocks are equal, format
     53       only the first block and output an asterisk alone on the following
     54       line to indicate that identical blocks have been elided: */
     55    OPT_v = 1 << 13,
     56    OPT_x = 1 << 14,
     57    OPT_s = 1 << 15,
     58    OPT_S = 1 << 16,
     59    OPT_w = 1 << 17,
     60    OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS,
     61};
     62
     63#define OD_GETOPT32() getopt32(argv, \
     64    "A:N:abcdfhij:lot:vxsS:w::", \
     65    /* -w with optional param */ \
     66    /* -S was -s and also had optional parameter */ \
     67    /* but in coreutils 6.3 it was renamed and now has */ \
     68    /* _mandatory_ parameter */ \
     69    &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block)
     70
     71
    5672/* Check for 0x7f is a coreutils 6.3 addition */
    57 #define ISPRINT(c) (((c)>=' ') && (c) != 0x7f)
     73#define ISPRINT(c) (((c) >= ' ') && (c) < 0x7f)
    5874
    5975typedef long double longdouble_t;
     
    159175};
    160176
    161 static smallint flag_dump_strings;
    162 /* Non-zero if an old-style 'pseudo-address' was specified.  */
    163 static smallint flag_pseudo_start;
    164 static smallint limit_bytes_to_format;
    165 /* When zero and two or more consecutive blocks are equal, format
    166    only the first block and output an asterisk alone on the following
    167    line to indicate that identical blocks have been elided.  */
    168 static smallint verbose;
    169 static smallint ioerror;
    170 
    171 static size_t string_min;
     177static smallint exit_code;
     178
     179static unsigned string_min;
    172180
    173181/* An array of specs describing how to format each input block.  */
     
    180188/* The difference between the old-style pseudo starting address and
    181189   the number of bytes to skip.  */
     190#if ENABLE_LONG_OPTS
    182191static off_t pseudo_offset;
     192#else
     193enum { pseudo_offset = 0 };
     194#endif
    183195/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
    184196   input is formatted.  */
     
    215227#define MAX_FP_TYPE_SIZE sizeof(longdouble_t)
    216228static const unsigned char fp_type_size[MAX_FP_TYPE_SIZE + 1] ALIGN1 = {
    217     /* gcc seems to allow repeated indexes. Last one stays */
     229    /* gcc seems to allow repeated indexes. Last one wins */
    218230    [sizeof(longdouble_t)] = FLOAT_LONG_DOUBLE,
    219231    [sizeof(double)] = FLOAT_DOUBLE,
     
    377389    // buf[N] pos:  01234 56789
    378390    char buf[12] = "   x\0 0xx\0";
    379     // actually "   x\0 xxx\0", but I want to share the string with below.
     391    // actually "   x\0 xxx\0", but want to share string with print_ascii.
    380392    // [12] because we take three 32bit stack slots anyway, and
    381393    // gcc is too dumb to initialize with constant stores,
     
    473485            break;
    474486        }
    475         ioerror = 1;
    476     }
    477 
    478     if (limit_bytes_to_format && !flag_dump_strings)
     487        exit_code = 1;
     488    }
     489
     490    if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
    479491        setbuf(in_stream, NULL);
    480492}
     
    496508                    : file_list[-1]
    497509            );
    498             ioerror = 1;
     510            exit_code = 1;
    499511        }
    500512        fclose_if_not_stdin(in_stream);
     
    503515
    504516    if (ferror(stdout)) {
    505         bb_error_msg(bb_msg_write_error);
    506         ioerror = 1;
     517        bb_error_msg_and_die(bb_msg_write_error);
    507518    }
    508519}
     
    535546    unsigned field_width = 0;
    536547    int pos;
    537 
    538548
    539549    switch (*s) {
     
    782792            } else {
    783793                if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
    784                     ioerror = 1;
     794                    exit_code = 1;
    785795                return;
    786796            }
     
    883893    size_t i;
    884894
    885     if (!verbose && !first
     895    if (!(option_mask32 & OPT_v)
     896     && !first
    886897     && n_bytes == bytes_per_block
    887898     && memcmp(prev_block, curr_block, bytes_per_block) == 0
     
    905916            if (spec[i].hexl_mode_trailer) {
    906917                /* space-pad out to full line width, then dump the trailer */
    907                 int datum_width = width_bytes[spec[i].size];
    908                 int blank_fields = (bytes_per_block - n_bytes) / datum_width;
    909                 int field_width = spec[i].field_width + 1;
     918                unsigned datum_width = width_bytes[spec[i].size];
     919                unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width;
     920                unsigned field_width = spec[i].field_width + 1;
    910921                printf("%*s", blank_fields * field_width, "");
    911922                dump_hexl_mode_trailer(n_bytes, curr_block);
     
    954965    return l_c_m;
    955966}
    956 
    957 #if ENABLE_LONG_OPTS
    958 /* If S is a valid traditional offset specification with an optional
    959    leading '+' return nonzero and set *OFFSET to the offset it denotes.  */
    960 
    961 static int
    962 parse_old_offset(const char *s, off_t *offset)
    963 {
    964     static const struct suffix_mult Bb[] = {
    965         { "B", 1024 },
    966         { "b", 512 },
    967         { "", 0 }
    968     };
    969     char *p;
    970     int radix;
    971 
    972     /* Skip over any leading '+'. */
    973     if (s[0] == '+') ++s;
    974 
    975     /* Determine the radix we'll use to interpret S.  If there is a '.',
    976      * it's decimal, otherwise, if the string begins with '0X'or '0x',
    977      * it's hexadecimal, else octal.  */
    978     p = strchr(s, '.');
    979     radix = 8;
    980     if (p) {
    981         p[0] = '\0'; /* cheating */
    982         radix = 10;
    983     } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
    984         radix = 16;
    985 
    986     *offset = xstrtooff_sfx(s, radix, Bb);
    987     if (p) p[0] = '.';
    988 
    989     return (*offset >= 0);
    990 }
    991 #endif
    992967
    993968/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
     
    1008983    size_t n_bytes_read;
    1009984
    1010     block[0] = xmalloc(2*bytes_per_block);
     985    block[0] = xmalloc(2 * bytes_per_block);
    1011986    block[1] = block[0] + bytes_per_block;
    1012987
    1013988    idx = 0;
    1014     if (limit_bytes_to_format) {
     989    if (option_mask32 & OPT_N) {
    1015990        while (1) {
    1016991            size_t n_needed;
     
    1019994                break;
    1020995            }
    1021             n_needed = MIN(end_offset - current_offset,
    1022                 (off_t) bytes_per_block);
     996            n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block);
    1023997            read_block(n_needed, block[idx], &n_bytes_read);
    1024998            if (n_bytes_read < bytes_per_block)
    1025999                break;
    10261000            assert(n_bytes_read == bytes_per_block);
    1027             write_block(current_offset, n_bytes_read,
    1028                    block[!idx], block[idx]);
     1001            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10291002            current_offset += n_bytes_read;
    1030             idx = !idx;
     1003            idx ^= 1;
    10311004        }
    10321005    } else {
     
    10361009                break;
    10371010            assert(n_bytes_read == bytes_per_block);
    1038             write_block(current_offset, n_bytes_read,
    1039                    block[!idx], block[idx]);
     1011            write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
    10401012            current_offset += n_bytes_read;
    1041             idx = !idx;
     1013            idx ^= 1;
    10421014        }
    10431015    }
     
    10501022
    10511023        /* Make bytes_to_write the smallest multiple of l_c_m that
    1052             is at least as large as n_bytes_read.  */
     1024          is at least as large as n_bytes_read.  */
    10531025        bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
    10541026
    10551027        memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
    10561028        write_block(current_offset, bytes_to_write,
    1057                    block[!idx], block[idx]);
     1029                block[idx ^ 1], block[idx]);
    10581030        current_offset += n_bytes_read;
    10591031    }
     
    10611033    format_address(current_offset, '\n');
    10621034
    1063     if (limit_bytes_to_format && current_offset >= end_offset)
     1035    if ((option_mask32 & OPT_N) && current_offset >= end_offset)
    10641036        check_and_close();
    10651037
    10661038    free(block[0]);
    1067 }
    1068 
    1069 /* Read a single byte into *C from the concatenation of the input files
    1070    named in the global array FILE_LIST.  On the first call to this
    1071    function, the global variable IN_STREAM is expected to be an open
    1072    stream associated with the input file INPUT_FILENAME.  If IN_STREAM
    1073    is at end-of-file, close it and update the global variables IN_STREAM
    1074    and INPUT_FILENAME so they correspond to the next file in the list.
    1075    Then try to read a byte from the newly opened file.  Repeat if
    1076    necessary until EOF is reached for the last file in FILE_LIST, then
    1077    set *C to EOF and return.  Subsequent calls do likewise.  */
    1078 
    1079 static void
    1080 read_char(int *c)
    1081 {
    1082     while (in_stream) { /* !EOF */
    1083         *c = fgetc(in_stream);
    1084         if (*c != EOF)
    1085             return;
    1086         check_and_close();
    1087         open_next_file();
    1088     }
    1089     *c = EOF;
    10901039}
    10911040
     
    11131062dump_strings(off_t address, off_t end_offset)
    11141063{
    1115     size_t bufsize = MAX(100, string_min);
    1116     char *buf = xmalloc(bufsize);
     1064    unsigned bufsize = MAX(100, string_min);
     1065    unsigned char *buf = xmalloc(bufsize);
    11171066
    11181067    while (1) {
     
    11221071        /* See if the next 'string_min' chars are all printing chars.  */
    11231072 tryline:
    1124         if (limit_bytes_to_format && (end_offset - string_min <= address))
     1073        if ((option_mask32 & OPT_N) && (end_offset - string_min <= address))
    11251074            break;
    11261075        i = 0;
    1127         while (!limit_bytes_to_format || address < end_offset) {
     1076        while (!(option_mask32 & OPT_N) || address < end_offset) {
    11281077            if (i == bufsize) {
    11291078                bufsize += bufsize/8;
    11301079                buf = xrealloc(buf, bufsize);
    11311080            }
    1132             read_char(&c);
    1133             if (c < 0) { /* EOF */
    1134                 free(buf);
    1135                 return;
     1081
     1082            while (in_stream) { /* !EOF */
     1083                c = fgetc(in_stream);
     1084                if (c != EOF)
     1085                    goto got_char;
     1086                check_and_close();
     1087                open_next_file();
    11361088            }
     1089            /* EOF */
     1090            goto ret;
     1091 got_char:
    11371092            address++;
    11381093            if (!c)
     
    11461101            goto tryline;
    11471102
    1148         /* If we get here, the string is all printable and NUL-terminated,
    1149          * so print it.  It is all in 'buf' and 'i' is its length.  */
     1103        /* If we get here, the string is all printable and NUL-terminated */
    11501104        buf[i] = 0;
    11511105        format_address(address - i - 1, ' ');
     
    11681122    /* We reach this point only if we search through
    11691123       (max_bytes_to_format - string_min) bytes before reaching EOF.  */
     1124    check_and_close();
     1125 ret:
    11701126    free(buf);
    1171 
    1172     check_and_close();
    1173 }
     1127}
     1128
     1129#if ENABLE_LONG_OPTS
     1130/* If S is a valid traditional offset specification with an optional
     1131   leading '+' return nonzero and set *OFFSET to the offset it denotes.  */
     1132
     1133static int
     1134parse_old_offset(const char *s, off_t *offset)
     1135{
     1136    static const struct suffix_mult Bb[] = {
     1137        { "B", 1024 },
     1138        { "b", 512 },
     1139        { "", 0 }
     1140    };
     1141    char *p;
     1142    int radix;
     1143
     1144    /* Skip over any leading '+'. */
     1145    if (s[0] == '+') ++s;
     1146    if (!isdigit(s[0])) return 0; /* not a number */
     1147
     1148    /* Determine the radix we'll use to interpret S.  If there is a '.',
     1149     * it's decimal, otherwise, if the string begins with '0X'or '0x',
     1150     * it's hexadecimal, else octal.  */
     1151    p = strchr(s, '.');
     1152    radix = 8;
     1153    if (p) {
     1154        p[0] = '\0'; /* cheating */
     1155        radix = 10;
     1156    } else if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
     1157        radix = 16;
     1158
     1159    *offset = xstrtooff_sfx(s, radix, Bb);
     1160    if (p) p[0] = '.';
     1161
     1162    return (*offset >= 0);
     1163}
     1164#endif
    11741165
    11751166int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    1176 int od_main(int argc, char **argv)
     1167int od_main(int argc UNUSED_PARAM, char **argv)
    11771168{
    11781169    static const struct suffix_mult bkm[] = {
     
    11811172        { "m", 1024*1024 },
    11821173        { "", 0 }
    1183     };
    1184     enum {
    1185         OPT_A = 1 << 0,
    1186         OPT_N = 1 << 1,
    1187         OPT_a = 1 << 2,
    1188         OPT_b = 1 << 3,
    1189         OPT_c = 1 << 4,
    1190         OPT_d = 1 << 5,
    1191         OPT_f = 1 << 6,
    1192         OPT_h = 1 << 7,
    1193         OPT_i = 1 << 8,
    1194         OPT_j = 1 << 9,
    1195         OPT_l = 1 << 10,
    1196         OPT_o = 1 << 11,
    1197         OPT_t = 1 << 12,
    1198         OPT_v = 1 << 13,
    1199         OPT_x = 1 << 14,
    1200         OPT_s = 1 << 15,
    1201         OPT_S = 1 << 16,
    1202         OPT_w = 1 << 17,
    1203         OPT_traditional = (1 << 18) * ENABLE_LONG_OPTS,
    12041174    };
    12051175#if ENABLE_LONG_OPTS
     
    12101180        "format\0"            Required_argument "t"
    12111181        "output-duplicates\0" No_argument       "v"
     1182        /* Yes, it's true: -S NUM, but --strings[=NUM]!
     1183         * that is, NUM is mandatory for -S but optional for --strings!
     1184         */
    12121185        "strings\0"           Optional_argument "S"
    12131186        "width\0"             Optional_argument "w"
     
    12151188        ;
    12161189#endif
    1217     char *str_A, *str_N, *str_j, *str_S;
     1190    const char *str_A, *str_N, *str_j, *str_S = "3";
    12181191    llist_t *lst_t = NULL;
    12191192    unsigned opt;
    12201193    int l_c_m;
    1221     /* The old-style 'pseudo starting address' to be printed in parentheses
    1222        after any true address.  */
    1223     off_t pseudo_start = pseudo_start; // for gcc
    12241194    /* The number of input bytes to skip before formatting and writing.  */
    12251195    off_t n_bytes_to_skip = 0;
     
    12331203    address_base_char = 'o';
    12341204    address_pad_len_char = '7';
    1235     /* flag_dump_strings = 0; - already is */
    12361205
    12371206    /* Parse command line */
     
    12401209    applet_long_options = od_longopts;
    12411210#endif
    1242     opt = getopt32(argv, "A:N:abcdfhij:lot:vxsS:"
    1243         "w::", // -w with optional param
    1244         // -S was -s and also had optional parameter
    1245         // but in coreutils 6.3 it was renamed and now has
    1246         // _mandatory_ parameter
    1247         &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block);
    1248     argc -= optind;
     1211    opt = OD_GETOPT32();
    12491212    argv += optind;
    12501213    if (opt & OPT_A) {
     
    12681231    }
    12691232    if (opt & OPT_N) {
    1270         limit_bytes_to_format = 1;
    12711233        max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm);
    12721234    }
     
    12811243    if (opt & OPT_l) decode_format_string("d4");
    12821244    if (opt & OPT_o) decode_format_string("o2");
    1283     //if (opt & OPT_t)...
    12841245    while (lst_t) {
    12851246        decode_format_string(llist_pop(&lst_t));
    12861247    }
    1287     if (opt & OPT_v) verbose = 1;
    12881248    if (opt & OPT_x) decode_format_string("x2");
    12891249    if (opt & OPT_s) decode_format_string("d2");
    12901250    if (opt & OPT_S) {
    1291         string_min = 3;
    12921251        string_min = xstrtou_sfx(str_S, 0, bkm);
    1293         flag_dump_strings = 1;
    1294     }
    1295     //if (opt & OPT_w)...
    1296     //if (opt & OPT_traditional)...
    1297 
    1298     if (flag_dump_strings && n_specs > 0)
    1299         bb_error_msg_and_die("no type may be specified when dumping strings");
     1252    }
     1253
     1254    // Bloat:
     1255    //if ((option_mask32 & OPT_S) && n_specs > 0)
     1256    //  bb_error_msg_and_die("no type may be specified when dumping strings");
    13001257
    13011258    /* If the --traditional option is used, there may be from
    13021259     * 0 to 3 remaining command line arguments;  handle each case
    13031260     * separately.
    1304      * od [file] [[+]offset[.][b] [[+]label[.][b]]]
     1261     * od [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]
    13051262     * The offset and pseudo_start have the same syntax.
    13061263     *
     
    13101267#if ENABLE_LONG_OPTS
    13111268    if (opt & OPT_traditional) {
    1312         off_t o1, o2;
    1313 
    1314         if (argc == 1) {
    1315             if (parse_old_offset(argv[0], &o1)) {
    1316                 n_bytes_to_skip = o1;
    1317                 --argc;
    1318                 ++argv;
     1269        if (argv[0]) {
     1270            off_t pseudo_start = -1;
     1271            off_t o1, o2;
     1272
     1273            if (!argv[1]) { /* one arg */
     1274                if (parse_old_offset(argv[0], &o1)) {
     1275                    /* od --traditional OFFSET */
     1276                    n_bytes_to_skip = o1;
     1277                    argv++;
     1278                }
     1279                /* od --traditional FILE */
     1280            } else if (!argv[2]) { /* two args */
     1281                if (parse_old_offset(argv[0], &o1)
     1282                 && parse_old_offset(argv[1], &o2)
     1283                ) {
     1284                    /* od --traditional OFFSET LABEL */
     1285                    n_bytes_to_skip = o1;
     1286                    pseudo_start = o2;
     1287                    argv += 2;
     1288                } else if (parse_old_offset(argv[1], &o2)) {
     1289                    /* od --traditional FILE OFFSET */
     1290                    n_bytes_to_skip = o2;
     1291                    argv[1] = NULL;
     1292                } else {
     1293                    bb_error_msg_and_die("invalid second argument '%s'", argv[1]);
     1294                }
     1295            } else if (!argv[3]) { /* three args */
     1296                if (parse_old_offset(argv[1], &o1)
     1297                 && parse_old_offset(argv[2], &o2)
     1298                ) {
     1299                    /* od --traditional FILE OFFSET LABEL */
     1300                    n_bytes_to_skip = o1;
     1301                    pseudo_start = o2;
     1302                    argv[1] = NULL;
     1303                } else {
     1304                    bb_error_msg_and_die("the last two arguments must be offsets");
     1305                }
     1306            } else { /* >3 args */
     1307                bb_error_msg_and_die("too many arguments");
    13191308            }
    1320         } else if (argc == 2) {
    1321             if (parse_old_offset(argv[0], &o1)
    1322              && parse_old_offset(argv[1], &o2)
    1323             ) {
    1324                 n_bytes_to_skip = o1;
    1325                 flag_pseudo_start = 1;
    1326                 pseudo_start = o2;
    1327                 argv += 2;
    1328                 argc -= 2;
    1329             } else if (parse_old_offset(argv[1], &o2)) {
    1330                 n_bytes_to_skip = o2;
    1331                 --argc;
    1332                 argv[1] = argv[0];
    1333                 ++argv;
    1334             } else {
    1335                 bb_error_msg_and_die("invalid second operand "
    1336                     "in compatibility mode '%s'", argv[1]);
     1309
     1310            if (pseudo_start >= 0) {
     1311                if (format_address == format_address_none) {
     1312                    address_base_char = 'o';
     1313                    address_pad_len_char = '7';
     1314                    format_address = format_address_paren;
     1315                } else {
     1316                    format_address = format_address_label;
     1317                }
     1318                pseudo_offset = pseudo_start - n_bytes_to_skip;
    13371319            }
    1338         } else if (argc == 3) {
    1339             if (parse_old_offset(argv[1], &o1)
    1340              && parse_old_offset(argv[2], &o2)
    1341             ) {
    1342                 n_bytes_to_skip = o1;
    1343                 flag_pseudo_start = 1;
    1344                 pseudo_start = o2;
    1345                 argv[2] = argv[0];
    1346                 argv += 2;
    1347                 argc -= 2;
    1348             } else {
    1349                 bb_error_msg_and_die("in compatibility mode "
    1350                     "the last two arguments must be offsets");
    1351             }
    1352         } else if (argc > 3)    {
    1353             bb_error_msg_and_die("compatibility mode supports "
    1354                 "at most three arguments");
    1355         }
    1356 
    1357         if (flag_pseudo_start) {
    1358             if (format_address == format_address_none) {
    1359                 address_base_char = 'o';
    1360                 address_pad_len_char = '7';
    1361                 format_address = format_address_paren;
    1362             } else
    1363                 format_address = format_address_label;
    1364         }
    1365     }
    1366 #endif
    1367 
    1368     if (limit_bytes_to_format) {
     1320        }
     1321        /* else: od --traditional (without args) */
     1322    }
     1323#endif
     1324
     1325    if (option_mask32 & OPT_N) {
    13691326        end_offset = n_bytes_to_skip + max_bytes_to_format;
    13701327        if (end_offset < n_bytes_to_skip)
    1371             bb_error_msg_and_die("skip-bytes + read-bytes is too large");
     1328            bb_error_msg_and_die("SKIP + SIZE is too large");
    13721329    }
    13731330
    13741331    if (n_specs == 0) {
    13751332        decode_format_string("o2");
    1376         n_specs = 1;
     1333        /*n_specs = 1; - done by decode_format_string */
    13771334    }
    13781335
     
    13811338       references the null-terminated list of one name: "-".  */
    13821339    file_list = bb_argv_dash;
    1383     if (argc > 0) {
     1340    if (argv[0]) {
    13841341        /* Set the global pointer FILE_LIST so that it
    13851342           references the first file-argument on the command-line.  */
     
    13871344    }
    13881345
    1389     /* open the first input file */
     1346    /* Open the first input file */
    13901347    open_next_file();
    1391     /* skip over any unwanted header bytes */
     1348    /* Skip over any unwanted header bytes */
    13921349    skip(n_bytes_to_skip);
    13931350    if (!in_stream)
    13941351        return EXIT_FAILURE;
    13951352
    1396     pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);
    1397 
    1398     /* Compute output block length.  */
     1353    /* Compute output block length */
    13991354    l_c_m = get_lcm();
    14001355
     
    14181373#endif
    14191374
    1420     if (flag_dump_strings)
     1375    if (option_mask32 & OPT_S)
    14211376        dump_strings(n_bytes_to_skip, end_offset);
    14221377    else
    14231378        dump(n_bytes_to_skip, end_offset);
    14241379
    1425     if (fclose(stdin) == EOF)
     1380    if (fclose(stdin))
    14261381        bb_perror_msg_and_die(bb_msg_standard_input);
    14271382
    1428     return ioerror;
    1429 }
     1383    return exit_code;
     1384}
  • branches/3.2/mindi-busybox/coreutils/printenv.c

    r2725 r3232  
    88 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 */
     10
     11//usage:#define printenv_trivial_usage
     12//usage:       "[VARIABLE]..."
     13//usage:#define printenv_full_usage "\n\n"
     14//usage:       "Print environment VARIABLEs.\n"
     15//usage:       "If no VARIABLE specified, print all."
    1016
    1117#include "libbb.h"
     
    2026    /* no variables specified, show whole env */
    2127    if (!argv[1]) {
    22         int e = 0;
    23         while (environ[e])
    24             puts(environ[e++]);
     28        char **e = environ;
     29
     30        /* environ can be NULL! (for example, after clearenv())
     31         * Check for that:
     32         */
     33        if (e)
     34            while (*e)
     35                puts(*e++);
    2536    } else {
    2637        /* search for specified variables and print them out if found */
  • branches/3.2/mindi-busybox/coreutils/printf.c

    r2725 r3232  
    3737*/
    3838
    39 //   19990508 Busy Boxed! Dave Cinege
     39/* 19990508 Busy Boxed! Dave Cinege */
     40
     41//usage:#define printf_trivial_usage
     42//usage:       "FORMAT [ARG]..."
     43//usage:#define printf_full_usage "\n\n"
     44//usage:       "Format and print ARG(s) according to FORMAT (a-la C printf)"
     45//usage:
     46//usage:#define printf_example_usage
     47//usage:       "$ printf \"Val=%d\\n\" 5\n"
     48//usage:       "Val=5\n"
    4049
    4150#include "libbb.h"
     
    123132}
    124133
     134/* Handles %b */
    125135static void print_esc_string(const char *str)
    126136{
     
    128138    while ((c = *str) != '\0') {
    129139        str++;
    130         if (c == '\\')
    131             c = bb_process_escape_sequence(&str);
     140        if (c == '\\') {
     141            /* %b also accepts 4-digit octals of the form \0### */
     142            if (*str == '0') {
     143                if ((unsigned char)(str[1] - '0') < 8) {
     144                    /* 2nd char is 0..7: skip leading '0' */
     145                    str++;
     146                }
     147            }
     148            {
     149                /* optimization: don't force arg to be on-stack,
     150                 * use another variable for that. */
     151                const char *z = str;
     152                c = bb_process_escape_sequence(&z);
     153                str = z;
     154            }
     155        }
    132156        putchar(c);
    133157    }
  • branches/3.2/mindi-busybox/coreutils/pwd.c

    r2725 r3232  
    88 */
    99
     10//usage:#define pwd_trivial_usage
     11//usage:       ""
     12//usage:#define pwd_full_usage "\n\n"
     13//usage:       "Print the full filename of the current working directory"
     14//usage:
     15//usage:#define pwd_example_usage
     16//usage:       "$ pwd\n"
     17//usage:       "/root\n"
     18
    1019#include "libbb.h"
    1120
    1221/* This is a NOFORK applet. Be very careful! */
     22
     23static int logical_getcwd(void)
     24{
     25    struct stat st1;
     26    struct stat st2;
     27    char *wd;
     28    char *p;
     29
     30    wd = getenv("PWD");
     31    if (!wd || wd[0] != '/')
     32        return 0;
     33
     34    p = wd;
     35    while (*p) {
     36        /* doing strstr(p, "/.") by hand is smaller and faster... */
     37        if (*p++ != '/')
     38            continue;
     39        if (*p != '.')
     40            continue;
     41        /* we found "/.", skip to next char */
     42        p++;
     43        if (*p == '.')
     44            p++; /* we found "/.." */
     45        if (*p == '\0' || *p == '/')
     46            return 0; /* "/./" or "/../" component: bad */
     47    }
     48
     49    if (stat(wd, &st1) != 0)
     50        return 0;
     51    if (stat(".", &st2) != 0)
     52        return 0;
     53    if (st1.st_ino != st2.st_ino)
     54        return 0;
     55    if (st1.st_dev != st2.st_dev)
     56        return 0;
     57
     58    puts(wd);
     59    return 1;
     60}
    1361
    1462int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     
    1765    char *buf;
    1866
     67    if (ENABLE_DESKTOP) {
     68        /* TODO: assume -L if $POSIXLY_CORRECT? (coreutils does that)
     69         * Rationale:
     70         * POSIX requires a default of -L, but most scripts expect -P
     71         */
     72        unsigned opt = getopt32(argv, "LP");
     73        if ((opt & 1) && logical_getcwd())
     74            return fflush_all();
     75    }
     76
    1977    buf = xrealloc_getcwd_or_warn(NULL);
    20     if (buf != NULL) {
     78
     79    if (buf) {
    2180        puts(buf);
    2281        free(buf);
  • branches/3.2/mindi-busybox/coreutils/readlink.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define readlink_trivial_usage
     11//usage:    IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE"
     12//usage:#define readlink_full_usage "\n\n"
     13//usage:       "Display the value of a symlink"
     14//usage:    IF_FEATURE_READLINK_FOLLOW( "\n"
     15//usage:     "\n    -f  Canonicalize by following all symlinks"
     16//usage:     "\n    -n  Don't add newline"
     17//usage:     "\n    -v  Verbose"
     18//usage:    )
     19
    920#include "libbb.h"
    1021
  • branches/3.2/mindi-busybox/coreutils/realpath.c

    r2725 r3232  
    1010 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1111 */
     12
     13//usage:#define realpath_trivial_usage
     14//usage:       "FILE..."
     15//usage:#define realpath_full_usage "\n\n"
     16//usage:       "Return the absolute pathnames of given FILE"
    1217
    1318#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/rm.c

    r2725 r3232  
    1515 * Size reduction.
    1616 */
     17
     18//usage:#define rm_trivial_usage
     19//usage:       "[-irf] FILE..."
     20//usage:#define rm_full_usage "\n\n"
     21//usage:       "Remove (unlink) FILEs\n"
     22//usage:     "\n    -i  Always prompt before removing"
     23//usage:     "\n    -f  Never prompt"
     24//usage:     "\n    -R,-r   Recurse"
     25//usage:
     26//usage:#define rm_example_usage
     27//usage:       "$ rm -rf /tmp/foo\n"
    1728
    1829#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/rmdir.c

    r2725 r3232  
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
    1212
     13//usage:#define rmdir_trivial_usage
     14//usage:       "[OPTIONS] DIRECTORY..."
     15//usage:#define rmdir_full_usage "\n\n"
     16//usage:       "Remove DIRECTORY if it is empty\n"
     17//usage:    IF_FEATURE_RMDIR_LONG_OPTIONS(
     18//usage:     "\n    -p|--parents    Include parents"
     19//usage:     "\n    --ignore-fail-on-non-empty"
     20//usage:    )
     21//usage:    IF_NOT_FEATURE_RMDIR_LONG_OPTIONS(
     22//usage:     "\n    -p  Include parents"
     23//usage:    )
     24//usage:
     25//usage:#define rmdir_example_usage
     26//usage:       "# rmdir /tmp/foo\n"
     27
    1328#include "libbb.h"
    1429
     
    1631
    1732
    18 #define PARENTS 0x01
    19 #define IGNORE_NON_EMPTY 0x02
     33#define PARENTS          (1 << 0)
     34//efine VERBOSE          (1 << 1) //accepted but ignored
     35#define IGNORE_NON_EMPTY (1 << 2)
    2036
    2137int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     
    2945    static const char rmdir_longopts[] ALIGN1 =
    3046        "parents\0"                  No_argument "p"
     47        "verbose\0"                  No_argument "v"
    3148        /* Debian etch: many packages fail to be purged or installed
    3249         * because they desperately want this option: */
     
    3552    applet_long_options = rmdir_longopts;
    3653#endif
    37     flags = getopt32(argv, "p");
     54    flags = getopt32(argv, "pv");
    3855    argv += optind;
    3956
  • branches/3.2/mindi-busybox/coreutils/seq.c

    r2725 r3232  
    77 * Licensed under GPLv2, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define seq_trivial_usage
     11//usage:       "[-w] [-s SEP] [FIRST [INC]] LAST"
     12//usage:#define seq_full_usage "\n\n"
     13//usage:       "Print numbers from FIRST to LAST, in steps of INC.\n"
     14//usage:       "FIRST, INC default to 1.\n"
     15//usage:     "\n    -w  Pad to last with leading zeros"
     16//usage:     "\n    -s SEP  String separator"
     17
    918#include "libbb.h"
    1019
  • branches/3.2/mindi-busybox/coreutils/sleep.c

    r2725 r3232  
    1818 * time suffixes for seconds, minutes, hours, and days.
    1919 */
     20
     21//usage:#define sleep_trivial_usage
     22//usage:    IF_FEATURE_FANCY_SLEEP("[") "N" IF_FEATURE_FANCY_SLEEP("]...")
     23//usage:#define sleep_full_usage "\n\n"
     24//usage:    IF_NOT_FEATURE_FANCY_SLEEP("Pause for N seconds")
     25//usage:    IF_FEATURE_FANCY_SLEEP(
     26//usage:       "Pause for a time equal to the total of the args given, where each arg can\n"
     27//usage:       "have an optional suffix of (s)econds, (m)inutes, (h)ours, or (d)ays")
     28//usage:
     29//usage:#define sleep_example_usage
     30//usage:       "$ sleep 2\n"
     31//usage:       "[2 second delay results]\n"
     32//usage:    IF_FEATURE_FANCY_SLEEP(
     33//usage:       "$ sleep 1d 3h 22m 8s\n"
     34//usage:       "[98528 second delay results]\n")
    2035
    2136#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/sort.c

    r2725 r3232  
    1212 * http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
    1313 */
     14
     15//usage:#define sort_trivial_usage
     16//usage:       "[-nru"
     17//usage:    IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR")
     18//usage:       "] [FILE]..."
     19//usage:#define sort_full_usage "\n\n"
     20//usage:       "Sort lines of text\n"
     21//usage:    IF_FEATURE_SORT_BIG(
     22//usage:     "\n    -b  Ignore leading blanks"
     23//usage:     "\n    -c  Check whether input is sorted"
     24//usage:     "\n    -d  Dictionary order (blank or alphanumeric only)"
     25//usage:     "\n    -f  Ignore case"
     26//usage:     "\n    -g  General numerical sort"
     27//usage:     "\n    -i  Ignore unprintable characters"
     28//usage:     "\n    -k  Sort key"
     29//usage:     "\n    -M  Sort month"
     30//usage:    )
     31//usage:     "\n    -n  Sort numbers"
     32//usage:    IF_FEATURE_SORT_BIG(
     33//usage:     "\n    -o  Output to file"
     34//usage:     "\n    -k  Sort by key"
     35//usage:     "\n    -t CHAR Key separator"
     36//usage:    )
     37//usage:     "\n    -r  Reverse sort order"
     38//usage:    IF_FEATURE_SORT_BIG(
     39//usage:     "\n    -s  Stable (don't sort ties alphabetically)"
     40//usage:    )
     41//usage:     "\n    -u  Suppress duplicate lines"
     42//usage:    IF_FEATURE_SORT_BIG(
     43//usage:     "\n    -z  Lines are terminated by NUL, not newline"
     44//usage:     "\n    -mST    Ignored for GNU compatibility")
     45//usage:
     46//usage:#define sort_example_usage
     47//usage:       "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n"
     48//usage:       "a\n"
     49//usage:       "b\n"
     50//usage:       "c\n"
     51//usage:       "d\n"
     52//usage:       "e\n"
     53//usage:       "f\n"
     54//usage:    IF_FEATURE_SORT_BIG(
     55//usage:        "$ echo -e \"c 3\\nb 2\\nd 2\" | $SORT -k 2,2n -k 1,1r\n"
     56//usage:        "d 2\n"
     57//usage:        "b 2\n"
     58//usage:        "c 3\n"
     59//usage:    )
     60//usage:       ""
    1461
    1562#include "libbb.h"
     
    173220#else
    174221    /* This curly bracket serves no purpose but to match the nesting
    175        level of the for () loop we're not using */
     222     * level of the for () loop we're not using */
    176223    {
    177224        x = *(char **)xarg;
  • branches/3.2/mindi-busybox/coreutils/split.c

    r2725 r3232  
    1010 * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html
    1111 */
     12
     13//usage:#define split_trivial_usage
     14//usage:       "[OPTIONS] [INPUT [PREFIX]]"
     15//usage:#define split_full_usage "\n\n"
     16//usage:       "    -b N[k|m]   Split by N (kilo|mega)bytes"
     17//usage:     "\n    -l N        Split by N lines"
     18//usage:     "\n    -a N        Use N letters as suffix"
     19//usage:
     20//usage:#define split_example_usage
     21//usage:       "$ split TODO foo\n"
     22//usage:       "$ cat TODO | split -a 2 -l 2 TODO_\n"
     23
    1224#include "libbb.h"
    1325
     
    3345    char *curr;
    3446
    35     do {
     47    while (1) {
    3648        curr = old + end - i;
    3749        if (*curr < 'z') {
     
    4456        }
    4557        *curr = 'a';
    46     } while (1);
     58    }
    4759
    4860    return old;
  • branches/3.2/mindi-busybox/coreutils/stat.c

    r2725 r3232  
    1313 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1414 */
     15
     16//usage:#define stat_trivial_usage
     17//usage:       "[OPTIONS] FILE..."
     18//usage:#define stat_full_usage "\n\n"
     19//usage:       "Display file (default) or filesystem status\n"
     20//usage:    IF_FEATURE_STAT_FORMAT(
     21//usage:     "\n    -c fmt  Use the specified format"
     22//usage:    )
     23//usage:     "\n    -f  Display filesystem status"
     24//usage:     "\n    -L  Follow links"
     25//usage:     "\n    -t  Display info in terse form"
     26//usage:    IF_SELINUX(
     27//usage:     "\n    -Z  Print security context"
     28//usage:    )
     29//usage:    IF_FEATURE_STAT_FORMAT(
     30//usage:       "\n\nValid format sequences for files:\n"
     31//usage:       " %a Access rights in octal\n"
     32//usage:       " %A Access rights in human readable form\n"
     33//usage:       " %b Number of blocks allocated (see %B)\n"
     34//usage:       " %B The size in bytes of each block reported by %b\n"
     35//usage:       " %d Device number in decimal\n"
     36//usage:       " %D Device number in hex\n"
     37//usage:       " %f Raw mode in hex\n"
     38//usage:       " %F File type\n"
     39//usage:       " %g Group ID of owner\n"
     40//usage:       " %G Group name of owner\n"
     41//usage:       " %h Number of hard links\n"
     42//usage:       " %i Inode number\n"
     43//usage:       " %n File name\n"
     44//usage:       " %N File name, with -> TARGET if symlink\n"
     45//usage:       " %o I/O block size\n"
     46//usage:       " %s Total size, in bytes\n"
     47//usage:       " %t Major device type in hex\n"
     48//usage:       " %T Minor device type in hex\n"
     49//usage:       " %u User ID of owner\n"
     50//usage:       " %U User name of owner\n"
     51//usage:       " %x Time of last access\n"
     52//usage:       " %X Time of last access as seconds since Epoch\n"
     53//usage:       " %y Time of last modification\n"
     54//usage:       " %Y Time of last modification as seconds since Epoch\n"
     55//usage:       " %z Time of last change\n"
     56//usage:       " %Z Time of last change as seconds since Epoch\n"
     57//usage:       "\nValid format sequences for file systems:\n"
     58//usage:       " %a Free blocks available to non-superuser\n"
     59//usage:       " %b Total data blocks in file system\n"
     60//usage:       " %c Total file nodes in file system\n"
     61//usage:       " %d Free file nodes in file system\n"
     62//usage:       " %f Free blocks in file system\n"
     63//usage:    IF_SELINUX(
     64//usage:       " %C Security context in selinux\n"
     65//usage:    )
     66//usage:       " %i File System ID in hex\n"
     67//usage:       " %l Maximum length of filenames\n"
     68//usage:       " %n File name\n"
     69//usage:       " %s Block size (for faster transfer)\n"
     70//usage:       " %S Fundamental block size (for block counts)\n"
     71//usage:       " %t Type in hex\n"
     72//usage:       " %T Type in human readable form"
     73//usage:    )
     74
    1575#include "libbb.h"
    1676
     
    40100    if (S_ISLNK(st->st_mode))  return "symbolic link";
    41101    if (S_ISSOCK(st->st_mode)) return "socket";
     102#ifdef S_TYPEISMQ
    42103    if (S_TYPEISMQ(st))        return "message queue";
     104#endif
     105#ifdef S_TYPEISSEM
    43106    if (S_TYPEISSEM(st))       return "semaphore";
     107#endif
     108#ifdef S_TYPEISSHM
    44109    if (S_TYPEISSHM(st))       return "shared memory object";
     110#endif
    45111#ifdef S_TYPEISTMO
    46112    if (S_TYPEISTMO(st))       return "typed memory object";
     
    377443            ) < 0
    378444        ) {
    379             bb_perror_msg(filename);
     445            bb_simple_perror_msg(filename);
    380446            return 0;
    381447        }
     
    490556            ) < 0
    491557        ) {
    492             bb_perror_msg(filename);
     558            bb_simple_perror_msg(filename);
    493559            return 0;
    494560        }
     
    526592        if (option_mask32 & OPT_TERSE) {
    527593            format = (option_mask32 & OPT_SELINUX ?
    528                   "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n":
    529                   "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n");
     594                "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"
     595                :
     596                "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"
     597                );
    530598        } else {
    531599            if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
    532600                format = (option_mask32 & OPT_SELINUX ?
    533                       "  File: %N\n"
    534                       "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
    535                       "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
    536                       " Device type: %t,%T\n"
    537                       "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
    538                       "   S_Context: %C\n"
    539                       "Access: %x\n" "Modify: %y\n" "Change: %z\n":
    540                       "  File: %N\n"
    541                       "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
    542                       "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
    543                       " Device type: %t,%T\n"
    544                       "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
    545                       "Access: %x\n" "Modify: %y\n" "Change: %z\n");
     601                    "  File: %N\n"
     602                    "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     603                    "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
     604                    " Device type: %t,%T\n"
     605                    "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     606                    "   S_Context: %C\n"
     607                    "Access: %x\n" "Modify: %y\n" "Change: %z\n"
     608                    :
     609                    "  File: %N\n"
     610                    "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     611                    "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
     612                    " Device type: %t,%T\n"
     613                    "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     614                    "Access: %x\n" "Modify: %y\n" "Change: %z\n"
     615                    );
    546616            } else {
    547617                format = (option_mask32 & OPT_SELINUX ?
    548                       "  File: %N\n"
    549                       "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
    550                       "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
    551                       "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
    552                       "S_Context: %C\n"
    553                       "Access: %x\n" "Modify: %y\n" "Change: %z\n":
    554                       "  File: %N\n"
    555                       "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
    556                       "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
    557                       "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
    558                       "Access: %x\n" "Modify: %y\n" "Change: %z\n");
     618                    "  File: %N\n"
     619                    "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     620                    "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
     621                    "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     622                    "S_Context: %C\n"
     623                    "Access: %x\n" "Modify: %y\n" "Change: %z\n"
     624                    :
     625                    "  File: %N\n"
     626                    "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     627                    "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
     628                    "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     629                    "Access: %x\n" "Modify: %y\n" "Change: %z\n"
     630                    );
    559631            }
    560632        }
  • branches/3.2/mindi-busybox/coreutils/stty.c

    r2725 r3232  
    2222   */
    2323
     24//usage:#define stty_trivial_usage
     25//usage:       "[-a|g] [-F DEVICE] [SETTING]..."
     26//usage:#define stty_full_usage "\n\n"
     27//usage:       "Without arguments, prints baud rate, line discipline,\n"
     28//usage:       "and deviations from stty sane\n"
     29//usage:     "\n    -F DEVICE   Open device instead of stdin"
     30//usage:     "\n    -a      Print all current settings in human-readable form"
     31//usage:     "\n    -g      Print in stty-readable form"
     32//usage:     "\n    [SETTING]   See manpage"
     33
    2434#include "libbb.h"
    2535
     
    5969#if defined(VEOL2) && !defined(CEOL2)
    6070# define CEOL2 _POSIX_VDISABLE
     71#endif
     72/* glibc-2.12.1 uses only VSWTC name */
     73#if defined(VSWTC) && !defined(VSWTCH)
     74# define VSWTCH VSWTC
    6175#endif
    6276/* ISC renamed swtch to susp for termios, but we'll accept either name */
     
    221235#ifndef XCASE
    222236# define XCASE 0
     237#endif
     238#ifndef IUTF8
     239# define IUTF8 0
    223240#endif
    224241
     
    339356    MI_ENTRY("ixon",     input,       REV,               IXON,       0 )
    340357    MI_ENTRY("ixoff",    input,       SANE_UNSET | REV,  IXOFF,      0 )
    341     MI_ENTRY("tandem",   input,       REV        | OMIT, IXOFF,      0 )
     358    MI_ENTRY("tandem",   input,       OMIT       | REV, IXOFF,      0 )
    342359#if IUCLC
    343360    MI_ENTRY("iuclc",    input,       SANE_UNSET | REV,  IUCLC,      0 )
     
    348365#if IMAXBEL
    349366    MI_ENTRY("imaxbel",  input,       SANE_SET   | REV,  IMAXBEL,    0 )
     367#endif
     368#if IUTF8
     369    MI_ENTRY("iutf8",    input,       SANE_UNSET | REV,  IUTF8,      0 )
    350370#endif
    351371    MI_ENTRY("opost",    output,      SANE_SET   | REV,  OPOST,      0 )
     
    416436    MI_ENTRY("echo",     local,       SANE_SET   | REV,  ECHO,       0 )
    417437    MI_ENTRY("echoe",    local,       SANE_SET   | REV,  ECHOE,      0 )
    418     MI_ENTRY("crterase", local,       REV        | OMIT, ECHOE,      0 )
     438    MI_ENTRY("crterase", local,       OMIT       | REV, ECHOE,      0 )
    419439    MI_ENTRY("echok",    local,       SANE_SET   | REV,  ECHOK,      0 )
    420440    MI_ENTRY("echonl",   local,       SANE_UNSET | REV,  ECHONL,     0 )
     
    428448#if ECHOPRT
    429449    MI_ENTRY("echoprt",  local,       SANE_UNSET | REV,  ECHOPRT,    0 )
    430     MI_ENTRY("prterase", local,       REV | OMIT,        ECHOPRT,    0 )
     450    MI_ENTRY("prterase", local,       OMIT       | REV,  ECHOPRT,    0 )
    431451#endif
    432452#if ECHOCTL
    433453    MI_ENTRY("echoctl",  local,       SANE_SET   | REV,  ECHOCTL,    0 )
    434     MI_ENTRY("ctlecho",  local,       REV        | OMIT, ECHOCTL,    0 )
     454    MI_ENTRY("ctlecho",  local,       OMIT       | REV, ECHOCTL,    0 )
    435455#endif
    436456#if ECHOKE
    437457    MI_ENTRY("echoke",   local,       SANE_SET   | REV,  ECHOKE,     0 )
    438     MI_ENTRY("crtkill",  local,       REV        | OMIT, ECHOKE,     0 )
     458    MI_ENTRY("crtkill",  local,       OMIT       | REV, ECHOKE,     0 )
    439459#endif
    440460    ;
     
    493513    MI_ENTRY("ixon",     input,       REV,               IXON,       0 )
    494514    MI_ENTRY("ixoff",    input,       SANE_UNSET | REV,  IXOFF,      0 )
    495     MI_ENTRY("tandem",   input,       REV        | OMIT, IXOFF,      0 )
     515    MI_ENTRY("tandem",   input,       OMIT       | REV, IXOFF,      0 )
    496516#if IUCLC
    497517    MI_ENTRY("iuclc",    input,       SANE_UNSET | REV,  IUCLC,      0 )
     
    502522#if IMAXBEL
    503523    MI_ENTRY("imaxbel",  input,       SANE_SET   | REV,  IMAXBEL,    0 )
     524#endif
     525#if IUTF8
     526    MI_ENTRY("iutf8",    input,       SANE_UNSET | REV,  IUTF8,      0 )
    504527#endif
    505528    MI_ENTRY("opost",    output,      SANE_SET   | REV,  OPOST,      0 )
     
    570593    MI_ENTRY("echo",     local,       SANE_SET   | REV,  ECHO,       0 )
    571594    MI_ENTRY("echoe",    local,       SANE_SET   | REV,  ECHOE,      0 )
    572     MI_ENTRY("crterase", local,       REV        | OMIT, ECHOE,      0 )
     595    MI_ENTRY("crterase", local,       OMIT       | REV, ECHOE,      0 )
    573596    MI_ENTRY("echok",    local,       SANE_SET   | REV,  ECHOK,      0 )
    574597    MI_ENTRY("echonl",   local,       SANE_UNSET | REV,  ECHONL,     0 )
     
    582605#if ECHOPRT
    583606    MI_ENTRY("echoprt",  local,       SANE_UNSET | REV,  ECHOPRT,    0 )
    584     MI_ENTRY("prterase", local,       REV | OMIT,        ECHOPRT,    0 )
     607    MI_ENTRY("prterase", local,       OMIT       | REV,  ECHOPRT,    0 )
    585608#endif
    586609#if ECHOCTL
    587610    MI_ENTRY("echoctl",  local,       SANE_SET   | REV,  ECHOCTL,    0 )
    588     MI_ENTRY("ctlecho",  local,       REV        | OMIT, ECHOCTL,    0 )
     611    MI_ENTRY("ctlecho",  local,       OMIT       | REV, ECHOCTL,    0 )
    589612#endif
    590613#if ECHOKE
    591614    MI_ENTRY("echoke",   local,       SANE_SET   | REV,  ECHOKE,     0 )
    592     MI_ENTRY("crtkill",  local,       REV        | OMIT, ECHOKE,     0 )
     615    MI_ENTRY("crtkill",  local,       OMIT       | REV, ECHOKE,     0 )
    593616#endif
    594617};
     
    9921015    unsigned long ispeed, ospeed;
    9931016
    994     ospeed = ispeed = cfgetispeed(mode);
    995     if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) {
     1017    ispeed = cfgetispeed(mode);
     1018    ospeed = cfgetospeed(mode);
     1019    if (ispeed == 0 || ispeed == ospeed) {
    9961020        ispeed = ospeed;                /* in case ispeed was 0 */
    9971021        //________ 0123 4 5 6 7 8 9
     
    10121036    if (all)
    10131037        display_window_size(1);
    1014 #ifdef HAVE_C_LINE
     1038#ifdef __linux__
    10151039    wrapf("line = %u;\n", mode->c_line);
    10161040#else
     
    10331057#endif
    10341058        wrapf("%s = %s;", nth_string(control_name, i),
    1035               visible(mode->c_cc[control_info[i].offset]));
     1059                visible(mode->c_cc[control_info[i].offset]));
    10361060    }
    10371061#if VEOF == VMIN
     
    13451369
    13461370        switch (param) {
    1347 #ifdef HAVE_C_LINE
     1371#ifdef __linux__
    13481372        case param_line:
    13491373# ifndef TIOCGWINSZ
     
    13811405    /* Specifying both -a and -g is an error */
    13821406    if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) ==
    1383         (STTY_verbose_output | STTY_recoverable_output))
    1384         bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive");
     1407        (STTY_verbose_output | STTY_recoverable_output)
     1408    ) {
     1409        bb_error_msg_and_die("-a and -g are mutually exclusive");
     1410    }
    13851411    /* Specifying -a or -g with non-options is an error */
    1386     if (!(stty_state & STTY_noargs)
    1387      && (stty_state & (STTY_verbose_output | STTY_recoverable_output))
     1412    if ((stty_state & (STTY_verbose_output | STTY_recoverable_output))
     1413     && !(stty_state & STTY_noargs)
    13881414    ) {
    1389         bb_error_msg_and_die("modes may not be set when specifying an output style");
     1415        bb_error_msg_and_die("modes may not be set when -a or -g is used");
    13901416    }
    13911417
     
    14491475
    14501476        switch (param) {
    1451 #ifdef HAVE_C_LINE
     1477#ifdef __linux__
    14521478        case param_line:
    14531479            mode.c_line = xatoul_sfx(argnext, stty_suffixes);
  • branches/3.2/mindi-busybox/coreutils/sum.c

    r2725 r3232  
    1313 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1414 */
     15
     16//usage:#define sum_trivial_usage
     17//usage:       "[-rs] [FILE]..."
     18//usage:#define sum_full_usage "\n\n"
     19//usage:       "Checksum and count the blocks in a file\n"
     20//usage:     "\n    -r  Use BSD sum algorithm (1K blocks)"
     21//usage:     "\n    -s  Use System V sum algorithm (512byte blocks)"
    1522
    1623#include "libbb.h"
     
    8895    } else {
    8996        /* Need to print the name if either
    90            - more than one file given
    91            - doing sysv */
     97         * - more than one file given
     98         * - doing sysv */
    9299        type += (argv[1] || type == SUM_SYSV);
    93100        n = 1;
  • branches/3.2/mindi-busybox/coreutils/sync.c

    r2725 r3232  
    99
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
     11
     12//usage:#define sync_trivial_usage
     13//usage:       ""
     14//usage:#define sync_full_usage "\n\n"
     15//usage:       "Write all buffered blocks to disk"
    1116
    1217#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/tac.c

    r2725 r3232  
    1616 * http://www.uclibc.org/lists/busybox/2003-July/008813.html
    1717 */
     18
     19//usage:#define tac_trivial_usage
     20//usage:    "[FILE]..."
     21//usage:#define tac_full_usage "\n\n"
     22//usage:    "Concatenate FILEs and print them in reverse"
    1823
    1924#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/tail.c

    r2725 r3232  
    2525 */
    2626
     27//usage:#define tail_trivial_usage
     28//usage:       "[OPTIONS] [FILE]..."
     29//usage:#define tail_full_usage "\n\n"
     30//usage:       "Print last 10 lines of each FILE (or stdin) to stdout.\n"
     31//usage:       "With more than one FILE, precede each with a filename header.\n"
     32//usage:     "\n    -f      Print data as file grows"
     33//usage:    IF_FEATURE_FANCY_TAIL(
     34//usage:     "\n    -s SECONDS  Wait SECONDS between reads with -f"
     35//usage:    )
     36//usage:     "\n    -n N[kbm]   Print last N lines"
     37//usage:    IF_FEATURE_FANCY_TAIL(
     38//usage:     "\n    -c N[kbm]   Print last N bytes"
     39//usage:     "\n    -q      Never print headers"
     40//usage:     "\n    -v      Always print headers"
     41//usage:     "\n"
     42//usage:     "\nN may be suffixed by k (x1024), b (x512), or m (x1024^2)."
     43//usage:     "\nIf N starts with a '+', output begins with the Nth item from the start"
     44//usage:     "\nof each file, not from the end."
     45//usage:    )
     46//usage:
     47//usage:#define tail_example_usage
     48//usage:       "$ tail -n 1 /etc/resolv.conf\n"
     49//usage:       "nameserver 10.0.0.1\n"
     50
    2751#include "libbb.h"
    2852
     
    3559
    3660struct globals {
    37     bool status;
     61    bool from_top;
     62    bool exitcode;
    3863} FIX_ALIASING;
    3964#define G (*(struct globals*)&bb_common_bufsiz1)
     65#define INIT_G() do { } while (0)
    4066
    4167static void tail_xprint_header(const char *fmt, const char *filename)
     
    6187    if (r < 0) {
    6288        bb_perror_msg(bb_msg_read_error);
    63         G.status = EXIT_FAILURE;
     89        G.exitcode = EXIT_FAILURE;
    6490    }
    6591
     
    75101    else if (*p == '+') {
    76102        p++;
    77         G.status = 1; /* mark that we saw "+" */
     103        G.from_top = 1;
    78104    }
    79105    return xatou_sfx(p, tail_suffixes);
     
    85111    unsigned count = 10;
    86112    unsigned sleep_period = 1;
    87     bool from_top;
    88113    const char *str_c, *str_n;
    89114
     
    96121    int *fds;
    97122    const char *fmt;
     123
     124    INIT_G();
    98125
    99126#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
     
    128155    argc -= optind;
    129156    argv += optind;
    130     from_top = G.status; /* 1 if there was "-c +N" or "-n +N" */
    131     G.status = EXIT_SUCCESS;
    132157
    133158    /* open all the files */
     
    147172        int fd = open_or_warn_stdin(argv[i]);
    148173        if (fd < 0 && !FOLLOW_RETRY) {
    149             G.status = EXIT_FAILURE;
     174            G.exitcode = EXIT_FAILURE;
    150175            continue;
    151176        }
     
    159184    /* prepare the buffer */
    160185    tailbufsize = BUFSIZ;
    161     if (!from_top && COUNT_BYTES) {
     186    if (!G.from_top && COUNT_BYTES) {
    162187        if (tailbufsize < count + BUFSIZ) {
    163188            tailbufsize = count + BUFSIZ;
    164189        }
    165190    }
    166     tailbuf = xmalloc(tailbufsize);
     191    /* tail -c1024m REGULAR_FILE doesn't really need 1G mem block.
     192     * (In fact, it doesn't need ANY memory). So delay allocation.
     193     */
     194    tailbuf = NULL;
    167195
    168196    /* tail the files */
    169     fmt = header_fmt_str + 1; /* skip header leading newline on first output */
     197
     198    fmt = header_fmt_str + 1; /* skip leading newline in the header on the first output */
    170199    i = 0;
    171200    do {
     
    178207
    179208        if (ENABLE_FEATURE_FANCY_TAIL && fd < 0)
    180             continue; /* may happen with -E */
     209            continue; /* may happen with -F */
    181210
    182211        if (nfiles > header_threshhold) {
     
    185214        }
    186215
    187         if (!from_top) {
     216        if (!G.from_top) {
    188217            off_t current = lseek(fd, 0, SEEK_END);
    189218            if (current > 0) {
     
    218247        }
    219248
     249        if (!tailbuf)
     250            tailbuf = xmalloc(tailbufsize);
     251
    220252        buf = tailbuf;
    221253        taillen = 0;
     
    224256        seen = 1;
    225257        newlines_seen = 0;
    226         while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) {
    227             if (from_top) {
     258        while ((nread = tail_read(fd, buf, tailbufsize - taillen)) > 0) {
     259            if (G.from_top) {
    228260                int nwrite = nread;
    229261                if (seen < count) {
     
    231263                    if (COUNT_BYTES) {
    232264                        nwrite -= (count - seen);
    233                         seen = count;
     265                        seen += nread;
    234266                    } else {
    235267                        char *s = buf;
     
    289321            }
    290322        } /* while (tail_read() > 0) */
    291         if (!from_top) {
     323        if (!G.from_top) {
    292324            xwrite(STDOUT_FILENO, tailbuf, taillen);
    293325        }
     
    344376            }
    345377        } while (++i < nfiles);
    346     }
     378    } /* while (1) */
     379
    347380    if (ENABLE_FEATURE_CLEAN_UP) {
    348381        free(fds);
    349382        free(tailbuf);
    350383    }
    351     return G.status;
     384    return G.exitcode;
    352385}
  • branches/3.2/mindi-busybox/coreutils/tee.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv3 compliant */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
     12
     13//usage:#define tee_trivial_usage
     14//usage:       "[-ai] [FILE]..."
     15//usage:#define tee_full_usage "\n\n"
     16//usage:       "Copy stdin to each FILE, and also to stdout\n"
     17//usage:     "\n    -a  Append to the given FILEs, don't overwrite"
     18//usage:     "\n    -i  Ignore interrupt signals (SIGINT)"
     19//usage:
     20//usage:#define tee_example_usage
     21//usage:       "$ echo \"Hello\" | tee /tmp/foo\n"
     22//usage:       "$ cat /tmp/foo\n"
     23//usage:       "Hello\n"
    1224
    1325#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/test.c

    r2725 r3232  
    4040//config:     Enable 64-bit support in test.
    4141
     42/* "test --help" does not print help (POSIX compat), only "[ --help" does.
     43 * We display "<applet> EXPRESSION ]" here (not "<applet> EXPRESSION")
     44 * Unfortunately, it screws up generated BusyBox.html. TODO. */
     45//usage:#define test_trivial_usage
     46//usage:       "EXPRESSION ]"
     47//usage:#define test_full_usage "\n\n"
     48//usage:       "Check file types, compare values etc. Return a 0/1 exit code\n"
     49//usage:       "depending on logical value of EXPRESSION"
     50//usage:
     51//usage:#define test_example_usage
     52//usage:       "$ test 1 -eq 2\n"
     53//usage:       "$ echo $?\n"
     54//usage:       "1\n"
     55//usage:       "$ test 1 -eq 1\n"
     56//usage:       "$ echo $?\n"
     57//usage:       "0\n"
     58//usage:       "$ [ -d /etc ]\n"
     59//usage:       "$ echo $?\n"
     60//usage:       "0\n"
     61//usage:       "$ [ -d /junk ]\n"
     62//usage:       "$ echo $?\n"
     63//usage:       "1\n"
     64
    4265#include "libbb.h"
    4366#include <setjmp.h>
     
    4669
    4770/* test_main() is called from shells, and we need to be extra careful here.
    48  * This is true regardless of PREFER_APPLETS and STANDALONE_SHELL
     71 * This is true regardless of PREFER_APPLETS and SH_STANDALONE
    4972 * state. */
    5073
     
    588611
    589612        /* Root can execute any file that has any one of the execute
    590            bits set. */
     613         * bits set. */
    591614        if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
    592615            return 0;
     
    688711            /* special case: [ ! ], [ a -a ! ] are valid */
    689712            /* IOW, "! ARG" may miss ARG */
    690             unnest_msg("<nexpr:1 (!EOI)\n");
     713            args--;
     714            unnest_msg("<nexpr:1 (!EOI), args:%s(%p)\n", args[0], &args[0]);
    691715            return 1;
    692716        }
     
    707731    nest_msg(">aexpr(%s)\n", TOKSTR[n]);
    708732    res = nexpr(n);
    709     dbg_msg("aexpr: nexpr:%lld, next args:%s\n", res, args[1]);
     733    dbg_msg("aexpr: nexpr:%lld, next args:%s(%p)\n", res, args[1], &args[1]);
    710734    if (check_operator(*++args) == BAND) {
    711         dbg_msg("aexpr: arg is AND, next args:%s\n", args[1]);
     735        dbg_msg("aexpr: arg is AND, next args:%s(%p)\n", args[1], &args[1]);
    712736        res = aexpr(check_operator(*++args)) && res;
    713737        unnest_msg("<aexpr:%lld\n", res);
     
    715739    }
    716740    args--;
    717     unnest_msg("<aexpr:%lld, args:%s\n", res, args[0]);
     741    unnest_msg("<aexpr:%lld, args:%s(%p)\n", res, args[0], &args[0]);
    718742    return res;
    719743}
     
    726750    nest_msg(">oexpr(%s)\n", TOKSTR[n]);
    727751    res = aexpr(n);
    728     dbg_msg("oexpr: aexpr:%lld, next args:%s\n", res, args[1]);
     752    dbg_msg("oexpr: aexpr:%lld, next args:%s(%p)\n", res, args[1], &args[1]);
    729753    if (check_operator(*++args) == BOR) {
    730         dbg_msg("oexpr: next arg is OR, next args:%s\n", args[1]);
     754        dbg_msg("oexpr: next arg is OR, next args:%s(%p)\n", args[1], &args[1]);
    731755        res = oexpr(check_operator(*++args)) || res;
    732756        unnest_msg("<oexpr:%lld\n", res);
     
    734758    }
    735759    args--;
    736     unnest_msg("<oexpr:%lld, args:%s\n", res, args[0]);
     760    unnest_msg("<oexpr:%lld, args:%s(%p)\n", res, args[0], &args[0]);
    737761    return res;
    738762}
     
    879903
    880904    if (*args != NULL && *++args != NULL) {
    881         /* TODO: example when this happens? */
     905        /* Examples:
     906         * test 3 -lt 5 6
     907         * test -t 1 2
     908         */
    882909        bb_error_msg("%s: unknown operand", *args);
    883910        res = 2;
  • branches/3.2/mindi-busybox/coreutils/touch.c

    r2725 r3232  
    88 */
    99
    10 /* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m, -r, -t not supported. */
     10/* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m not supported. */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */
    1212
     
    1919
    2020#include "libbb.h"
     21
     22//config:config TOUCH
     23//config:   bool "touch"
     24//config:   default y
     25//config:   help
     26//config:     touch is used to create or change the access and/or
     27//config:     modification timestamp of specified files.
     28//config:
     29//config:config FEATURE_TOUCH_SUSV3
     30//config:   bool "Add support for SUSV3 features (-d -t -r)"
     31//config:   default y
     32//config:   depends on TOUCH
     33//config:   help
     34//config:     Enable touch to use a reference file or a given date/time argument.
     35
     36//applet:IF_TOUCH(APPLET_NOFORK(touch, touch, BB_DIR_BIN, BB_SUID_DROP, touch))
     37
     38//kbuild:lib-$(CONFIG_TOUCH) += touch.o
     39
     40//usage:#define touch_trivial_usage
     41//usage:       "[-c]" IF_FEATURE_TOUCH_SUSV3(" [-d DATE] [-t DATE] [-r FILE]") " FILE..."
     42//usage:#define touch_full_usage "\n\n"
     43//usage:       "Update the last-modified date on the given FILE[s]\n"
     44//usage:     "\n    -c  Don't create files"
     45//usage:    IF_FEATURE_TOUCH_SUSV3(
     46//usage:     "\n    -d DT   Date/time to use"
     47//usage:     "\n    -t DT   Date/time to use"
     48//usage:     "\n    -r FILE Use FILE's date/time"
     49//usage:    )
     50//usage:
     51//usage:#define touch_example_usage
     52//usage:       "$ ls -l /tmp/foo\n"
     53//usage:       "/bin/ls: /tmp/foo: No such file or directory\n"
     54//usage:       "$ touch /tmp/foo\n"
     55//usage:       "$ ls -l /tmp/foo\n"
     56//usage:       "-rw-rw-r--    1 andersen andersen        0 Apr 15 01:11 /tmp/foo\n"
    2157
    2258/* This is a NOFORK applet. Be very careful! */
     
    4480    int status = EXIT_SUCCESS;
    4581    int opts;
    46 #if ENABLE_DESKTOP
     82#if ENABLE_FEATURE_TOUCH_SUSV3
    4783# if ENABLE_LONG_OPTS
    4884    static const char touch_longopts[] ALIGN1 =
     
    6399#endif
    64100
    65 #if ENABLE_DESKTOP && ENABLE_LONG_OPTS
     101#if ENABLE_FEATURE_TOUCH_SUSV3 && ENABLE_LONG_OPTS
    66102    applet_long_options = touch_longopts;
    67103#endif
     
    69105     * accepted data format differs a bit between -d and -t.
    70106     * We accept the same formats for both */
    71     opts = getopt32(argv, "c" IF_DESKTOP("r:d:t:")
     107    opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:")
    72108                /*ignored:*/ "fma"
    73                 IF_DESKTOP(, &reference_file)
    74                 IF_DESKTOP(, &date_str)
    75                 IF_DESKTOP(, &date_str)
     109                IF_FEATURE_TOUCH_SUSV3(, &reference_file)
     110                IF_FEATURE_TOUCH_SUSV3(, &date_str)
     111                IF_FEATURE_TOUCH_SUSV3(, &date_str)
    76112    );
    77113
     
    92128        time_t t;
    93129
    94         //time(&t);
    95         //localtime_r(&t, &tm_time);
    96         memset(&tm_time, 0, sizeof(tm_time));
     130        //memset(&tm_time, 0, sizeof(tm_time));
     131        /* Better than memset: makes "HH:MM" dates meaningful */
     132        time(&t);
     133        localtime_r(&t, &tm_time);
    97134        parse_datestr(date_str, &tm_time);
    98135
  • branches/3.2/mindi-busybox/coreutils/tr.c

    r2725 r3232  
    4747//config:     useful for cases when no other way of expressing a character
    4848//config:     is possible.
     49
     50//usage:#define tr_trivial_usage
     51//usage:       "[-cds] STRING1 [STRING2]"
     52//usage:#define tr_full_usage "\n\n"
     53//usage:       "Translate, squeeze, or delete characters from stdin, writing to stdout\n"
     54//usage:     "\n    -c  Take complement of STRING1"
     55//usage:     "\n    -d  Delete input characters coded STRING1"
     56//usage:     "\n    -s  Squeeze multiple output characters of STRING2 into one character"
     57//usage:
     58//usage:#define tr_example_usage
     59//usage:       "$ echo \"gdkkn vnqkc\" | tr [a-y] [b-z]\n"
     60//usage:       "hello world\n"
    4961
    5062#include "libbb.h"
     
    325337    }
    326338
     339    if (ENABLE_FEATURE_CLEAN_UP) {
     340        free(vector);
     341        free(str2);
     342        free(str1);
     343    }
     344
    327345    return EXIT_SUCCESS;
    328346}
  • branches/3.2/mindi-busybox/coreutils/true.c

    r2725 r3232  
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */
    1212
     13//usage:#define true_trivial_usage
     14//usage:       ""
     15//usage:#define true_full_usage "\n\n"
     16//usage:       "Return an exit code of TRUE (0)"
     17//usage:
     18//usage:#define true_example_usage
     19//usage:       "$ true\n"
     20//usage:       "$ echo $?\n"
     21//usage:       "0\n"
     22
    1323#include "libbb.h"
    1424
  • branches/3.2/mindi-busybox/coreutils/tty.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv4 compliant */
    1111/* http://www.opengroup.org/onlinepubs/9699919799/utilities/tty.html */
     12
     13//usage:#define tty_trivial_usage
     14//usage:       ""
     15//usage:#define tty_full_usage "\n\n"
     16//usage:       "Print file name of stdin's terminal"
     17//usage:    IF_INCLUDE_SUSv2( "\n"
     18//usage:     "\n    -s  Print nothing, only return exit status"
     19//usage:    )
     20//usage:
     21//usage:#define tty_example_usage
     22//usage:       "$ tty\n"
     23//usage:       "/dev/tty2\n"
    1224
    1325#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/uname.c

    r2725 r3232  
    4848 *  Fix handling of -a to not print "unknown", add -o and -i support.
    4949 */
     50
     51//usage:#define uname_trivial_usage
     52//usage:       "[-amnrspv]"
     53//usage:#define uname_full_usage "\n\n"
     54//usage:       "Print system information\n"
     55//usage:     "\n    -a  Print all"
     56//usage:     "\n    -m  The machine (hardware) type"
     57//usage:     "\n    -n  Hostname"
     58//usage:     "\n    -r  OS release"
     59//usage:     "\n    -s  OS name (default)"
     60//usage:     "\n    -p  Processor type"
     61//usage:     "\n    -v  OS version"
     62//usage:
     63//usage:#define uname_example_usage
     64//usage:       "$ uname -a\n"
     65//usage:       "Linux debian 2.4.23 #2 Tue Dec 23 17:09:10 MST 2003 i686 GNU/Linux\n"
    5066
    5167#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/uniq.c

    r2725 r3232  
    1010/* BB_AUDIT SUSv3 compliant */
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
     12
     13//usage:#define uniq_trivial_usage
     14//usage:       "[-cdu][-f,s,w N] [INPUT [OUTPUT]]"
     15//usage:#define uniq_full_usage "\n\n"
     16//usage:       "Discard duplicate lines\n"
     17//usage:     "\n    -c  Prefix lines by the number of occurrences"
     18//usage:     "\n    -d  Only print duplicate lines"
     19//usage:     "\n    -u  Only print unique lines"
     20//usage:     "\n    -f N    Skip first N fields"
     21//usage:     "\n    -s N    Skip first N chars (after any skipped fields)"
     22//usage:     "\n    -w N    Compare N characters in line"
     23//usage:
     24//usage:#define uniq_example_usage
     25//usage:       "$ echo -e \"a\\na\\nb\\nc\\nc\\na\" | sort | uniq\n"
     26//usage:       "a\n"
     27//usage:       "b\n"
     28//usage:       "c\n"
    1229
    1330#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/usleep.c

    r2725 r3232  
    99
    1010/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */
     11
     12//usage:#define usleep_trivial_usage
     13//usage:       "N"
     14//usage:#define usleep_full_usage "\n\n"
     15//usage:       "Pause for N microseconds"
     16//usage:
     17//usage:#define usleep_example_usage
     18//usage:       "$ usleep 1000000\n"
     19//usage:       "[pauses for 1 second]\n"
    1120
    1221#include "libbb.h"
     
    2130    }
    2231
    23     if (usleep(xatou(argv[1]))) {
    24         bb_perror_nomsg_and_die();
    25     }
     32    usleep(xatou(argv[1]));
    2633
    2734    return EXIT_SUCCESS;
  • branches/3.2/mindi-busybox/coreutils/uudecode.c

    r2725 r3232  
    1111 * "end" line
    1212 */
     13
     14//usage:#define uudecode_trivial_usage
     15//usage:       "[-o OUTFILE] [INFILE]"
     16//usage:#define uudecode_full_usage "\n\n"
     17//usage:       "Uudecode a file\n"
     18//usage:       "Finds OUTFILE in uuencoded source unless -o is given"
     19//usage:
     20//usage:#define uudecode_example_usage
     21//usage:       "$ uudecode -o busybox busybox.uu\n"
     22//usage:       "$ ls -l busybox\n"
     23//usage:       "-rwxr-xr-x   1 ams      ams        245264 Jun  7 21:35 busybox\n"
     24
    1325#include "libbb.h"
    1426
     
    114126        if (outname == NULL) {
    115127            outname = strchr(line_ptr, ' ');
    116             if ((outname == NULL) || (*outname == '\0')) {
    117                 break;
    118             }
     128            if (!outname)
     129                break;
    119130            outname++;
     131            if (!outname[0])
     132                break;
    120133        }
    121134        dst_stream = stdout;
     
    133146#endif
    134147
    135 //applet:IF_BASE64(APPLET(base64, _BB_DIR_BIN, _BB_SUID_DROP))
     148//applet:IF_BASE64(APPLET(base64, BB_DIR_BIN, BB_SUID_DROP))
    136149
    137150//kbuild:lib-$(CONFIG_BASE64) += uudecode.o
     
    147160//usage:#define base64_full_usage "\n\n"
    148161//usage:       "Base64 encode or decode FILE to standard output"
    149 //usage:     "\nOptions:"
    150162//usage:     "\n    -d  Decode data"
    151163////usage:     "\n  -w COL  Wrap lines at COL (default 76, 0 disables)"
  • branches/3.2/mindi-busybox/coreutils/uuencode.c

    r2725 r3232  
    88 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 */
     10
     11//usage:#define uuencode_trivial_usage
     12//usage:       "[-m] [FILE] STORED_FILENAME"
     13//usage:#define uuencode_full_usage "\n\n"
     14//usage:       "Uuencode FILE (or stdin) to stdout\n"
     15//usage:     "\n    -m  Use base64 encoding per RFC1521"
     16//usage:
     17//usage:#define uuencode_example_usage
     18//usage:       "$ uuencode busybox busybox\n"
     19//usage:       "begin 755 busybox\n"
     20//usage:       "<encoded file snipped>\n"
     21//usage:       "$ uudecode busybox busybox > busybox.uu\n"
     22//usage:       "$\n"
    1023
    1124#include "libbb.h"
  • branches/3.2/mindi-busybox/coreutils/wc.c

    r2725 r3232  
    6565//usage:#define wc_full_usage "\n\n"
    6666//usage:       "Count lines, words, and bytes for each FILE (or stdin)\n"
    67 //usage:     "\nOptions:"
    6867//usage:     "\n    -c  Count bytes"
    6968//usage:    IF_UNICODE_SUPPORT(
  • branches/3.2/mindi-busybox/coreutils/who.c

    r2725 r3232  
    1919/* BB_AUDIT SUSv3 _NOT_ compliant -- missing options -b, -d, -l, -m, -p, -q, -r, -s, -t, -T, -u; Missing argument 'file'.  */
    2020
     21//config:config WHO
     22//config:      bool "who"
     23//config:      default y
     24//config:      depends on FEATURE_UTMP
     25//config:      help
     26//config:        who is used to show who is logged on.
     27
     28//config:config USERS
     29//config:      bool "users"
     30//config:      default y
     31//config:      depends on FEATURE_UTMP
     32//config:      help
     33//config:        Print users currently logged on.
     34
     35//applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users))
     36//applet:IF_WHO(  APPLET(  who, BB_DIR_USR_BIN, BB_SUID_DROP))
     37
     38//kbuild:lib-$(CONFIG_USERS) += who.o
     39//kbuild:lib-$(CONFIG_WHO) += who.o
     40
     41//usage:#define users_trivial_usage
     42//usage:       ""
     43//usage:#define users_full_usage "\n\n"
     44//usage:       "Print the users currently logged on"
     45
     46//usage:#define who_trivial_usage
     47//usage:       "[-a]"
     48//usage:#define who_full_usage "\n\n"
     49//usage:       "Show who is logged on\n"
     50//usage:     "\n    -a  Show all"
     51//usage:     "\n    -H  Print column headers"
     52
    2153#include "libbb.h"
    22 #include <utmp.h>
    2354
    2455static void idle_string(char *str6, time_t t)
     
    4576    struct utmp *ut;
    4677    unsigned opt;
     78    int do_users = (ENABLE_USERS && (!ENABLE_WHO || applet_name[0] == 'u'));
     79    const char *fmt = "%s";
    4780
    4881    opt_complementary = "=0";
    49     opt = getopt32(argv, "aH");
     82    opt = getopt32(argv, do_users ? "" : "aH");
    5083    if (opt & 2) // -H
    5184        printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n");
     
    5689         && ((opt & 1) || ut->ut_type == USER_PROCESS)
    5790        ) {
    58             char str6[6];
    59             char name[sizeof("/dev/") + sizeof(ut->ut_line) + 1];
    60             struct stat st;
    61             time_t seconds;
     91            if (!do_users) {
     92                char str6[6];
     93                char name[sizeof("/dev/") + sizeof(ut->ut_line) + 1];
     94                struct stat st;
     95                time_t seconds;
    6296
    63             str6[0] = '?';
    64             str6[1] = '\0';
    65             strcpy(name, "/dev/");
    66             safe_strncpy(ut->ut_line[0] == '/' ? name : name + sizeof("/dev/")-1,
    67                 ut->ut_line,
    68                 sizeof(ut->ut_line)+1
    69             );
    70             if (stat(name, &st) == 0)
    71                 idle_string(str6, st.st_atime);
    72             /* manpages say ut_tv.tv_sec *is* time_t,
    73              * but some systems have it wrong */
    74             seconds = ut->ut_tv.tv_sec;
    75             /* How wide time field can be?
    76              * "Nov 10 19:33:20": 15 chars
    77              * "2010-11-10 19:33": 16 chars
    78              */
    79             printf("%-15.*s %-15.*s %-7s %-16.16s %.*s\n",
    80                     (int)sizeof(ut->ut_user), ut->ut_user,
    81                     (int)sizeof(ut->ut_line), ut->ut_line,
    82                     str6,
    83                     ctime(&seconds) + 4,
    84                     (int)sizeof(ut->ut_host), ut->ut_host
    85             );
     97                str6[0] = '?';
     98                str6[1] = '\0';
     99                strcpy(name, "/dev/");
     100                safe_strncpy(ut->ut_line[0] == '/' ? name : name + sizeof("/dev/")-1,
     101                    ut->ut_line,
     102                    sizeof(ut->ut_line)+1
     103                );
     104                if (stat(name, &st) == 0)
     105                    idle_string(str6, st.st_atime);
     106                /* manpages say ut_tv.tv_sec *is* time_t,
     107                 * but some systems have it wrong */
     108                seconds = ut->ut_tv.tv_sec;
     109                /* How wide time field can be?
     110                 * "Nov 10 19:33:20": 15 chars
     111                 * "2010-11-10 19:33": 16 chars
     112                 */
     113                printf("%-15.*s %-15.*s %-7s %-16.16s %.*s\n",
     114                        (int)sizeof(ut->ut_user), ut->ut_user,
     115                        (int)sizeof(ut->ut_line), ut->ut_line,
     116                        str6,
     117                        ctime(&seconds) + 4,
     118                        (int)sizeof(ut->ut_host), ut->ut_host
     119                );
     120            } else {
     121                printf(fmt, ut->ut_user);
     122                fmt = " %s";
     123            }
    86124        }
    87125    }
     126    if (do_users)
     127        bb_putchar('\n');
    88128    if (ENABLE_FEATURE_CLEAN_UP)
    89129        endutent();
  • branches/3.2/mindi-busybox/coreutils/whoami.c

    r2725 r3232  
    99
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
     11
     12//usage:#define whoami_trivial_usage
     13//usage:       ""
     14//usage:#define whoami_full_usage "\n\n"
     15//usage:       "Print the user name associated with the current effective user id"
    1116
    1217#include "libbb.h"
Note: See TracChangeset for help on using the changeset viewer.