Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/findutils/xargs.c

    r821 r1770  
    1818 */
    1919
    20 #include "busybox.h"
    21 #include <stdio.h>
    22 #include <stdlib.h>
    23 #include <string.h>
    24 #include <unistd.h>
    25 #include <getopt.h>
    26 #include <errno.h>
    27 #include <fcntl.h>
    28 #include <sys/types.h>
    29 #include <sys/wait.h>
     20#include "libbb.h"
     21
     22/* This is a NOEXEC applet. Be very careful! */
     23
    3024
    3125/* COMPAT:  SYSV version defaults size (and has a max value of) to 470.
     
    4034
    4135#ifdef TEST
    42 # ifndef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
    43 #  define CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
     36# ifndef ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION
     37#  define ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION 1
    4438# endif
    45 # ifndef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
    46 #  define CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
     39# ifndef ENABLE_FEATURE_XARGS_SUPPORT_QUOTES
     40#  define ENABLE_FEATURE_XARGS_SUPPORT_QUOTES 1
    4741# endif
    48 # ifndef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
    49 #  define CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
     42# ifndef ENABLE_FEATURE_XARGS_SUPPORT_TERMOPT
     43#  define ENABLE_FEATURE_XARGS_SUPPORT_TERMOPT 1
    5044# endif
    51 # ifndef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
    52 #  define CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
     45# ifndef ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM
     46#  define ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM 1
    5347# endif
    5448#endif
    5549
    5650/*
    57    This function have special algorithm.
    58    Don`t use fork and include to main!
     51   This function has special algorithm.
     52   Don't use fork and include to main!
    5953*/
    60 static int xargs_exec(char *const *args)
    61 {
    62     pid_t p;
    63     volatile int exec_errno = 0;    /* shared vfork stack */
    64 
    65     if ((p = vfork()) >= 0) {
    66         if (p == 0) {
    67             /* vfork -- child */
    68             execvp(args[0], args);
    69             exec_errno = errno;     /* set error to shared stack */
    70             _exit(1);
    71         } else {
    72             /* vfork -- parent */
    73             int status;
    74 
    75             while (wait(&status) == (pid_t) - 1)
    76                 if (errno != EINTR)
    77                     break;
    78             if (exec_errno) {
    79                 errno = exec_errno;
    80                 bb_perror_msg("%s", args[0]);
    81                 return exec_errno == ENOENT ? 127 : 126;
    82             } else {
    83                 if (WEXITSTATUS(status) == 255) {
    84                     bb_error_msg("%s: exited with status 255; aborting", args[0]);
    85                     return 124;
    86                 }
    87                 if (WIFSTOPPED(status)) {
    88                     bb_error_msg("%s: stopped by signal %d",
    89                         args[0], WSTOPSIG(status));
    90                     return 125;
    91                 }
    92                 if (WIFSIGNALED(status)) {
    93                     bb_error_msg("%s: terminated by signal %d",
    94                         args[0], WTERMSIG(status));
    95                     return 125;
    96                 }
    97                 if (WEXITSTATUS(status) != 0)
    98                     return 123;
    99                 return 0;
    100             }
    101         }
    102     } else {
    103         bb_perror_msg_and_die("vfork");
    104     }
    105 }
    106 
    107 
    108 typedef struct xlist_s {
    109     char *data;
    110     size_t lenght;
    111     struct xlist_s *link;
     54static int xargs_exec(char **args)
     55{
     56    int status;
     57
     58    status = spawn_and_wait(args);
     59    if (status < 0) {
     60        bb_perror_msg("%s", args[0]);
     61        return errno == ENOENT ? 127 : 126;
     62    }
     63    if (status == 255) {
     64        bb_error_msg("%s: exited with status 255; aborting", args[0]);
     65        return 124;
     66    }
     67/* Huh? I think we won't see this, ever. We don't wait with WUNTRACED!
     68    if (WIFSTOPPED(status)) {
     69        bb_error_msg("%s: stopped by signal %d",
     70            args[0], WSTOPSIG(status));
     71        return 125;
     72    }
     73*/
     74    if (status >= 1000) {
     75        bb_error_msg("%s: terminated by signal %d",
     76            args[0], status - 1000);
     77        return 125;
     78    }
     79    if (status)
     80        return 123;
     81    return 0;
     82}
     83
     84
     85typedef struct xlist_t {
     86    struct xlist_t *link;
     87    size_t length;
     88    char xstr[1];
    11289} xlist_t;
    11390
    114 static int eof_stdin_detected;
     91static smallint eof_stdin_detected;
    11592
    11693#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
    117 #define ISSPACE(c) (ISBLANK (c) || (c) == '\n' || (c) == '\r' \
     94#define ISSPACE(c) (ISBLANK(c) || (c) == '\n' || (c) == '\r' \
    11895            || (c) == '\f' || (c) == '\v')
    11996
    120 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
    121 static xlist_t *process_stdin(xlist_t * list_arg,
     97#if ENABLE_FEATURE_XARGS_SUPPORT_QUOTES
     98static xlist_t *process_stdin(xlist_t *list_arg,
    12299    const char *eof_str, size_t mc, char *buf)
    123100{
     
    129106    char *s = NULL;         /* start word */
    130107    char *p = NULL;         /* pointer to end word */
    131     char q = 0;             /* quote char */
     108    char q = '\0';          /* quote char */
    132109    char state = NORM;
    133110    char eof_str_detected = 0;
     
    137114    xlist_t *prev;
    138115
    139     for (prev = cur = list_arg; cur; cur = cur->link) {
    140         line_l += cur->lenght;  /* previous allocated */
    141         if (prev != cur)
    142             prev = prev->link;
     116    prev = cur = list_arg;
     117    while (1) {
     118        if (!cur) break;
     119        prev = cur;
     120        line_l += cur->length;
     121        cur = cur->link;
    143122    }
    144123
     
    146125        c = getchar();
    147126        if (c == EOF) {
    148             eof_stdin_detected++;
     127            eof_stdin_detected = 1;
    149128            if (s)
    150129                goto unexpected_eof;
     
    157136            goto set;
    158137        } else if (state == QUOTE) {
    159             if (c == q) {
    160                 q = 0;
    161                 state = NORM;
    162             } else {
     138            if (c != q)
    163139                goto set;
    164             }
    165         } else { /* if(state == NORM) */
    166 
     140            q = '\0';
     141            state = NORM;
     142        } else { /* if (state == NORM) */
    167143            if (ISSPACE(c)) {
    168144                if (s) {
    169 unexpected_eof:
     145 unexpected_eof:
    170146                    state = SPACE;
    171                     c = 0;
     147                    c = '\0';
    172148                    goto set;
    173149                }
     
    181157                    state = QUOTE;
    182158                } else {
    183 set:
     159 set:
    184160                    if ((size_t)(p - buf) >= mc)
    185161                        bb_error_msg_and_die("argument line too long");
     
    195171            /* word loaded */
    196172            if (eof_str) {
    197                 eof_str_detected = strcmp(s, eof_str) == 0;
     173                eof_str_detected = (strcmp(s, eof_str) == 0);
    198174            }
    199175            if (!eof_str_detected) {
    200                 size_t lenght = (p - buf);
    201 
    202                 cur = xmalloc(sizeof(xlist_t) + lenght);
    203                 cur->data = memcpy(cur + 1, s, lenght);
    204                 cur->lenght = lenght;
     176                size_t length = (p - buf);
     177                /* Dont xzalloc - it can be quite big */
     178                cur = xmalloc(offsetof(xlist_t, xstr) + length);
    205179                cur->link = NULL;
     180                cur->length = length;
     181                memcpy(cur->xstr, s, length);
    206182                if (prev == NULL) {
    207183                    list_arg = cur;
     
    210186                }
    211187                prev = cur;
    212                 line_l += lenght;
     188                line_l += length;
    213189                if (line_l > mc) {
    214190                    /* stop memory usage :-) */
     
    224200#else
    225201/* The variant does not support single quotes, double quotes or backslash */
    226 static xlist_t *process_stdin(xlist_t * list_arg,
    227     const char *eof_str, size_t mc, char *buf)
     202static xlist_t *process_stdin(xlist_t *list_arg,
     203        const char *eof_str, size_t mc, char *buf)
    228204{
    229205
    230206    int c;                  /* current char */
    231     int eof_str_detected = 0;
     207    char eof_str_detected = 0;
    232208    char *s = NULL;         /* start word */
    233209    char *p = NULL;         /* pointer to end word */
     
    236212    xlist_t *prev;
    237213
    238     for (prev = cur = list_arg; cur; cur = cur->link) {
    239         line_l += cur->lenght;  /* previous allocated */
    240         if (prev != cur)
    241             prev = prev->link;
     214    prev = cur = list_arg;
     215    while (1) {
     216        if (!cur) break;
     217        prev = cur;
     218        line_l += cur->length;
     219        cur = cur->link;
    242220    }
    243221
     
    245223        c = getchar();
    246224        if (c == EOF) {
    247             eof_stdin_detected++;
     225            eof_stdin_detected = 1;
    248226        }
    249227        if (eof_str_detected)
     
    258236        if ((p - buf) >= mc)
    259237            bb_error_msg_and_die("argument line too long");
    260         *p++ = c == EOF ? 0 : c;
     238        *p++ = (c == EOF ? '\0' : c);
    261239        if (c == EOF) { /* word's delimiter or EOF detected */
    262240            /* word loaded */
    263241            if (eof_str) {
    264                 eof_str_detected = strcmp(s, eof_str) == 0;
     242                eof_str_detected = (strcmp(s, eof_str) == 0);
    265243            }
    266244            if (!eof_str_detected) {
    267                 size_t lenght = (p - buf);
    268 
    269                 cur = xmalloc(sizeof(xlist_t) + lenght);
    270                 cur->data = memcpy(cur + 1, s, lenght);
    271                 cur->lenght = lenght;
     245                size_t length = (p - buf);
     246                /* Dont xzalloc - it can be quite big */
     247                cur = xmalloc(offsetof(xlist_t, xstr) + length);
    272248                cur->link = NULL;
     249                cur->length = length;
     250                memcpy(cur->xstr, s, length);
    273251                if (prev == NULL) {
    274252                    list_arg = cur;
     
    277255                }
    278256                prev = cur;
    279                 line_l += lenght;
     257                line_l += length;
    280258                if (line_l > mc) {
    281259                    /* stop memory usage :-) */
     
    288266    return list_arg;
    289267}
    290 #endif /* CONFIG_FEATURE_XARGS_SUPPORT_QUOTES */
    291 
    292 
    293 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
     268#endif /* FEATURE_XARGS_SUPPORT_QUOTES */
     269
     270
     271#if ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION
    294272/* Prompt the user for a response, and
    295273   if the user responds affirmatively, return true;
    296    otherwise, return false. Used "/dev/tty", not stdin. */
     274   otherwise, return false. Uses "/dev/tty", not stdin. */
    297275static int xargs_ask_confirmation(void)
    298276{
    299     static FILE *tty_stream;
     277    FILE *tty_stream;
    300278    int c, savec;
    301279
    302     if (!tty_stream) {
    303         tty_stream = bb_xfopen(CURRENT_TTY, "r");
    304         /* pranoidal security by vodz */
    305         fcntl(fileno(tty_stream), F_SETFD, FD_CLOEXEC);
    306     }
     280    tty_stream = xfopen(CURRENT_TTY, "r");
    307281    fputs(" ?...", stderr);
    308282    fflush(stderr);
     
    310284    while (c != EOF && c != '\n')
    311285        c = getc(tty_stream);
    312     if (savec == 'y' || savec == 'Y')
    313         return 1;
    314     return 0;
    315 }
    316 
    317 # define OPT_INC_P 1
     286    fclose(tty_stream);
     287    return (savec == 'y' || savec == 'Y');
     288}
    318289#else
    319 # define OPT_INC_P 0
    320290# define xargs_ask_confirmation() 1
    321 #endif /* CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION */
    322 
    323 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
    324 # define OPT_INC_X 1
    325 #else
    326 # define OPT_INC_X 0
    327 #endif
    328 
    329 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
    330 static xlist_t *process0_stdin(xlist_t * list_arg, const char *eof_str ATTRIBUTE_UNUSED,
    331                                size_t mc, char *buf)
     291#endif /* FEATURE_XARGS_SUPPORT_CONFIRMATION */
     292
     293#if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM
     294static xlist_t *process0_stdin(xlist_t *list_arg,
     295        const char *eof_str ATTRIBUTE_UNUSED, size_t mc, char *buf)
    332296{
    333297    int c;                  /* current char */
     
    338302    xlist_t *prev;
    339303
    340     for (prev = cur = list_arg; cur; cur = cur->link) {
    341         line_l += cur->lenght;  /* previous allocated */
    342         if (prev != cur)
    343             prev = prev->link;
     304    prev = cur = list_arg;
     305    while (1) {
     306        if (!cur) break;
     307        prev = cur;
     308        line_l += cur->length;
     309        cur = cur->link;
    344310    }
    345311
     
    347313        c = getchar();
    348314        if (c == EOF) {
    349             eof_stdin_detected++;
     315            eof_stdin_detected = 1;
    350316            if (s == NULL)
    351317                break;
    352             c = 0;
     318            c = '\0';
    353319        }
    354320        if (s == NULL)
     
    357323            bb_error_msg_and_die("argument line too long");
    358324        *p++ = c;
    359         if (c == 0) {   /* word's delimiter or EOF detected */
     325        if (c == '\0') {   /* word's delimiter or EOF detected */
    360326            /* word loaded */
    361             size_t lenght = (p - buf);
    362 
    363             cur = xmalloc(sizeof(xlist_t) + lenght);
    364             cur->data = memcpy(cur + 1, s, lenght);
    365             cur->lenght = lenght;
     327            size_t length = (p - buf);
     328            /* Dont xzalloc - it can be quite big */
     329            cur = xmalloc(offsetof(xlist_t, xstr) + length);
    366330            cur->link = NULL;
     331            cur->length = length;
     332            memcpy(cur->xstr, s, length);
    367333            if (prev == NULL) {
    368334                list_arg = cur;
     
    371337            }
    372338            prev = cur;
    373             line_l += lenght;
     339            line_l += length;
    374340            if (line_l > mc) {
    375341                /* stop memory usage :-) */
     
    381347    return list_arg;
    382348}
    383 
    384 # define READ_ARGS(l, e, nmc, mc) (*read_args)(l, e, nmc, mc)
    385 # define OPT_INC_0 1    /* future use */
    386 #else
    387 # define OPT_INC_0 0    /* future use */
    388 # define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc)
    389 #endif /* CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM */
    390 
    391 
    392 #define OPT_VERBOSE     (1<<0)
    393 #define OPT_NO_EMPTY    (1<<1)
    394 #define OPT_UPTO_NUMBER (1<<2)
    395 #define OPT_UPTO_SIZE   (1<<3)
    396 #define OPT_EOF_STRING  (1<<4)
    397 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
    398 #define OPT_INTERACTIVE (1<<5)
    399 #else
    400 #define OPT_INTERACTIVE (0)     /* require for algorithm &| */
    401 #endif
    402 #define OPT_TERMINATE   (1<<(5+OPT_INC_P))
    403 #define OPT_ZEROTERM    (1<<(5+OPT_INC_P+OPT_INC_X))
    404 /* next future
    405 #define OPT_NEXT_OTHER  (1<<(5+OPT_INC_P+OPT_INC_X+OPT_INC_0))
    406 */
    407 
     349#endif /* FEATURE_XARGS_SUPPORT_ZERO_TERM */
     350
     351/* Correct regardless of combination of CONFIG_xxx */
     352enum {
     353    OPTBIT_VERBOSE = 0,
     354    OPTBIT_NO_EMPTY,
     355    OPTBIT_UPTO_NUMBER,
     356    OPTBIT_UPTO_SIZE,
     357    OPTBIT_EOF_STRING,
     358    USE_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,)
     359    USE_FEATURE_XARGS_SUPPORT_TERMOPT(     OPTBIT_TERMINATE  ,)
     360    USE_FEATURE_XARGS_SUPPORT_ZERO_TERM(   OPTBIT_ZEROTERM   ,)
     361
     362    OPT_VERBOSE     = 1<<OPTBIT_VERBOSE    ,
     363    OPT_NO_EMPTY    = 1<<OPTBIT_NO_EMPTY   ,
     364    OPT_UPTO_NUMBER = 1<<OPTBIT_UPTO_NUMBER,
     365    OPT_UPTO_SIZE   = 1<<OPTBIT_UPTO_SIZE  ,
     366    OPT_EOF_STRING  = 1<<OPTBIT_EOF_STRING ,
     367    OPT_INTERACTIVE = USE_FEATURE_XARGS_SUPPORT_CONFIRMATION((1<<OPTBIT_INTERACTIVE)) + 0,
     368    OPT_TERMINATE   = USE_FEATURE_XARGS_SUPPORT_TERMOPT(     (1<<OPTBIT_TERMINATE  )) + 0,
     369    OPT_ZEROTERM    = USE_FEATURE_XARGS_SUPPORT_ZERO_TERM(   (1<<OPTBIT_ZEROTERM   )) + 0,
     370};
     371#define OPTION_STR "+trn:s:e::" \
     372    USE_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \
     373    USE_FEATURE_XARGS_SUPPORT_TERMOPT(     "x") \
     374    USE_FEATURE_XARGS_SUPPORT_ZERO_TERM(   "0")
     375
     376int xargs_main(int argc, char **argv);
    408377int xargs_main(int argc, char **argv)
    409378{
    410379    char **args;
    411     int i, a, n;
     380    int i, n;
    412381    xlist_t *list = NULL;
    413382    xlist_t *cur;
     
    418387    long orig_arg_max;
    419388    const char *eof_str = "_";
    420     unsigned long opt;
     389    unsigned opt;
    421390    size_t n_max_chars;
    422 
    423 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
    424     xlist_t *(*read_args) (xlist_t *, const char *, size_t, char *) = process_stdin;
     391#if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM
     392    xlist_t* (*read_args)(xlist_t*, const char*, size_t, char*) = process_stdin;
     393#else
     394#define read_args process_stdin
    425395#endif
    426396
    427 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
    428     bb_opt_complementally = "pt";
    429 #endif
    430 
    431     opt = bb_getopt_ulflags(argc, argv, "+trn:s:e::"
    432 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
    433     "p"
    434 #endif
    435 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
    436     "x"
    437 #endif
    438 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
    439     "0"
    440 #endif
    441     ,&max_args, &max_chars, &eof_str);
    442 
    443     a = argc - optind;
     397    opt = getopt32(argv, OPTION_STR, &max_args, &max_chars, &eof_str);
     398
     399    if (opt & OPT_ZEROTERM)
     400        USE_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin);
     401
    444402    argv += optind;
    445     if (a == 0) {
     403    argc -= optind;
     404    if (!argc) {
    446405        /* default behavior is to echo all the filenames */
    447         *argv = "echo";
    448         a++;
     406        *argv = (char*)"echo";
     407        argc++;
    449408    }
    450409
     
    452411    if (orig_arg_max == -1)
    453412        orig_arg_max = LONG_MAX;
    454     orig_arg_max -= 2048;   /* POSIX.2 requires subtracting 2048.  */
    455     if ((opt & OPT_UPTO_SIZE)) {
    456         n_max_chars = bb_xgetularg10_bnd(max_chars, 1, orig_arg_max);
    457         for (i = 0; i < a; i++) {
     413    orig_arg_max -= 2048;   /* POSIX.2 requires subtracting 2048 */
     414
     415    if (opt & OPT_UPTO_SIZE) {
     416        n_max_chars = xatoul_range(max_chars, 1, orig_arg_max);
     417        for (i = 0; i < argc; i++) {
    458418            n_chars += strlen(*argv) + 1;
    459419        }
    460420        if (n_max_chars < n_chars) {
    461             bb_error_msg_and_die("can not fit single argument within argument list size limit");
     421            bb_error_msg_and_die("cannot fit single argument within argument list size limit");
    462422        }
    463423        n_max_chars -= n_chars;
     
    473433    max_chars = xmalloc(n_max_chars);
    474434
    475     if ((opt & OPT_UPTO_NUMBER)) {
    476         n_max_arg = bb_xgetularg10_bnd(max_args, 1, INT_MAX);
     435    if (opt & OPT_UPTO_NUMBER) {
     436        n_max_arg = xatoul_range(max_args, 1, INT_MAX);
    477437    } else {
    478438        n_max_arg = n_max_chars;
    479439    }
    480440
    481 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
    482     if (opt & OPT_ZEROTERM)
    483         read_args = process0_stdin;
    484 #endif
    485 
    486     while ((list = READ_ARGS(list, eof_str, n_max_chars, max_chars)) != NULL ||
    487         (opt & OPT_NO_EMPTY) == 0)
     441    while ((list = read_args(list, eof_str, n_max_chars, max_chars)) != NULL ||
     442        !(opt & OPT_NO_EMPTY))
    488443    {
    489444        opt |= OPT_NO_EMPTY;
    490445        n = 0;
    491446        n_chars = 0;
    492 #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
     447#if ENABLE_FEATURE_XARGS_SUPPORT_TERMOPT
    493448        for (cur = list; cur;) {
    494             n_chars += cur->lenght;
     449            n_chars += cur->length;
    495450            n++;
    496451            cur = cur->link;
     
    503458#else
    504459        for (cur = list; cur; cur = cur->link) {
    505             n_chars += cur->lenght;
     460            n_chars += cur->length;
    506461            n++;
    507462            if (n_chars > n_max_chars || n == n_max_arg) {
     
    509464            }
    510465        }
    511 #endif /* CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT */
    512 
    513         /* allocating pointers for execvp:
    514            a*arg, n*arg from stdin, NULL */
    515         args = xcalloc(n + a + 1, sizeof(char *));
    516 
    517         /* Store the command to be executed
     466#endif /* FEATURE_XARGS_SUPPORT_TERMOPT */
     467
     468        /* allocate pointers for execvp:
     469           argc*arg, n*arg from stdin, NULL */
     470        args = xzalloc((n + argc + 1) * sizeof(char *));
     471
     472        /* store the command to be executed
    518473           (taken from the command line) */
    519         for (i = 0; i < a; i++)
     474        for (i = 0; i < argc; i++)
    520475            args[i] = argv[i];
    521476        /* (taken from stdin) */
    522477        for (cur = list; n; cur = cur->link) {
    523             args[i++] = cur->data;
     478            args[i++] = cur->xstr;
    524479            n--;
    525480        }
    526481
    527         if ((opt & (OPT_INTERACTIVE | OPT_VERBOSE))) {
     482        if (opt & (OPT_INTERACTIVE | OPT_VERBOSE)) {
    528483            for (i = 0; args[i]; i++) {
    529484                if (i)
     
    531486                fputs(args[i], stderr);
    532487            }
    533             if ((opt & OPT_INTERACTIVE) == 0)
     488            if (!(opt & OPT_INTERACTIVE))
    534489                fputc('\n', stderr);
    535490        }
    536         if ((opt & OPT_INTERACTIVE) == 0 || xargs_ask_confirmation() != 0) {
     491        if (!(opt & OPT_INTERACTIVE) || xargs_ask_confirmation()) {
    537492            child_error = xargs_exec(args);
    538493        }
    539494
    540495        /* clean up */
    541         for (i = a; args[i]; i++) {
     496        for (i = argc; args[i]; i++) {
    542497            cur = list;
    543498            list = list->link;
     
    549504        }
    550505    }
    551 #ifdef CONFIG_FEATURE_CLEAN_UP
    552     free(max_chars);
    553 #endif
     506    if (ENABLE_FEATURE_CLEAN_UP)
     507        free(max_chars);
    554508    return child_error;
    555509}
     
    558512#ifdef TEST
    559513
    560 const char *bb_applet_name = "debug stuff usage";
     514const char *applet_name = "debug stuff usage";
    561515
    562516void bb_show_usage(void)
    563517{
    564518    fprintf(stderr, "Usage: %s [-p] [-r] [-t] -[x] [-n max_arg] [-s max_chars]\n",
    565         bb_applet_name);
     519        applet_name);
    566520    exit(1);
    567521}
Note: See TracChangeset for help on using the changeset viewer.