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


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/libbb
Files:
56 edited

Legend:

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

    r2725 r3232  
    1515      Minimum allowable password length.
    1616
    17 config MD5_SIZE_VS_SPEED
     17config MD5_SMALL
    1818    int "MD5: Trade bytes for speed (0:fast, 3:slow)"
    19     default 2
     19    default 1
    2020    range 0 3
    2121    help
     
    2929      3 (smallest)        5.1                4912
    3030
     31config SHA3_SMALL
     32    int "SHA3: Trade bytes for speed (0:fast, 1:slow)"
     33    default 1
     34    range 0 1
     35    help
     36      Trade binary size versus speed for the sha3sum algorithm.
     37      SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate):
     38      64-bit x86: +270 bytes of code, 45% faster
     39      32-bit x86: +450 bytes of code, 75% faster
     40
    3141config FEATURE_FAST_TOP
    3242    bool "Faster /proc scanning code (+100 bytes)"
     
    8191config FEATURE_EDITING_HISTORY
    8292    int "History size"
    83     range 0 99999
     93    # Don't allow way too big values here, code uses fixed "char *history[N]" struct member
     94    range 0 9999
    8495    default 255
    8596    depends on FEATURE_EDITING
    8697    help
    87       Specify command history size.
     98      Specify command history size (0 - disable).
    8899
    89100config FEATURE_EDITING_SAVEHISTORY
     
    93104    help
    94105      Enable history saving in shells.
     106
     107config FEATURE_EDITING_SAVE_ON_EXIT
     108    bool "Save history on shell exit, not after every command"
     109    default n
     110    depends on FEATURE_EDITING_SAVEHISTORY
     111    help
     112      Save history on shell exit, not after every command.
     113
     114config FEATURE_REVERSE_SEARCH
     115    bool "Reverse history search"
     116    default y
     117    depends on FEATURE_EDITING_SAVEHISTORY
     118    help
     119      Enable readline-like Ctrl-R combination for reverse history search.
     120      Increases code by about 0.5k.
    95121
    96122config FEATURE_TAB_COMPLETION
     
    136162      but prevents a symlink attack.
    137163      Similarly, "cp file device" will not send file's data
    138       to the device.
     164      to the device. (To do that, use "cat file >device")
    139165
    140166config FEATURE_VERBOSE_CP_MESSAGE
     
    157183    default 4
    158184    help
    159       Size of buffer used by cp, mv, install etc.
     185      Size of buffer used by cp, mv, install, wget etc.
    160186      Buffers which are 4 kb or less will be allocated on stack.
    161187      Bigger buffers will be allocated with mmap, with fallback to 4 kb
    162188      stack buffer if mmap fails.
    163189
     190config FEATURE_SKIP_ROOTFS
     191    bool "Skip rootfs in mount table"
     192    default y
     193    help
     194      Ignore rootfs entry in mount table.
     195
     196      In Linux, kernel has a special filesystem, rootfs, which is initially
     197      mounted on /. It contains initramfs data, if kernel is configured
     198      to have one. Usually, another file system is mounted over / early
     199      in boot process, and therefore most tools which manipulate
     200      mount table, such as df, will skip rootfs entry.
     201
     202      However, some systems do not mount anything on /.
     203      If you need to configure busybox for one of these systems,
     204      you may find it useful to turn this option off to make df show
     205      initramfs statistics.
     206
     207      Otherwise, choose Y.
     208
    164209config MONOTONIC_SYSCALL
    165210    bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
    166211    default n
    167     depends on PLATFORM_LINUX
     212    select PLATFORM_LINUX
    168213    help
    169214      Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring
  • branches/3.2/mindi-busybox/libbb/Kbuild.src

    r2725 r3232  
    1414lib-y += ask_confirmation.o
    1515lib-y += bb_askpass.o
    16 lib-y += bb_basename.o
    1716lib-y += bb_bswap_64.o
    1817lib-y += bb_do_delay.o
     
    6059lib-y += make_directory.o
    6160lib-y += makedev.o
    62 lib-y += match_fstype.o
    6361lib-y += hash_md5_sha.o
    6462# Alternative (disabled) MD5 implementation
     
    6664lib-y += messages.o
    6765lib-y += mode_string.o
    68 lib-y += obscure.o
    6966lib-y += parse_mode.o
    70 lib-y += parse_config.o
    7167lib-y += perror_msg.o
    7268lib-y += perror_nomsg.o
     
    10298lib-y += trim.o
    10399lib-y += u_signal_names.o
    104 lib-y += udp_io.o
    105100lib-y += uuencode.o
    106101lib-y += vdprintf.o
     
    121116lib-y += xrealloc_vector.o
    122117
     118lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o
     119
    123120lib-$(CONFIG_FEATURE_UTMP) += utmp.o
    124121
     
    130127lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o
    131128
     129lib-$(CONFIG_NC) += udp_io.o
     130lib-$(CONFIG_DNSD) += udp_io.o
     131lib-$(CONFIG_NTPD) += udp_io.o
     132lib-$(CONFIG_TFTP) += udp_io.o
     133lib-$(CONFIG_TFTPD) += udp_io.o
     134lib-$(CONFIG_TCPSVD) += udp_io.o
     135lib-$(CONFIG_UDPSVD) += udp_io.o
     136lib-$(CONFIG_TRACEROUTE) += udp_io.o
     137
    132138lib-$(CONFIG_LOSETUP) += loop.o
    133139lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o
     
    138144lib-$(CONFIG_DELUSER) += update_passwd.o
    139145
    140 lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o
     146lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o
    141147lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o
    142148lib-$(CONFIG_CRYPTPW) += pw_encrypt.o
     
    161167lib-$(CONFIG_POWERTOP) += get_cpu_count.o
    162168
     169lib-$(CONFIG_PING) += inet_cksum.o
     170lib-$(CONFIG_TRACEROUTE) += inet_cksum.o
     171lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o
     172lib-$(CONFIG_UDHCPC) += inet_cksum.o
     173lib-$(CONFIG_UDHCPC6) += inet_cksum.o
     174lib-$(CONFIG_UDHCPD) += inet_cksum.o
     175
    163176# We shouldn't build xregcomp.c if we don't need it - this ensures we don't
    164177# require regex.h to be in the include dir even if we don't need it thereby
  • branches/3.2/mindi-busybox/libbb/appletlib.c

    r2725 r3232  
    2828 */
    2929#include "busybox.h"
    30 #include <assert.h>
    31 #include <malloc.h>
    32 /* Try to pull in PAGE_SIZE */
    33 #ifdef __linux__
    34 # include <sys/user.h>
    35 #endif
    36 #ifdef __GNU__ /* Hurd */
    37 # include <mach/vm_param.h>
     30
     31#if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
     32        || defined(__APPLE__) \
     33    )
     34# include <malloc.h> /* for mallopt */
    3835#endif
    3936
     
    4340#include "applets.h"
    4441#undef PROTOTYPES
    45 
    4642
    4743/* Include generated applet names, pointers to <applet>_main, etc */
     
    5551#endif
    5652
    57 
    5853#include "usage_compressed.h"
     54
    5955
    6056#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
     
    6763
    6864static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
    69 # include "archive.h"
     65# include "bb_archive.h"
    7066static const char *unpack_usage_messages(void)
    7167{
     
    145141
    146142#if NUM_APPLETS > 8
    147 /* NB: any char pointer will work as well, not necessarily applet_names */
    148 static int applet_name_compare(const void *name, const void *v)
    149 {
    150     int i = (const char *)v - applet_names;
     143static int applet_name_compare(const void *name, const void *idx)
     144{
     145    int i = (int)(ptrdiff_t)idx - 1;
    151146    return strcmp(name, APPLET_NAME(i));
    152147}
     
    157152    /* Do a binary search to find the applet entry given the name. */
    158153    const char *p;
    159     p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare);
    160     if (!p)
    161         return -1;
    162     return p - applet_names;
     154    p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare);
     155    /*
     156     * if (!p) return -1;
     157     * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :)
     158     */
     159    return (int)(ptrdiff_t)p - 1;
    163160#else
    164161    /* A version which does not pull in bsearch */
     
    228225IF_FEATURE_SUID(static uid_t ruid;)  /* real uid */
    229226
    230 #if ENABLE_FEATURE_SUID_CONFIG
    231 
    232 /* applets[] is const, so we have to define this "override" structure */
    233 static struct BB_suid_config {
     227# if ENABLE_FEATURE_SUID_CONFIG
     228
     229static struct suid_config_t {
     230    /* next ptr must be first: this struct needs to be llist-compatible */
     231    struct suid_config_t *m_next;
     232    struct bb_uidgid_t m_ugid;
    234233    int m_applet;
    235     uid_t m_uid;
    236     gid_t m_gid;
    237234    mode_t m_mode;
    238     struct BB_suid_config *m_next;
    239235} *suid_config;
    240236
     
    245241{
    246242    struct group *grp = getgrgid(g);
    247 
    248243    if (grp) {
    249244        char **mem;
    250 
    251245        for (mem = grp->gr_mem; *mem; mem++) {
    252246            struct passwd *pwd = getpwnam(*mem);
    253 
    254247            if (pwd && (pwd->pw_uid == u))
    255248                return 1;
     
    259252}
    260253
    261 /* This should probably be a libbb routine.  In that case,
    262  * I'd probably rename it to something like bb_trimmed_slice.
    263  */
     254/* libbb candidate */
    264255static char *get_trimmed_slice(char *s, char *e)
    265256{
     
    279270}
    280271
    281 /* Don't depend on the tools to combine strings. */
    282 static const char config_file[] ALIGN1 = "/etc/busybox.conf";
    283 
    284 /* We don't supply a value for the nul, so an index adjustment is
    285  * necessary below.  Also, we use unsigned short here to save some
    286  * space even though these are really mode_t values. */
    287 static const unsigned short mode_mask[] ALIGN2 = {
    288     /*  SST     sst                 xxx         --- */
    289     S_ISUID,    S_ISUID|S_IXUSR,    S_IXUSR,    0,  /* user */
    290     S_ISGID,    S_ISGID|S_IXGRP,    S_IXGRP,    0,  /* group */
    291     0,          S_IXOTH,            S_IXOTH,    0   /* other */
    292 };
    293 
    294 #define parse_error(x)  do { errmsg = x; goto pe_label; } while (0)
    295 
    296272static void parse_config_file(void)
    297273{
    298     struct BB_suid_config *sct_head;
    299     struct BB_suid_config *sct;
     274    /* Don't depend on the tools to combine strings. */
     275    static const char config_file[] ALIGN1 = "/etc/busybox.conf";
     276
     277    struct suid_config_t *sct_head;
    300278    int applet_no;
    301279    FILE *f;
    302280    const char *errmsg;
    303     char *s;
    304     char *e;
    305     int i;
    306281    unsigned lc;
    307282    smallint section;
    308     char buffer[256];
    309283    struct stat st;
    310 
    311     assert(!suid_config); /* Should be set to NULL by bss init. */
    312284
    313285    ruid = getuid();
     
    319291     || (st.st_uid != 0)                    /* Not owned by root? */
    320292     || (st.st_mode & (S_IWGRP | S_IWOTH))  /* Writable by non-root? */
    321      || !(f = fopen_for_read(config_file))      /* Cannot open? */
     293     || !(f = fopen_for_read(config_file))  /* Cannot open? */
    322294    ) {
    323295        return;
     
    329301
    330302    while (1) {
    331         s = buffer;
    332 
    333         if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */
    334 // why?
    335             if (ferror(f)) {   /* Make sure it wasn't a read error. */
    336                 parse_error("reading");
    337             }
     303        char buffer[256];
     304        char *s;
     305
     306        if (!fgets(buffer, sizeof(buffer), f)) { /* Are we done? */
     307            // Looks like bloat
     308            //if (ferror(f)) {   /* Make sure it wasn't a read error. */
     309            //  errmsg = "reading";
     310            //  goto pe_label;
     311            //}
    338312            fclose(f);
    339313            suid_config = sct_head; /* Success, so set the pointer. */
     
    341315        }
    342316
     317        s = buffer;
    343318        lc++;                   /* Got a (partial) line. */
    344319
     
    352327         * too long if it did end with a newline. */
    353328        if (!strchr(s, '\n') && !feof(f)) {
    354             parse_error("line too long");
     329            errmsg = "line too long";
     330            goto pe_label;
    355331        }
    356332
     
    368344             * whitespace for the section name.  We also require that
    369345             * there are no stray characters after the closing bracket. */
    370             e = strchr(s, ']');
     346            char *e = strchr(s, ']');
    371347            if (!e   /* Missing right bracket? */
    372348             || e[1] /* Trailing characters? */
    373349             || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */
    374350            ) {
    375                 parse_error("section header");
     351                errmsg = "section header";
     352                goto pe_label;
    376353            }
    377354            /* Right now we only have one section so just check it.
     
    398375
    399376            /* First get the key (an applet name in our case). */
    400             e = strchr(s, '=');
     377            char *e = strchr(s, '=');
    401378            if (e) {
    402379                s = get_trimmed_slice(s, e);
    403380            }
    404381            if (!e || !*s) {    /* Missing '=' or empty key. */
    405                 parse_error("keyword");
     382                errmsg = "keyword";
     383                goto pe_label;
    406384            }
    407385
     
    412390            applet_no = find_applet_by_name(s);
    413391            if (applet_no >= 0) {
     392                unsigned i;
     393                struct suid_config_t *sct;
     394
    414395                /* Note: We currently don't check for duplicates!
    415396                 * The last config line for each applet will be the
    416397                 * one used since we insert at the head of the list.
    417398                 * I suppose this could be considered a feature. */
    418                 sct = xmalloc(sizeof(struct BB_suid_config));
     399                sct = xzalloc(sizeof(*sct));
    419400                sct->m_applet = applet_no;
    420                 sct->m_mode = 0;
     401                /*sct->m_mode = 0;*/
    421402                sct->m_next = sct_head;
    422403                sct_head = sct;
     
    427408
    428409                for (i = 0; i < 3; i++) {
    429                     /* There are 4 chars + 1 nul for each of user/group/other. */
    430                     static const char mode_chars[] ALIGN1 = "Ssx-\0" "Ssx-\0" "Ttx-";
    431 
    432                     const char *q;
    433                     q = strchrnul(mode_chars + 5*i, *e++);
    434                     if (!*q) {
    435                         parse_error("mode");
     410                    /* There are 4 chars for each of user/group/other.
     411                     * "x-xx" instead of "x-" are to make
     412                     * "idx > 3" check catch invalid chars.
     413                     */
     414                    static const char mode_chars[] ALIGN1 = "Ssx-" "Ssx-" "x-xx";
     415                    static const unsigned short mode_mask[] ALIGN2 = {
     416                        S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* Ssx- */
     417                        S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* Ssx- */
     418                                                  S_IXOTH, 0  /*   x- */
     419                    };
     420                    const char *q = strchrnul(mode_chars + 4*i, *e);
     421                    unsigned idx = q - (mode_chars + 4*i);
     422                    if (idx > 3) {
     423                        errmsg = "mode";
     424                        goto pe_label;
    436425                    }
    437                     /* Adjust by -i to account for nul. */
    438                     sct->m_mode |= mode_mask[(q - mode_chars) - i];
     426                    sct->m_mode |= mode_mask[q - mode_chars];
     427                    e++;
    439428                }
    440429
    441                 /* Now get the the user/group info. */
     430                /* Now get the user/group info. */
    442431
    443432                s = skip_whitespace(e);
    444 
    445                 /* Note: we require whitespace between the mode and the
    446                  * user/group info. */
    447                 if ((s == e) || !(e = strchr(s, '.'))) {
    448                     parse_error("<uid>.<gid>");
    449                 }
    450                 *e++ = '\0';
    451 
    452                 /* We can't use get_ug_id here since it would exit()
    453                  * if a uid or gid was not found.  Oh well... */
    454                 sct->m_uid = bb_strtoul(s, NULL, 10);
    455                 if (errno) {
    456                     struct passwd *pwd = getpwnam(s);
    457                     if (!pwd) {
    458                         parse_error("user");
     433                /* Default is 0.0, else parse USER.GROUP: */
     434                if (*s) {
     435                    /* We require whitespace between mode and USER.GROUP */
     436                    if ((s == e) || !(e = strchr(s, '.'))) {
     437                        errmsg = "uid.gid";
     438                        goto pe_label;
    459439                    }
    460                     sct->m_uid = pwd->pw_uid;
    461                 }
    462 
    463                 sct->m_gid = bb_strtoul(e, NULL, 10);
    464                 if (errno) {
    465                     struct group *grp;
    466                     grp = getgrnam(e);
    467                     if (!grp) {
    468                         parse_error("group");
     440                    *e = ':'; /* get_uidgid needs USER:GROUP syntax */
     441                    if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) {
     442                        errmsg = "unknown user/group";
     443                        goto pe_label;
    469444                    }
    470                     sct->m_gid = grp->gr_gid;
    471445                }
    472446            }
     
    482456         * are used in some future version of busybox. */
    483457        if (!section) {
    484             parse_error("keyword outside section");
     458            errmsg = "keyword outside section";
     459            goto pe_label;
    485460        }
    486461
     
    488463
    489464 pe_label:
    490     fprintf(stderr, "Parse error in %s, line %d: %s\n",
    491             config_file, lc, errmsg);
    492 
    493465    fclose(f);
     466    bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg);
     467
    494468    /* Release any allocated memory before returning. */
    495     while (sct_head) {
    496         sct = sct_head->m_next;
    497         free(sct_head);
    498         sct_head = sct;
    499     }
    500 }
    501 #else
     469    llist_free((llist_t*)sct_head, NULL);
     470}
     471# else
    502472static inline void parse_config_file(void)
    503473{
    504474    IF_FEATURE_SUID(ruid = getuid();)
    505475}
    506 #endif /* FEATURE_SUID_CONFIG */
    507 
    508 
    509 #if ENABLE_FEATURE_SUID
     476# endif /* FEATURE_SUID_CONFIG */
     477
     478
     479# if ENABLE_FEATURE_SUID
    510480static void check_suid(int applet_no)
    511481{
     
    516486    rgid = getgid();
    517487
    518 #if ENABLE_FEATURE_SUID_CONFIG
     488#  if ENABLE_FEATURE_SUID_CONFIG
    519489    if (suid_cfg_readable) {
    520490        uid_t uid;
    521         struct BB_suid_config *sct;
     491        struct suid_config_t *sct;
    522492        mode_t m;
    523493
     
    528498        goto check_need_suid;
    529499 found:
     500        /* Is this user allowed to run this applet? */
    530501        m = sct->m_mode;
    531         if (sct->m_uid == ruid)
     502        if (sct->m_ugid.uid == ruid)
    532503            /* same uid */
    533504            m >>= 6;
    534         else if ((sct->m_gid == rgid) || ingroup(ruid, sct->m_gid))
     505        else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid))
    535506            /* same group / in group */
    536507            m >>= 3;
    537 
    538         if (!(m & S_IXOTH))           /* is x bit not set ? */
    539             bb_error_msg_and_die("you have no permission to run this applet!");
    540 
    541         /* _both_ sgid and group_exec have to be set for setegid */
    542         if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
    543             rgid = sct->m_gid;
    544         /* else (no setegid) we will set egid = rgid */
     508        if (!(m & S_IXOTH)) /* is x bit not set? */
     509            bb_error_msg_and_die("you have no permission to run this applet");
    545510
    546511        /* We set effective AND saved ids. If saved-id is not set
    547          * like we do below, seteiud(0) can still later succeed! */
     512         * like we do below, seteuid(0) can still later succeed! */
     513
     514        /* Are we directed to change gid
     515         * (APPLET = *s* USER.GROUP or APPLET = *S* USER.GROUP)?
     516         */
     517        if (sct->m_mode & S_ISGID)
     518            rgid = sct->m_ugid.gid;
     519        /* else: we will set egid = rgid, thus dropping sgid effect */
    548520        if (setresgid(-1, rgid, rgid))
    549521            bb_perror_msg_and_die("setresgid");
    550522
    551         /* do we have to set effective uid? */
     523        /* Are we directed to change uid
     524         * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)?
     525         */
    552526        uid = ruid;
    553527        if (sct->m_mode & S_ISUID)
    554             uid = sct->m_uid;
    555         /* else (no seteuid) we will set euid = ruid */
    556 
     528            uid = sct->m_ugid.uid;
     529        /* else: we will set euid = ruid, thus dropping suid effect */
    557530        if (setresuid(-1, uid, uid))
    558531            bb_perror_msg_and_die("setresuid");
    559         return;
    560     }
    561 #if !ENABLE_FEATURE_SUID_CONFIG_QUIET
     532
     533        goto ret;
     534    }
     535#   if !ENABLE_FEATURE_SUID_CONFIG_QUIET
    562536    {
    563537        static bool onetime = 0;
     
    565539        if (!onetime) {
    566540            onetime = 1;
    567             fprintf(stderr, "Using fallback suid method\n");
    568         }
    569     }
    570 #endif
     541            bb_error_msg("using fallback suid method");
     542        }
     543    }
     544#   endif
    571545 check_need_suid:
    572 #endif
    573     if (APPLET_SUID(applet_no) == _BB_SUID_REQUIRE) {
     546#  endif
     547    if (APPLET_SUID(applet_no) == BB_SUID_REQUIRE) {
    574548        /* Real uid is not 0. If euid isn't 0 too, suid bit
    575549         * is most probably not set on our executable */
    576550        if (geteuid())
    577551            bb_error_msg_and_die("must be suid to work properly");
    578     } else if (APPLET_SUID(applet_no) == _BB_SUID_DROP) {
     552    } else if (APPLET_SUID(applet_no) == BB_SUID_DROP) {
    579553        xsetgid(rgid);  /* drop all privileges */
    580554        xsetuid(ruid);
    581555    }
    582 }
    583 #else
    584 #define check_suid(x) ((void)0)
    585 #endif /* FEATURE_SUID */
    586 
    587 
    588 #if ENABLE_FEATURE_INSTALLER
     556#  if ENABLE_FEATURE_SUID_CONFIG
     557 ret: ;
     558    llist_free((llist_t*)suid_config, NULL);
     559#  endif
     560}
     561# else
     562#  define check_suid(x) ((void)0)
     563# endif /* FEATURE_SUID */
     564
     565
     566# if ENABLE_FEATURE_INSTALLER
    589567static const char usr_bin [] ALIGN1 = "/usr/bin/";
    590568static const char usr_sbin[] ALIGN1 = "/usr/sbin/";
     
    593571    &usr_bin [4], /* "/bin/" */
    594572    &usr_sbin[4]  /* "/sbin/" */
    595 # if !ENABLE_INSTALL_NO_USR
     573#  if !ENABLE_INSTALL_NO_USR
    596574    ,usr_bin
    597575    ,usr_sbin
    598 # endif
     576#  endif
    599577};
    600 
    601578
    602579/* create (sym)links for each applet */
     
    629606    }
    630607}
    631 #else
    632 # define install_links(x,y,z) ((void)0)
    633 #endif
     608# else
     609#  define install_links(x,y,z) ((void)0)
     610# endif
    634611
    635612/* If we were called as "busybox..." */
     
    652629        full_write2_str(" multi-call binary.\n"); /* reuse */
    653630        full_write2_str(
    654             "Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko\n"
    655             "and others. Licensed under GPLv2.\n"
    656             "See source distribution for full notice.\n"
     631            "BusyBox is copyrighted by many authors between 1998-2012.\n"
     632            "Licensed under GPLv2. See source distribution for detailed\n"
     633            "copyright notices.\n"
    657634            "\n"
    658             "Usage: busybox [function] [arguments]...\n"
    659             "   or: busybox --list[-full]\n"
     635            "Usage: busybox [function [arguments]...]\n"
     636            "   or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n"
     637            IF_FEATURE_INSTALLER(
     638            "   or: busybox --install [-s] [DIR]\n"
     639            )
    660640            "   or: function [arguments]...\n"
    661641            "\n"
     
    696676        dup2(1, 2);
    697677        while (*a) {
    698 #if ENABLE_FEATURE_INSTALLER
    699             if (argv[1][6]) /* --list-path? */
     678# if ENABLE_FEATURE_INSTALLER
     679            if (argv[1][6]) /* --list-full? */
    700680                full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
    701 #endif
     681# endif
    702682            full_write2_str(a);
    703683            full_write2_str("\n");
     
    711691        int use_symbolic_links;
    712692        const char *busybox;
     693
    713694        busybox = xmalloc_readlink(bb_busybox_exec_path);
    714         if (!busybox)
    715             busybox = bb_busybox_exec_path;
    716         /* busybox --install [-s] [DIR]: */
    717         /* -s: make symlinks */
    718         /* DIR: directory to install links to */
    719         use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && argv++);
     695        if (!busybox) {
     696            /* bb_busybox_exec_path is usually "/proc/self/exe".
     697             * In chroot, readlink("/proc/self/exe") usually fails.
     698             * In such case, better use argv[0] as symlink target
     699             * if it is a full path name.
     700             */
     701            if (argv[0][0] != '/')
     702                bb_error_msg_and_die("'%s' is not an absolute path", argv[0]);
     703            busybox = argv[0];
     704        }
     705        /* busybox --install [-s] [DIR]:
     706         * -s: make symlinks
     707         * DIR: directory to install links to
     708         */
     709        use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv);
    720710        install_links(busybox, use_symbolic_links, argv[2]);
    721711        return 0;
     
    759749         * should be no different from e.g. "test --foo".  */
    760750//TODO: just compare applet_no with APPLET_NO_test
    761         if (!ENABLE_TEST || strcmp(applet_name, "test") != 0)
     751        if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) {
     752            /* If you want "foo --help" to return 0: */
     753            /*xfunc_error_retval = 0;*/
    762754            bb_show_usage();
     755        }
    763756    }
    764757    if (ENABLE_FEATURE_SUID)
     
    772765    if (applet >= 0)
    773766        run_applet_no_and_exit(applet, argv);
    774     if (!strncmp(name, "busybox", 7))
     767    if (strncmp(name, "busybox", 7) == 0)
    775768        exit(busybox_main(argv));
    776769}
     
    787780{
    788781    /* Tweak malloc for reduced memory consumption */
    789 #ifndef PAGE_SIZE
    790 # define PAGE_SIZE (4*1024) /* guess */
    791 #endif
    792782#ifdef M_TRIM_THRESHOLD
    793783    /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory
     
    795785     * Default is way too big: 256k
    796786     */
    797     mallopt(M_TRIM_THRESHOLD, 2 * PAGE_SIZE);
     787    mallopt(M_TRIM_THRESHOLD, 8 * 1024);
    798788#endif
    799789#ifdef M_MMAP_THRESHOLD
     
    801791     * Default is too big: 256k
    802792     */
    803     mallopt(M_MMAP_THRESHOLD, 8 * PAGE_SIZE - 256);
     793    mallopt(M_MMAP_THRESHOLD, 32 * 1024 - 256);
     794#endif
     795
     796#if !BB_MMU
     797    /* NOMMU re-exec trick sets high-order bit in first byte of name */
     798    if (argv[0][0] & 0x80) {
     799        re_execed = 1;
     800        argv[0][0] &= 0x7f;
     801    }
    804802#endif
    805803
    806804#if defined(SINGLE_APPLET_MAIN)
    807     /* Only one applet is selected by the user! */
     805    /* Only one applet is selected in .config */
     806    if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) {
     807        /* "busybox <applet> <params>" should still work as expected */
     808        argv++;
     809    }
    808810    /* applet_names in this case is just "applet\0\0" */
    809811    lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv));
     
    812814    lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
    813815
    814 #if !BB_MMU
    815     /* NOMMU re-exec trick sets high-order bit in first byte of name */
    816     if (argv[0][0] & 0x80) {
    817         re_execed = 1;
    818         argv[0][0] &= 0x7f;
    819     }
    820 #endif
    821816    applet_name = argv[0];
    822817    if (applet_name[0] == '-')
  • branches/3.2/mindi-busybox/libbb/bb_askpass.c

    r2725 r3232  
    3131    struct termios tio, oldtio;
    3232
     33    fputs(prompt, stdout);
     34    fflush_all();
     35    tcflush(fd, TCIFLUSH);
     36
    3337    tcgetattr(fd, &oldtio);
    34     tcflush(fd, TCIFLUSH);
    3538    tio = oldtio;
    36 #ifndef IUCLC
    37 # define IUCLC 0
     39#if 0
     40    /* Switch off UPPERCASE->lowercase conversion (never used since 198x)
     41     * and XON/XOFF (why we want to mess with this??)
     42     */
     43# ifndef IUCLC
     44#  define IUCLC 0
     45# endif
     46    tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
    3847#endif
    39     tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
    40     tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
     48    /* Switch off echo */
     49    tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
    4150    tcsetattr(fd, TCSANOW, &tio);
    4251
     
    5059        alarm(timeout);
    5160    }
    52 
    53     fputs(prompt, stdout);
    54     fflush_all();
    5561
    5662    if (!passwd)
  • branches/3.2/mindi-busybox/libbb/bb_pwd.c

    r2725 r3232  
    7373}
    7474
    75 char* FAST_FUNC uid2uname_utoa(long uid)
     75char* FAST_FUNC uid2uname_utoa(uid_t uid)
    7676{
    7777    char *name = uid2uname(uid);
     
    7979}
    8080
    81 char* FAST_FUNC gid2group_utoa(long gid)
     81char* FAST_FUNC gid2group_utoa(gid_t gid)
    8282{
    8383    char *name = gid2group(gid);
  • branches/3.2/mindi-busybox/libbb/bb_strtonum.c

    r2725 r3232  
    3737}
    3838
    39 static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr)
     39static unsigned long long handle_errors(unsigned long long v, char **endp)
    4040{
    41     if (endp) *endp = endptr;
     41    char next_ch = **endp;
    4242
    4343    /* errno is already set to ERANGE by strtoXXX if value overflowed */
    44     if (endptr[0]) {
     44    if (next_ch) {
    4545        /* "1234abcg" or out-of-range? */
    46         if (isalnum(endptr[0]) || errno)
     46        if (isalnum(next_ch) || errno)
    4747            return ret_ERANGE();
    4848        /* good number, just suspicious terminator */
     
    5858    char *endptr;
    5959
     60    if (!endp) endp = &endptr;
     61    *endp = (char*) arg;
     62
    6063    /* strtoul("  -4200000000") returns 94967296, errno 0 (!) */
    6164    /* I don't think that this is right. Preventing this... */
     
    6467    /* not 100% correct for lib func, but convenient for the caller */
    6568    errno = 0;
    66     v = strtoull(arg, &endptr, base);
    67     return handle_errors(v, endp, endptr);
     69    v = strtoull(arg, endp, base);
     70    return handle_errors(v, endp);
    6871}
    6972
     
    7275    unsigned long long v;
    7376    char *endptr;
     77    char first;
     78
     79    if (!endp) endp = &endptr;
     80    *endp = (char*) arg;
    7481
    7582    /* Check for the weird "feature":
    7683     * a "-" string is apparently a valid "number" for strto[u]l[l]!
    7784     * It returns zero and errno is 0! :( */
    78     char first = (arg[0] != '-' ? arg[0] : arg[1]);
     85    first = (arg[0] != '-' ? arg[0] : arg[1]);
    7986    if (!isalnum(first)) return ret_ERANGE();
    8087
    8188    errno = 0;
    82     v = strtoll(arg, &endptr, base);
    83     return handle_errors(v, endp, endptr);
     89    v = strtoll(arg, endp, base);
     90    return handle_errors(v, endp);
    8491}
    8592
     
    9097    char *endptr;
    9198
     99    if (!endp) endp = &endptr;
     100    *endp = (char*) arg;
     101
    92102    if (!isalnum(arg[0])) return ret_ERANGE();
    93103    errno = 0;
    94     v = strtoul(arg, &endptr, base);
    95     return handle_errors(v, endp, endptr);
     104    v = strtoul(arg, endp, base);
     105    return handle_errors(v, endp);
    96106}
    97107
     
    100110    long v;
    101111    char *endptr;
     112    char first;
    102113
    103     char first = (arg[0] != '-' ? arg[0] : arg[1]);
     114    if (!endp) endp = &endptr;
     115    *endp = (char*) arg;
     116
     117    first = (arg[0] != '-' ? arg[0] : arg[1]);
    104118    if (!isalnum(first)) return ret_ERANGE();
    105119
    106120    errno = 0;
    107     v = strtol(arg, &endptr, base);
    108     return handle_errors(v, endp, endptr);
     121    v = strtol(arg, endp, base);
     122    return handle_errors(v, endp);
    109123}
    110124#endif
     
    116130    char *endptr;
    117131
     132    if (!endp) endp = &endptr;
     133    *endp = (char*) arg;
     134
    118135    if (!isalnum(arg[0])) return ret_ERANGE();
    119136    errno = 0;
    120     v = strtoul(arg, &endptr, base);
     137    v = strtoul(arg, endp, base);
    121138    if (v > UINT_MAX) return ret_ERANGE();
    122     return handle_errors(v, endp, endptr);
     139    return handle_errors(v, endp);
    123140}
    124141
     
    127144    long v;
    128145    char *endptr;
     146    char first;
    129147
    130     char first = (arg[0] != '-' ? arg[0] : arg[1]);
     148    if (!endp) endp = &endptr;
     149    *endp = (char*) arg;
     150
     151    first = (arg[0] != '-' ? arg[0] : arg[1]);
    131152    if (!isalnum(first)) return ret_ERANGE();
    132153
    133154    errno = 0;
    134     v = strtol(arg, &endptr, base);
     155    v = strtol(arg, endp, base);
    135156    if (v > INT_MAX) return ret_ERANGE();
    136157    if (v < INT_MIN) return ret_ERANGE();
    137     return handle_errors(v, endp, endptr);
     158    return handle_errors(v, endp);
    138159}
    139160#endif
  • branches/3.2/mindi-busybox/libbb/copy_file.c

    r2725 r3232  
    7979    struct stat source_stat;
    8080    struct stat dest_stat;
    81     signed char retval = 0;
    82     signed char dest_exists = 0;
    83     signed char ovr;
     81    smallint retval = 0;
     82    smallint dest_exists = 0;
     83    smallint ovr;
    8484
    8585/* Inverse of cp -d ("cp without -d") */
     
    148148        }
    149149
    150         /* Create DEST */
    151150        if (dest_exists) {
    152151            if (!S_ISDIR(dest_stat.st_mode)) {
     
    157156             * this check and actual creation of files inside dest */
    158157        } else {
     158            /* Create DEST */
    159159            mode_t mode;
    160160            saved_umask = umask(0);
  • branches/3.2/mindi-busybox/libbb/correct_password.c

    r2725 r3232  
    4242    const char *correct;
    4343    int r;
    44 #if ENABLE_FEATURE_SHADOWPASSWDS
    45     /* Using _r function to avoid pulling in static buffers */
    46     struct spwd spw;
    47     char buffer[256];
    48 #endif
    49 
    5044    /* fake salt. crypt() can choke otherwise. */
    5145    correct = "aa";
     
    5650    correct = pw->pw_passwd;
    5751#if ENABLE_FEATURE_SHADOWPASSWDS
     52    /* Using _r function to avoid pulling in static buffers */
    5853    if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) {
     54        struct spwd spw;
     55        char buffer[256];
    5956        /* getspnam_r may return 0 yet set result to NULL.
    6057         * At least glibc 2.4 does this. Be extra paranoid here. */
  • branches/3.2/mindi-busybox/libbb/crc32.c

    r2725 r3232  
    6060
    6161    while (buf != end) {
    62                 val = crc_table[(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8);
     62        val = crc_table[(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8);
    6363        buf = (uint8_t*)buf + 1;
    6464    }
  • branches/3.2/mindi-busybox/libbb/die_if_bad_username.c

    r2725 r3232  
    1919void FAST_FUNC die_if_bad_username(const char *name)
    2020{
    21     /* 1st char being dash or dot isn't valid: */
     21    const char *start = name;
     22
     23    /* 1st char being dash or dot isn't valid:
     24     * for example, name like ".." can make adduser
     25     * chown "/home/.." recursively - NOT GOOD.
     26     * Name of just a single "$" is also rejected.
     27     */
    2228    goto skip;
    23     /* For example, name like ".." can make adduser
    24      * chown "/home/.." recursively - NOT GOOD
    25      */
    2629
    2730    do {
    28         if (*name == '-' || *name == '.')
    29             continue;
    30  skip:
    31         if (isalnum(*name)
    32          || *name == '_'
    33          || *name == '@'
     31        unsigned char ch;
     32
     33        /* These chars are valid unless they are at the 1st pos: */
     34        if (*name == '-'
     35         || *name == '.'
     36        /* $ is allowed if it's the last char: */
    3437         || (*name == '$' && !name[1])
    3538        ) {
    3639            continue;
    3740        }
    38         bb_error_msg_and_die("illegal character '%c'", *name);
     41 skip:
     42        ch = *name;
     43        if (ch == '_'
     44        /* || ch == '@' -- we disallow this too. Think about "user@host" */
     45        /* open-coded isalnum: */
     46         || (ch >= '0' && ch <= '9')
     47         || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z')
     48        ) {
     49            continue;
     50        }
     51        bb_error_msg_and_die("illegal character with code %u at position %u",
     52                (unsigned)ch, (unsigned)(name - start));
    3953    } while (*++name);
     54
     55    /* The minimum size of the login name is one char or two if
     56     * last char is the '$'. Violations of this are caught above.
     57     * The maximum size of the login name is LOGIN_NAME_MAX
     58     * including the terminating null byte.
     59     */
     60    if (name - start >= LOGIN_NAME_MAX)
     61        bb_error_msg_and_die("name is too long");
    4062}
  • branches/3.2/mindi-busybox/libbb/dump.c

    r2725 r3232  
    7272             * case it's a %s format.
    7373             */
    74             while (strchr(index_str + 1, *++fmt));
     74            while (strchr(index_str + 1, *++fmt))
     75                continue;
    7576            if (*fmt == '.' && isdigit(*++fmt)) {
    7677                prec = atoi(fmt);
     
    100101{
    101102    enum { NOTOKAY, USEBCNT, USEPREC } sokay;
    102     PR *pr, **nextpr = NULL;
    103103    FU *fu;
     104    PR *pr;
    104105    char *p1, *p2, *p3;
    105106    char savech, *fmtp;
     
    112113         * conversion character gets its own.
    113114         */
    114         for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {
     115        for (nconv = 0, fmtp = fu->fmt; *fmtp; ) {
    115116            /* NOSTRICT */
    116117            /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL*/
     
    118119            if (!fu->nextpr)
    119120                fu->nextpr = pr;
    120             /* ignore nextpr -- its unused inside the loop and is
    121              * uninitialized 1st time through.
    122              */
    123121
    124122            /* skip preceding text and up to the next % sign */
     
    296294     * repeat it as necessary.
    297295     *
    298      * if, rep count is greater than 1, no trailing whitespace
     296     * if rep count is greater than 1, no trailing whitespace
    299297     * gets output from the last iteration of the format unit.
    300298     */
    301299    for (fu = fs->nextfu; fu; fu = fu->nextfu) {
    302         if (!fu->nextfu && fs->bcnt < dumper->blocksize
    303          && !(fu->flags & F_SETREP) && fu->bcnt
     300        if (!fu->nextfu
     301         && fs->bcnt < dumper->blocksize
     302         && !(fu->flags & F_SETREP)
     303         && fu->bcnt
    304304        ) {
    305305            fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt;
    306306        }
    307         if (fu->reps > 1) {
     307        if (fu->reps > 1 && fu->nextpr) {
    308308            for (pr = fu->nextpr;; pr = pr->nextpr)
    309309                if (!pr->nextpr)
     
    725725    for (;;) {
    726726        p = skip_whitespace(p);
    727         if (!*p) {
     727        if (*p == '\0') {
    728728            break;
    729729        }
     
    753753        /* skip slash and trailing white space */
    754754        if (*p == '/') {
    755             p = skip_whitespace(++p);
     755            p = skip_whitespace(p + 1);
    756756        }
    757757
     
    767767            tfu->bcnt = atoi(savep);
    768768            /* skip trailing white space */
    769             p = skip_whitespace(++p);
     769            p = skip_whitespace(p + 1);
    770770        }
    771771
     
    775775        }
    776776        for (savep = ++p; *p != '"';) {
    777             if (*p++ == 0) {
     777            if (*p++ == '\0') {
    778778                bb_error_msg_and_die("bad format {%s}", fmt);
    779779            }
     
    786786        /* alphabetic escape sequences have to be done in place */
    787787        for (p2 = p1;; ++p1, ++p2) {
    788             if (!*p1) {
     788            if (*p1 == '\0') {
    789789                *p2 = *p1;
    790790                break;
  • branches/3.2/mindi-busybox/libbb/execable.c

    r2725 r3232  
    6969
    7070#if ENABLE_FEATURE_PREFER_APPLETS
    71 /* just like the real execvp, but try to launch an applet named 'file' first
    72  */
    73 int FAST_FUNC bb_execvp(const char *file, char *const argv[])
     71/* just like the real execvp, but try to launch an applet named 'file' first */
     72int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
    7473{
    75     return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file,
    76                     argv);
     74    if (find_applet_by_name(file) >= 0)
     75        execvp(bb_busybox_exec_path, argv);
     76    return execvp(file, argv);
    7777}
    7878#endif
  • branches/3.2/mindi-busybox/libbb/find_mount_point.c

    r2725 r3232  
    3131    devno_of_name = s.st_dev;
    3232    block_dev = 0;
    33     if (S_ISBLK(s.st_mode)) {
     33    /* Why S_ISCHR? - UBI volumes use char devices, not block */
     34    if (S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode)) {
    3435        devno_of_name = s.st_rdev;
    3536        block_dev = 1;
     
    4445         * and it makes sense to always ignore it.
    4546         * Otherwise people can't reference their "real" root! */
    46         if (strcmp(mountEntry->mnt_fsname, "rootfs") == 0)
     47        if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(mountEntry->mnt_fsname, "rootfs") == 0)
    4748            continue;
    4849
  • branches/3.2/mindi-busybox/libbb/find_root_device.c

    r2725 r3232  
    3030    int len, rem;
    3131
     32    len = strlen(ap->devpath);
     33    rem = DEVNAME_MAX-2 - len;
     34    if (rem <= 0)
     35        return NULL;
     36
    3237    dir = opendir(ap->devpath);
    3338    if (!dir)
    3439        return NULL;
    3540
    36     len = strlen(ap->devpath);
    37     rem = DEVNAME_MAX-2 - len;
    38     if (rem <= 0)
    39         return NULL;
    4041    ap->devpath[len++] = '/';
    4142
  • branches/3.2/mindi-busybox/libbb/get_last_path_component.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9#include "libbb.h"
    910
    10 #include "libbb.h"
     11const char* FAST_FUNC bb_basename(const char *name)
     12{
     13    const char *cp = strrchr(name, '/');
     14    if (cp)
     15        return cp + 1;
     16    return name;
     17}
     18
    1119/*
    1220 * "/"        -> "/"
  • branches/3.2/mindi-busybox/libbb/get_line_from_file.c

    r2725 r3232  
    1212#include "libbb.h"
    1313
    14 /* This function reads an entire line from a text file, up to a newline
    15  * or NUL byte, inclusive.  It returns a malloc'ed char * which
    16  * must be free'ed by the caller.  If end is NULL '\n' isn't considered
    17  * end of line.  If end isn't NULL, length of the chunk is stored in it.
    18  * If lineno is not NULL, *lineno is incremented for each line,
    19  * and also trailing '\' is recognized as line continuation.
    20  *
    21  * Returns NULL if EOF/error. */
    22 char* FAST_FUNC bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno)
     14char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end)
    2315{
    2416    int ch;
    25     int idx = 0;
     17    unsigned idx = 0;
    2618    char *linebuf = NULL;
    27     int linebufsz = 0;
    2819
    2920    while ((ch = getc(file)) != EOF) {
    3021        /* grow the line buffer as necessary */
    31         if (idx >= linebufsz) {
    32             linebufsz += 256;
    33             linebuf = xrealloc(linebuf, linebufsz);
    34         }
     22        if (!(idx & 0xff))
     23            linebuf = xrealloc(linebuf, idx + 0x100);
    3524        linebuf[idx++] = (char) ch;
    36         if (!ch)
     25        if (ch == '\0')
    3726            break;
    38         if (end && ch == '\n') {
    39             if (lineno == NULL)
    40                 break;
    41             (*lineno)++;
    42             if (idx < 2 || linebuf[idx-2] != '\\')
    43                 break;
    44             idx -= 2;
    45         }
     27        if (end && ch == '\n')
     28            break;
    4629    }
    4730    if (end)
     
    5841    }
    5942    return linebuf;
    60 }
    61 
    62 char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end)
    63 {
    64     return bb_get_chunk_with_continuation(file, end, NULL);
    6543}
    6644
  • branches/3.2/mindi-busybox/libbb/getopt32.c

    r2725 r3232  
    88 */
    99
    10 #include <getopt.h>
     10#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG
     11# include <getopt.h>
     12#endif
    1113#include "libbb.h"
    1214
     
    8183
    8284        static const char applet_longopts[] ALIGN1 =
    83         //"name\0" has_arg val
    84         "verbose\0" No_argument "v"
    85         ;
     85                //"name\0" has_arg val
     86                "verbose\0" No_argument "v"
     87                ;
    8688        applet_long_options = applet_longopts;
    8789
     
    227229        opt_complementary = "b--cf:c--bf:f--bc".  If two of the
    228230        mutually exclusive options are found, getopt32 will call
    229     bb_show_usage() and die.
     231        bb_show_usage() and die.
    230232
    231233 "x--x" Variation of the above, it means that -x option should occur
     
    466468        for (on_off = complementary; on_off->opt_char; on_off++)
    467469            if (on_off->opt_char == *s)
    468                 break;
     470                goto found_opt;
     471        /* Without this, diagnostic of such bugs is not easy */
     472        bb_error_msg_and_die("NO OPT %c!", *s);
     473 found_opt:
    469474        if (c == ':' && s[2] == ':') {
    470475            on_off->param_type = PARAM_LIST;
     
    473478        if (c == '+' && (s[2] == ':' || s[2] == '\0')) {
    474479            on_off->param_type = PARAM_INT;
     480            s++;
    475481            continue;
    476482        }
     
    532538    /* In case getopt32 was already called:
    533539     * reset the libc getopt() function, which keeps internal state.
    534      * run_nofork_applet_prime() does this, but we might end up here
     540     * run_nofork_applet() does this, but we might end up here
    535541     * also via gunzip_main() -> gzip_main(). Play safe.
    536542     */
     
    542548#endif
    543549    /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */
    544 
    545     pargv = NULL;
    546550
    547551    /* Note: just "getopt() <= 0" will not work well for
     
    575579        if (on_off->counter)
    576580            (*(on_off->counter))++;
    577         if (on_off->param_type == PARAM_LIST) {
    578             if (optarg)
     581        if (optarg) {
     582            if (on_off->param_type == PARAM_LIST) {
    579583                llist_add_to_end((llist_t **)(on_off->optarg), optarg);
    580         } else if (on_off->param_type == PARAM_INT) {
    581             if (optarg)
     584            } else if (on_off->param_type == PARAM_INT) {
    582585//TODO: xatoi_positive indirectly pulls in printf machinery
    583586                *(unsigned*)(on_off->optarg) = xatoi_positive(optarg);
    584         } else if (on_off->optarg) {
    585             if (optarg)
     587            } else if (on_off->optarg) {
    586588                *(char **)(on_off->optarg) = optarg;
    587         }
    588         if (pargv != NULL)
    589             break;
     589            }
     590        }
    590591    }
    591592
  • branches/3.2/mindi-busybox/libbb/getpty.c

    r2725 r3232  
    2020        grantpt(p); /* chmod+chown corresponding slave pty */
    2121        unlockpt(p); /* (what does this do?) */
    22 #if 0 /* if ptsname_r is not available... */
    23         const char *name;
    24         name = ptsname(p); /* find out the name of slave pty */
    25         if (!name) {
    26             bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
     22# ifndef HAVE_PTSNAME_R
     23        {
     24            const char *name;
     25            name = ptsname(p); /* find out the name of slave pty */
     26            if (!name) {
     27                bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
     28            }
     29            safe_strncpy(line, name, GETPTY_BUFSIZE);
    2730        }
    28         safe_strncpy(line, name, GETPTY_BUFSIZE);
    29 #else
     31# else
    3032        /* find out the name of slave pty */
    3133        if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
     
    3335        }
    3436        line[GETPTY_BUFSIZE-1] = '\0';
    35 #endif
     37# endif
    3638        return p;
    3739    }
  • branches/3.2/mindi-busybox/libbb/hash_md5_sha.c

    r2725 r3232  
    3232}
    3333
     34/* rotl64 only used for sha3 currently */
     35static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n)
     36{
     37    return (x << n) | (x >> (64 - n));
     38}
    3439
    3540/* Feed data through a temporary buffer.
     
    5257        buffer = (const char *)buffer + remaining;
    5358        bufpos += remaining;
    54         /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
     59        /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
    5560        bufpos -= 64;
    5661        if (bufpos != 0)
     
    105110
    106111/* 0: fastest, 3: smallest */
    107 #if CONFIG_MD5_SIZE_VS_SPEED < 0
    108 # define MD5_SIZE_VS_SPEED 0
    109 #elif CONFIG_MD5_SIZE_VS_SPEED > 3
    110 # define MD5_SIZE_VS_SPEED 3
     112#if CONFIG_MD5_SMALL < 0
     113# define MD5_SMALL 0
     114#elif CONFIG_MD5_SMALL > 3
     115# define MD5_SMALL 3
    111116#else
    112 # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED
     117# define MD5_SMALL CONFIG_MD5_SMALL
    113118#endif
    114119
     
    130135static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx)
    131136{
    132 #if MD5_SIZE_VS_SPEED > 0
     137#if MD5_SMALL > 0
    133138    /* Before we start, one word to the strange constants.
    134139       They are defined in RFC 1321 as
     
    158163    };
    159164    static const char P_array[] ALIGN1 = {
    160 # if MD5_SIZE_VS_SPEED > 1
     165# if MD5_SMALL > 1
    161166        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
    162167# endif
     
    172177    uint32_t D = ctx->hash[3];
    173178
    174 #if MD5_SIZE_VS_SPEED >= 2  /* 2 or 3 */
     179#if MD5_SMALL >= 2  /* 2 or 3 */
    175180
    176181    static const char S_array[] ALIGN1 = {
     
    186191    uint32_t temp;
    187192
    188 # if BB_BIG_ENDIAN
    189     for (i = 0; i < 16; i++)
    190         words[i] = SWAP_LE32(words[i]);
    191 # endif
    192 
    193 # if MD5_SIZE_VS_SPEED == 3
     193    if (BB_BIG_ENDIAN)
     194        for (i = 0; i < 16; i++)
     195            words[i] = SWAP_LE32(words[i]);
     196
     197# if MD5_SMALL == 3
    194198    pc = C_array;
    195199    pp = P_array;
     
    221225        B = temp;
    222226    }
    223 # else  /* MD5_SIZE_VS_SPEED == 2 */
     227# else  /* MD5_SMALL == 2 */
    224228    pc = C_array;
    225229    pp = P_array;
     
    272276    ctx->hash[3] += D;
    273277
    274 #else  /* MD5_SIZE_VS_SPEED == 0 or 1 */
     278#else  /* MD5_SMALL == 0 or 1 */
    275279
    276280    uint32_t A_save = A;
     
    278282    uint32_t C_save = C;
    279283    uint32_t D_save = D;
    280 # if MD5_SIZE_VS_SPEED == 1
     284# if MD5_SMALL == 1
    281285    const uint32_t *pc;
    282286    const char *pp;
     
    300304
    301305    /* Round 1 */
    302 # if MD5_SIZE_VS_SPEED == 1
     306# if MD5_SMALL == 1
    303307    pc = C_array;
    304308    for (i = 0; i < 4; i++) {
     
    340344
    341345    /* Round 2 */
    342 # if MD5_SIZE_VS_SPEED == 1
     346# if MD5_SMALL == 1
    343347    pp = P_array;
    344348    for (i = 0; i < 4; i++) {
     
    368372
    369373    /* Round 3 */
    370 # if MD5_SIZE_VS_SPEED == 1
     374# if MD5_SMALL == 1
    371375    for (i = 0; i < 4; i++) {
    372376        OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
     
    395399
    396400    /* Round 4 */
    397 # if MD5_SIZE_VS_SPEED == 1
     401# if MD5_SMALL == 1
    398402    for (i = 0; i < 4; i++) {
    399403        OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
     
    463467
    464468    /* The MD5 result is in little endian byte order */
    465 #if BB_BIG_ENDIAN
    466     ctx->hash[0] = SWAP_LE32(ctx->hash[0]);
    467     ctx->hash[1] = SWAP_LE32(ctx->hash[1]);
    468     ctx->hash[2] = SWAP_LE32(ctx->hash[2]);
    469     ctx->hash[3] = SWAP_LE32(ctx->hash[3]);
    470 #endif
     469    if (BB_BIG_ENDIAN) {
     470        ctx->hash[0] = SWAP_LE32(ctx->hash[0]);
     471        ctx->hash[1] = SWAP_LE32(ctx->hash[1]);
     472        ctx->hash[2] = SWAP_LE32(ctx->hash[2]);
     473        ctx->hash[3] = SWAP_LE32(ctx->hash[3]);
     474    }
     475
    471476    memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4);
    472477}
     
    835840        buffer = (const char *)buffer + remaining;
    836841        bufpos += remaining;
    837         /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */
     842        /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
    838843        bufpos -= 128;
    839844        if (bufpos != 0)
     
    897902    memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
    898903}
     904
     905
     906/*
     907 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
     908 * Michael Peeters and Gilles Van Assche. For more information, feedback or
     909 * questions, please refer to our website: http://keccak.noekeon.org/
     910 *
     911 * Implementation by Ronny Van Keer,
     912 * hereby denoted as "the implementer".
     913 *
     914 * To the extent possible under law, the implementer has waived all copyright
     915 * and related or neighboring rights to the source code in this file.
     916 * http://creativecommons.org/publicdomain/zero/1.0/
     917 *
     918 * Busybox modifications (C) Lauri Kasanen, under the GPLv2.
     919 */
     920
     921#if CONFIG_SHA3_SMALL < 0
     922# define SHA3_SMALL 0
     923#elif CONFIG_SHA3_SMALL > 1
     924# define SHA3_SMALL 1
     925#else
     926# define SHA3_SMALL CONFIG_SHA3_SMALL
     927#endif
     928
     929enum {
     930    SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */
     931};
     932
     933/*
     934 * In the crypto literature this function is usually called Keccak-f().
     935 */
     936static void sha3_process_block72(uint64_t *state)
     937{
     938    enum { NROUNDS = 24 };
     939
     940    /* Elements should be 64-bit, but top half is always zero or 0x80000000.
     941     * We encode 63rd bits in a separate word below.
     942     * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit.
     943     * The speed penalty is lost in the noise.
     944     */
     945    static const uint16_t IOTA_CONST[NROUNDS] = {
     946        0x0001,
     947        0x8082,
     948        0x808a,
     949        0x8000,
     950        0x808b,
     951        0x0001,
     952        0x8081,
     953        0x8009,
     954        0x008a,
     955        0x0088,
     956        0x8009,
     957        0x000a,
     958        0x808b,
     959        0x008b,
     960        0x8089,
     961        0x8003,
     962        0x8002,
     963        0x0080,
     964        0x800a,
     965        0x000a,
     966        0x8081,
     967        0x8080,
     968        0x0001,
     969        0x8008,
     970    };
     971    /* bit for CONST[0] is in msb: 0011 0011 0000 0111 1101 1101 */
     972    const uint32_t IOTA_CONST_bit63 = (uint32_t)(0x3307dd00);
     973    /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */
     974    const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00);
     975
     976    static const uint8_t ROT_CONST[24] = {
     977        1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
     978        27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44,
     979    };
     980    static const uint8_t PI_LANE[24] = {
     981        10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
     982        15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
     983    };
     984    /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/
     985
     986    unsigned x, y;
     987    unsigned round;
     988
     989    if (BB_BIG_ENDIAN) {
     990        for (x = 0; x < 25; x++) {
     991            state[x] = SWAP_LE64(state[x]);
     992        }
     993    }
     994
     995    for (round = 0; round < NROUNDS; ++round) {
     996        /* Theta */
     997        {
     998            uint64_t BC[10];
     999            for (x = 0; x < 5; ++x) {
     1000                BC[x + 5] = BC[x] = state[x]
     1001                    ^ state[x + 5] ^ state[x + 10]
     1002                    ^ state[x + 15] ^ state[x + 20];
     1003            }
     1004            /* Using 2x5 vector above eliminates the need to use
     1005             * BC[MOD5[x+N]] trick below to fetch BC[(x+N) % 5],
     1006             * and the code is a bit _smaller_.
     1007             */
     1008            for (x = 0; x < 5; ++x) {
     1009                uint64_t temp = BC[x + 4] ^ rotl64(BC[x + 1], 1);
     1010                state[x] ^= temp;
     1011                state[x + 5] ^= temp;
     1012                state[x + 10] ^= temp;
     1013                state[x + 15] ^= temp;
     1014                state[x + 20] ^= temp;
     1015            }
     1016        }
     1017
     1018        /* Rho Pi */
     1019        if (SHA3_SMALL) {
     1020            uint64_t t1 = state[1];
     1021            for (x = 0; x < 24; ++x) {
     1022                uint64_t t0 = state[PI_LANE[x]];
     1023                state[PI_LANE[x]] = rotl64(t1, ROT_CONST[x]);
     1024                t1 = t0;
     1025            }
     1026        } else {
     1027            /* Especially large benefit for 32-bit arch (75% faster):
     1028             * 64-bit rotations by non-constant usually are SLOW on those.
     1029             * We resort to unrolling here.
     1030             * This optimizes out PI_LANE[] and ROT_CONST[],
     1031             * but generates 300-500 more bytes of code.
     1032             */
     1033            uint64_t t0;
     1034            uint64_t t1 = state[1];
     1035#define RhoPi_twice(x) \
     1036    t0 = state[PI_LANE[x  ]]; \
     1037    state[PI_LANE[x  ]] = rotl64(t1, ROT_CONST[x  ]); \
     1038    t1 = state[PI_LANE[x+1]]; \
     1039    state[PI_LANE[x+1]] = rotl64(t0, ROT_CONST[x+1]);
     1040            RhoPi_twice(0); RhoPi_twice(2);
     1041            RhoPi_twice(4); RhoPi_twice(6);
     1042            RhoPi_twice(8); RhoPi_twice(10);
     1043            RhoPi_twice(12); RhoPi_twice(14);
     1044            RhoPi_twice(16); RhoPi_twice(18);
     1045            RhoPi_twice(20); RhoPi_twice(22);
     1046#undef RhoPi_twice
     1047        }
     1048
     1049        /* Chi */
     1050        for (y = 0; y <= 20; y += 5) {
     1051            uint64_t BC0, BC1, BC2, BC3, BC4;
     1052            BC0 = state[y + 0];
     1053            BC1 = state[y + 1];
     1054            BC2 = state[y + 2];
     1055            state[y + 0] = BC0 ^ ((~BC1) & BC2);
     1056            BC3 = state[y + 3];
     1057            state[y + 1] = BC1 ^ ((~BC2) & BC3);
     1058            BC4 = state[y + 4];
     1059            state[y + 2] = BC2 ^ ((~BC3) & BC4);
     1060            state[y + 3] = BC3 ^ ((~BC4) & BC0);
     1061            state[y + 4] = BC4 ^ ((~BC0) & BC1);
     1062        }
     1063
     1064        /* Iota */
     1065        state[0] ^= IOTA_CONST[round]
     1066            | (uint32_t)((IOTA_CONST_bit31 << round) & 0x80000000)
     1067            | (uint64_t)((IOTA_CONST_bit63 << round) & 0x80000000) << 32;
     1068    }
     1069
     1070    if (BB_BIG_ENDIAN) {
     1071        for (x = 0; x < 25; x++) {
     1072            state[x] = SWAP_LE64(state[x]);
     1073        }
     1074    }
     1075}
     1076
     1077void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
     1078{
     1079    memset(ctx, 0, sizeof(*ctx));
     1080}
     1081
     1082void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
     1083{
     1084#if SHA3_SMALL
     1085    const uint8_t *data = buffer;
     1086    unsigned bufpos = ctx->bytes_queued;
     1087
     1088    while (1) {
     1089        unsigned remaining = SHA3_IBLK_BYTES - bufpos;
     1090        if (remaining > len)
     1091            remaining = len;
     1092        len -= remaining;
     1093        /* XOR data into buffer */
     1094        while (remaining != 0) {
     1095            uint8_t *buf = (uint8_t*)ctx->state;
     1096            buf[bufpos] ^= *data++;
     1097            bufpos++;
     1098            remaining--;
     1099        }
     1100        /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
     1101        bufpos -= SHA3_IBLK_BYTES;
     1102        if (bufpos != 0)
     1103            break;
     1104        /* Buffer is filled up, process it */
     1105        sha3_process_block72(ctx->state);
     1106        /*bufpos = 0; - already is */
     1107    }
     1108    ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES;
     1109#else
     1110    /* +50 bytes code size, but a bit faster because of long-sized XORs */
     1111    const uint8_t *data = buffer;
     1112    unsigned bufpos = ctx->bytes_queued;
     1113
     1114    /* If already data in queue, continue queuing first */
     1115    while (len != 0 && bufpos != 0) {
     1116        uint8_t *buf = (uint8_t*)ctx->state;
     1117        buf[bufpos] ^= *data++;
     1118        len--;
     1119        bufpos++;
     1120        if (bufpos == SHA3_IBLK_BYTES) {
     1121            bufpos = 0;
     1122            goto do_block;
     1123        }
     1124    }
     1125
     1126    /* Absorb complete blocks */
     1127    while (len >= SHA3_IBLK_BYTES) {
     1128        /* XOR data onto beginning of state[].
     1129         * We try to be efficient - operate one word at a time, not byte.
     1130         * Careful wrt unaligned access: can't just use "*(long*)data"!
     1131         */
     1132        unsigned count = SHA3_IBLK_BYTES / sizeof(long);
     1133        long *buf = (long*)ctx->state;
     1134        do {
     1135            long v;
     1136            move_from_unaligned_long(v, (long*)data);
     1137            *buf++ ^= v;
     1138            data += sizeof(long);
     1139        } while (--count);
     1140        len -= SHA3_IBLK_BYTES;
     1141 do_block:
     1142        sha3_process_block72(ctx->state);
     1143    }
     1144
     1145    /* Queue remaining data bytes */
     1146    while (len != 0) {
     1147        uint8_t *buf = (uint8_t*)ctx->state;
     1148        buf[bufpos] ^= *data++;
     1149        bufpos++;
     1150        len--;
     1151    }
     1152
     1153    ctx->bytes_queued = bufpos;
     1154#endif
     1155}
     1156
     1157void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
     1158{
     1159    /* Padding */
     1160    uint8_t *buf = (uint8_t*)ctx->state;
     1161    buf[ctx->bytes_queued]   ^= 1;
     1162    buf[SHA3_IBLK_BYTES - 1] ^= 0x80;
     1163
     1164    sha3_process_block72(ctx->state);
     1165
     1166    /* Output */
     1167    memcpy(resbuf, ctx->state, 64);
     1168}
  • branches/3.2/mindi-busybox/libbb/hash_md5prime.c

    r2725 r3232  
    6060 *
    6161 * Reintroduced the loop unrolling in md5_transform and added the
    62  * MD5_SIZE_VS_SPEED option for configurability.  Define below as:
     62 * MD5_SMALL option for configurability.  Define below as:
    6363 *       0    fully unrolled loops
    6464 *       1    partially unrolled (4 ops per loop)
     
    7676
    7777/* 1: fastest, 3: smallest */
    78 #if CONFIG_MD5_SIZE_VS_SPEED < 1
    79 # define MD5_SIZE_VS_SPEED 1
    80 #elif CONFIG_MD5_SIZE_VS_SPEED > 3
    81 # define MD5_SIZE_VS_SPEED 3
     78#if CONFIG_MD5_SMALL < 1
     79# define MD5_SMALL 1
     80#elif CONFIG_MD5_SMALL > 3
     81# define MD5_SMALL 3
    8282#else
    83 # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED
     83# define MD5_SMALL CONFIG_MD5_SMALL
    8484#endif
    8585
     
    153153{
    154154    uint32_t a, b, c, d, x[16];
    155 #if MD5_SIZE_VS_SPEED > 1
     155#if MD5_SMALL > 1
    156156    uint32_t temp;
    157157    const unsigned char *ps;
     
    163163        6, 10, 15, 21
    164164    };
    165 #endif /* MD5_SIZE_VS_SPEED > 1 */
    166 
    167 #if MD5_SIZE_VS_SPEED > 0
     165#endif /* MD5_SMALL > 1 */
     166
     167#if MD5_SMALL > 0
    168168    const uint32_t *pc;
    169169    const unsigned char *pp;
     
    199199    };
    200200
    201 #endif /* MD5_SIZE_VS_SPEED > 0 */
     201#endif /* MD5_SMALL > 0 */
    202202
    203203    memcpy32_le2cpu(x, block, 64);
     
    208208    d = state[3];
    209209
    210 #if MD5_SIZE_VS_SPEED > 2
     210#if MD5_SMALL > 2
    211211    pc = C;
    212212    pp = P;
     
    234234        a = d; d = c; c = b; b = temp;
    235235    }
    236 #elif MD5_SIZE_VS_SPEED > 1
     236#elif MD5_SMALL > 1
    237237    pc = C;
    238238    pp = P;
     
    261261        temp = d; d = c; c = b; b = a; a = temp;
    262262    }
    263 #elif MD5_SIZE_VS_SPEED > 0
     263#elif MD5_SMALL > 0
    264264    pc = C;
    265265    pp = P;
  • branches/3.2/mindi-busybox/libbb/inet_common.c

    r2725 r3232  
    9898#ifdef DEBUG
    9999        bb_error_msg("rresolve: unsupported address family %d!",
    100                   s_in->sin_family);
     100                s_in->sin_family);
    101101#endif
    102102        errno = EAFNOSUPPORT;
     
    165165int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6)
    166166{
    167     struct addrinfo req, *ai;
     167    struct addrinfo req, *ai = NULL;
    168168    int s;
    169169
    170     memset(&req, '\0', sizeof req);
     170    memset(&req, 0, sizeof(req));
    171171    req.ai_family = AF_INET6;
    172172    s = getaddrinfo(name, NULL, &req, &ai);
    173     if (s) {
     173    if (s != 0) {
    174174        bb_error_msg("getaddrinfo: %s: %d", name, s);
    175175        return -1;
    176176    }
    177     memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
    178     freeaddrinfo(ai);
     177    memcpy(sin6, ai->ai_addr, sizeof(*sin6));
     178    if (ai)
     179        freeaddrinfo(ai);
    179180    return 0;
    180181}
     
    195196#ifdef DEBUG
    196197        bb_error_msg("rresolve: unsupported address family %d!",
    197                   sin6->sin6_family);
     198                sin6->sin6_family);
    198199#endif
    199200        errno = EAFNOSUPPORT;
     
    210211    }
    211212
    212     s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
    213                 name, sizeof(name), NULL, 0, 0);
    214     if (s) {
     213    s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6),
     214                name, sizeof(name),
     215                /*serv,servlen:*/ NULL, 0,
     216                0);
     217    if (s != 0) {
    215218        bb_error_msg("getnameinfo failed");
    216219        return NULL;
  • branches/3.2/mindi-busybox/libbb/isdirectory.c

    r2725 r3232  
    1616 * Nonexistent files return FALSE.
    1717 */
    18 int FAST_FUNC is_directory(const char *fileName, int followLinks, struct stat *statBuf)
     18int FAST_FUNC is_directory(const char *fileName, int followLinks)
    1919{
    2020    int status;
    21     struct stat astatBuf;
    22 
    23     if (statBuf == NULL) {
    24         /* use auto stack buffer */
    25         statBuf = &astatBuf;
    26     }
     21    struct stat statBuf;
    2722
    2823    if (followLinks)
    29         status = stat(fileName, statBuf);
     24        status = stat(fileName, &statBuf);
    3025    else
    31         status = lstat(fileName, statBuf);
     26        status = lstat(fileName, &statBuf);
    3227
    33     status = (status == 0 && S_ISDIR(statBuf->st_mode));
     28    status = (status == 0 && S_ISDIR(statBuf.st_mode));
    3429
    3530    return status;
  • branches/3.2/mindi-busybox/libbb/kernel_version.c

    r2725 r3232  
    2121{
    2222    struct utsname name;
    23     char *s;
     23    char *s, *t;
    2424    int i, r;
    2525
    26     if (uname(&name) == -1) {
    27         bb_perror_msg("can't get system information");
    28         return 0;
    29     }
    30 
     26    uname(&name); /* never fails */
    3127    s = name.release;
    3228    r = 0;
    3329    for (i = 0; i < 3; i++) {
    34         r = r * 256 + atoi(strtok(s, "."));
     30        t = strtok(s, ".");
     31        r = r * 256 + (t ? atoi(t) : 0);
    3532        s = NULL;
    3633    }
  • branches/3.2/mindi-busybox/libbb/lineedit.c

    r2725 r3232  
    4242#include "libbb.h"
    4343#include "unicode.h"
     44#ifndef _POSIX_VDISABLE
     45# define _POSIX_VDISABLE '\0'
     46#endif
     47
    4448
    4549#ifdef TEST
     
    185189    IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \
    186190} while (0)
     191
    187192static void deinit_S(void)
    188193{
     
    203208
    204209#if ENABLE_UNICODE_SUPPORT
    205 static size_t load_string(const char *src, int maxsize)
    206 {
    207     ssize_t len = mbstowcs(command_ps, src, maxsize - 1);
    208     if (len < 0)
    209         len = 0;
    210     command_ps[len] = BB_NUL;
    211     return len;
     210static size_t load_string(const char *src)
     211{
     212    if (unicode_status == UNICODE_ON) {
     213        ssize_t len = mbstowcs(command_ps, src, S.maxsize - 1);
     214        if (len < 0)
     215            len = 0;
     216        command_ps[len] = BB_NUL;
     217        return len;
     218    } else {
     219        unsigned i = 0;
     220        while (src[i] && i < S.maxsize - 1) {
     221            command_ps[i] = src[i];
     222            i++;
     223        }
     224        command_ps[i] = BB_NUL;
     225        return i;
     226    }
    212227}
    213228static unsigned save_string(char *dst, unsigned maxsize)
    214229{
     230    if (unicode_status == UNICODE_ON) {
    215231# if !ENABLE_UNICODE_PRESERVE_BROKEN
    216     ssize_t len = wcstombs(dst, command_ps, maxsize - 1);
    217     if (len < 0)
    218         len = 0;
    219     dst[len] = '\0';
    220     return len;
     232        ssize_t len = wcstombs(dst, command_ps, maxsize - 1);
     233        if (len < 0)
     234            len = 0;
     235        dst[len] = '\0';
     236        return len;
    221237# else
    222     unsigned dstpos = 0;
    223     unsigned srcpos = 0;
    224 
    225     maxsize--;
    226     while (dstpos < maxsize) {
    227         wchar_t wc;
    228         int n = srcpos;
    229 
    230         /* Convert up to 1st invalid byte (or up to end) */
    231         while ((wc = command_ps[srcpos]) != BB_NUL
    232             && !unicode_is_raw_byte(wc)
    233         ) {
     238        unsigned dstpos = 0;
     239        unsigned srcpos = 0;
     240
     241        maxsize--;
     242        while (dstpos < maxsize) {
     243            wchar_t wc;
     244            int n = srcpos;
     245
     246            /* Convert up to 1st invalid byte (or up to end) */
     247            while ((wc = command_ps[srcpos]) != BB_NUL
     248                && !unicode_is_raw_byte(wc)
     249            ) {
     250                srcpos++;
     251            }
     252            command_ps[srcpos] = BB_NUL;
     253            n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos);
     254            if (n < 0) /* should not happen */
     255                break;
     256            dstpos += n;
     257            if (wc == BB_NUL) /* usually is */
     258                break;
     259
     260            /* We do have invalid byte here! */
     261            command_ps[srcpos] = wc; /* restore it */
    234262            srcpos++;
    235         }
    236         command_ps[srcpos] = BB_NUL;
    237         n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos);
    238         if (n < 0) /* should not happen */
    239             break;
    240         dstpos += n;
    241         if (wc == BB_NUL) /* usually is */
    242             break;
    243 
    244         /* We do have invalid byte here! */
    245         command_ps[srcpos] = wc; /* restore it */
    246         srcpos++;
    247         if (dstpos == maxsize)
    248             break;
    249         dst[dstpos++] = (char) wc;
    250     }
    251     dst[dstpos] = '\0';
    252     return dstpos;
     263            if (dstpos == maxsize)
     264                break;
     265            dst[dstpos++] = (char) wc;
     266        }
     267        dst[dstpos] = '\0';
     268        return dstpos;
    253269# endif
     270    } else {
     271        unsigned i = 0;
     272        while ((dst[i] = command_ps[i]) != 0)
     273            i++;
     274        return i;
     275    }
    254276}
    255277/* I thought just fputwc(c, stdout) would work. But no... */
    256278static void BB_PUTCHAR(wchar_t c)
    257279{
    258     char buf[MB_CUR_MAX + 1];
    259     mbstate_t mbst = { 0 };
    260     ssize_t len;
    261 
    262     len = wcrtomb(buf, c, &mbst);
    263     if (len > 0) {
    264         buf[len] = '\0';
    265         fputs(buf, stdout);
     280    if (unicode_status == UNICODE_ON) {
     281        char buf[MB_CUR_MAX + 1];
     282        mbstate_t mbst = { 0 };
     283        ssize_t len = wcrtomb(buf, c, &mbst);
     284        if (len > 0) {
     285            buf[len] = '\0';
     286            fputs(buf, stdout);
     287        }
     288    } else {
     289        /* In this case, c is always one byte */
     290        putchar(c);
    266291    }
    267292}
     
    298323}
    299324#else /* !UNICODE */
    300 static size_t load_string(const char *src, int maxsize)
    301 {
    302     safe_strncpy(command_ps, src, maxsize);
     325static size_t load_string(const char *src)
     326{
     327    safe_strncpy(command_ps, src, S.maxsize);
    303328    return strlen(command_ps);
    304329}
     
    12031228            /* where do we want to have cursor after all? */
    12041229            strcpy(&command[cursor_mb], chosen_match + match_pfx_len);
    1205             len = load_string(command, S.maxsize);
     1230            len = load_string(command);
    12061231            /* add match and tail */
    12071232            sprintf(&command[cursor_mb], "%s%s", chosen_match + match_pfx_len, match_buf);
    1208             command_len = load_string(command, S.maxsize);
     1233            command_len = load_string(command);
    12091234            /* write out the matched command */
    12101235            /* paranoia: load_string can return 0 on conv error,
     
    12271252    line_input_t *n = xzalloc(sizeof(*n));
    12281253    n->flags = flags;
     1254    n->max_history = MAX_HISTORY;
    12291255    return n;
    12301256}
     
    12321258
    12331259#if MAX_HISTORY > 0
     1260
     1261unsigned size_from_HISTFILESIZE(const char *hp)
     1262{
     1263    int size = MAX_HISTORY;
     1264    if (hp) {
     1265        size = atoi(hp);
     1266        if (size <= 0)
     1267            return 1;
     1268        if (size > MAX_HISTORY)
     1269            return MAX_HISTORY;
     1270    }
     1271    return size;
     1272}
    12341273
    12351274static void save_command_ps_at_cur_history(void)
     
    13131352        /* fill temp_h[], retaining only last MAX_HISTORY lines */
    13141353        memset(temp_h, 0, sizeof(temp_h));
    1315         st_parm->cnt_history_in_file = idx = 0;
     1354        idx = 0;
     1355        st_parm->cnt_history_in_file = 0;
    13161356        while ((line = xmalloc_fgetline(fp)) != NULL) {
    13171357            if (line[0] == '\0') {
     
    13231363            st_parm->cnt_history_in_file++;
    13241364            idx++;
    1325             if (idx == MAX_HISTORY)
     1365            if (idx == st_parm->max_history)
    13261366                idx = 0;
    13271367        }
     
    13321372            while (temp_h[idx] == NULL) {
    13331373                idx++;
    1334                 if (idx == MAX_HISTORY)
     1374                if (idx == st_parm->max_history)
    13351375                    idx = 0;
    13361376            }
     
    13381378
    13391379        /* copy temp_h[] to st_parm->history[] */
    1340         for (i = 0; i < MAX_HISTORY;) {
     1380        for (i = 0; i < st_parm->max_history;) {
    13411381            line = temp_h[idx];
    13421382            if (!line)
    13431383                break;
    13441384            idx++;
    1345             if (idx == MAX_HISTORY)
     1385            if (idx == st_parm->max_history)
    13461386                idx = 0;
    13471387            line_len = strlen(line);
     
    13511391        }
    13521392        st_parm->cnt_history = i;
    1353     }
    1354 }
    1355 
    1356 /* state->flags is already checked to be nonzero */
     1393        if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
     1394            st_parm->cnt_history_in_file = i;
     1395    }
     1396}
     1397
     1398#  if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
     1399void save_history(line_input_t *st)
     1400{
     1401    FILE *fp;
     1402
     1403    if (!st->hist_file)
     1404        return;
     1405    if (st->cnt_history <= st->cnt_history_in_file)
     1406        return;
     1407
     1408    fp = fopen(st->hist_file, "a");
     1409    if (fp) {
     1410        int i, fd;
     1411        char *new_name;
     1412        line_input_t *st_temp;
     1413
     1414        for (i = st->cnt_history_in_file; i < st->cnt_history; i++)
     1415            fprintf(fp, "%s\n", st->history[i]);
     1416        fclose(fp);
     1417
     1418        /* we may have concurrently written entries from others.
     1419         * load them */
     1420        st_temp = new_line_input_t(st->flags);
     1421        st_temp->hist_file = st->hist_file;
     1422        st_temp->max_history = st->max_history;
     1423        load_history(st_temp);
     1424
     1425        /* write out temp file and replace hist_file atomically */
     1426        new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid());
     1427        fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
     1428        if (fd >= 0) {
     1429            fp = xfdopen_for_write(fd);
     1430            for (i = 0; i < st_temp->cnt_history; i++)
     1431                fprintf(fp, "%s\n", st_temp->history[i]);
     1432            fclose(fp);
     1433            if (rename(new_name, st->hist_file) == 0)
     1434                st->cnt_history_in_file = st_temp->cnt_history;
     1435        }
     1436        free(new_name);
     1437        free_line_input_t(st_temp);
     1438    }
     1439}
     1440#  else
    13571441static void save_history(char *str)
    13581442{
    13591443    int fd;
    13601444    int len, len2;
     1445
     1446    if (!state->hist_file)
     1447        return;
    13611448
    13621449    fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
     
    13741461    /* did we write so much that history file needs trimming? */
    13751462    state->cnt_history_in_file++;
    1376     if (state->cnt_history_in_file > MAX_HISTORY * 4) {
     1463    if (state->cnt_history_in_file > state->max_history * 4) {
    13771464        char *new_name;
    13781465        line_input_t *st_temp;
     
    13821469        st_temp = new_line_input_t(state->flags);
    13831470        st_temp->hist_file = state->hist_file;
     1471        st_temp->max_history = state->max_history;
    13841472        load_history(st_temp);
    13851473
    13861474        /* write out temp file and replace hist_file atomically */
    13871475        new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid());
    1388         fd = open(state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
     1476        fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
    13891477        if (fd >= 0) {
    13901478            FILE *fp;
     
    14021490    }
    14031491}
     1492#  endif
    14041493# else
    14051494#  define load_history(a) ((void)0)
     
    14201509        return;
    14211510
    1422     free(state->history[MAX_HISTORY]); /* redundant, paranoia */
    1423     state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */
     1511    free(state->history[state->max_history]); /* redundant, paranoia */
     1512    state->history[state->max_history] = NULL; /* redundant, paranoia */
    14241513
    14251514    /* If history[] is full, remove the oldest command */
    1426     /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */
    1427     if (i >= MAX_HISTORY) {
     1515    /* we need to keep history[state->max_history] empty, hence >=, not > */
     1516    if (i >= state->max_history) {
    14281517        free(state->history[0]);
    1429         for (i = 0; i < MAX_HISTORY-1; i++)
     1518        for (i = 0; i < state->max_history-1; i++)
    14301519            state->history[i] = state->history[i+1];
    1431         /* i == MAX_HISTORY-1 */
    1432     }
    1433     /* i <= MAX_HISTORY-1 */
     1520        /* i == state->max_history-1 */
     1521# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
     1522        if (state->cnt_history_in_file)
     1523            state->cnt_history_in_file--;
     1524# endif
     1525    }
     1526    /* i <= state->max_history-1 */
    14341527    state->history[i++] = xstrdup(str);
    1435     /* i <= MAX_HISTORY */
     1528    /* i <= state->max_history */
    14361529    state->cur_history = i;
    14371530    state->cnt_history = i;
    1438 # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
    1439     if ((state->flags & SAVE_HISTORY) && state->hist_file)
    1440         save_history(str);
     1531# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
     1532    save_history(str);
    14411533# endif
    14421534    IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
     
    16451737     * poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)  <-- no input exists
    16461738     * write(1, "\33[6n", 4) = 4  <-- send the ESC sequence, quick!
    1647      * poll([{fd=0, events=POLLIN}], 1, 4294967295) = 1 ([{fd=0, revents=POLLIN}])
     1739     * poll([{fd=0, events=POLLIN}], 1, -1) = 1 ([{fd=0, revents=POLLIN}])
    16481740     * read(0, "\n", 1)      = 1  <-- oh crap, user's input got in first
    16491741     */
     
    18031895    int sv_errno = errno;
    18041896    unsigned width;
     1897
    18051898    get_terminal_width_height(0, &width, NULL);
    1806     cmdedit_setwidth(width, nsig /* - just a yes/no flag */);
    1807     if (nsig == SIGWINCH)
    1808         signal(SIGWINCH, win_changed); /* rearm ourself */
     1899//FIXME: cmdedit_setwidth() -> redraw() -> printf() -> KABOOM! (we are in signal handler!)
     1900    cmdedit_setwidth(width, /*redraw_flg:*/ nsig);
     1901
    18091902    errno = sv_errno;
    18101903}
    18111904
    1812 static int lineedit_read_key(char *read_key_buffer)
     1905static int lineedit_read_key(char *read_key_buffer, int timeout)
    18131906{
    18141907    int64_t ic;
    1815     int timeout = -1;
    18161908#if ENABLE_UNICODE_SUPPORT
    18171909    char unicode_buf[MB_CUR_MAX + 1];
     
    19122004#define CTRL(a) ((a) & ~0x40)
    19132005
     2006enum {
     2007    VI_CMDMODE_BIT = 0x40000000,
     2008    /* 0x80000000 bit flags KEYCODE_xxx */
     2009};
     2010
     2011#if ENABLE_FEATURE_REVERSE_SEARCH
     2012/* Mimic readline Ctrl-R reverse history search.
     2013 * When invoked, it shows the following prompt:
     2014 * (reverse-i-search)'': user_input [cursor pos unchanged by Ctrl-R]
     2015 * and typing results in search being performed:
     2016 * (reverse-i-search)'tmp': cd /tmp [cursor under t in /tmp]
     2017 * Search is performed by looking at progressively older lines in history.
     2018 * Ctrl-R again searches for the next match in history.
     2019 * Backspace deletes last matched char.
     2020 * Control keys exit search and return to normal editing (at current history line).
     2021 */
     2022static int32_t reverse_i_search(void)
     2023{
     2024    char match_buf[128]; /* for user input */
     2025    char read_key_buffer[KEYCODE_BUFFER_SIZE];
     2026    const char *matched_history_line;
     2027    const char *saved_prompt;
     2028    int32_t ic;
     2029
     2030    matched_history_line = NULL;
     2031    read_key_buffer[0] = 0;
     2032    match_buf[0] = '\0';
     2033
     2034    /* Save and replace the prompt */
     2035    saved_prompt = cmdedit_prompt;
     2036    goto set_prompt;
     2037
     2038    while (1) {
     2039        int h;
     2040        unsigned match_buf_len = strlen(match_buf);
     2041
     2042        fflush_all();
     2043//FIXME: correct timeout?
     2044        ic = lineedit_read_key(read_key_buffer, -1);
     2045
     2046        switch (ic) {
     2047        case CTRL('R'): /* searching for the next match */
     2048            break;
     2049
     2050        case '\b':
     2051        case '\x7f':
     2052            /* Backspace */
     2053            if (unicode_status == UNICODE_ON) {
     2054                while (match_buf_len != 0) {
     2055                    uint8_t c = match_buf[--match_buf_len];
     2056                    if ((c & 0xc0) != 0x80) /* start of UTF-8 char? */
     2057                        break; /* yes */
     2058                }
     2059            } else {
     2060                if (match_buf_len != 0)
     2061                    match_buf_len--;
     2062            }
     2063            match_buf[match_buf_len] = '\0';
     2064            break;
     2065
     2066        default:
     2067            if (ic < ' '
     2068             || (!ENABLE_UNICODE_SUPPORT && ic >= 256)
     2069             || (ENABLE_UNICODE_SUPPORT && ic >= VI_CMDMODE_BIT)
     2070            ) {
     2071                goto ret;
     2072            }
     2073
     2074            /* Append this char */
     2075#if ENABLE_UNICODE_SUPPORT
     2076            if (unicode_status == UNICODE_ON) {
     2077                mbstate_t mbstate = { 0 };
     2078                char buf[MB_CUR_MAX + 1];
     2079                int len = wcrtomb(buf, ic, &mbstate);
     2080                if (len > 0) {
     2081                    buf[len] = '\0';
     2082                    if (match_buf_len + len < sizeof(match_buf))
     2083                        strcpy(match_buf + match_buf_len, buf);
     2084                }
     2085            } else
     2086#endif
     2087            if (match_buf_len < sizeof(match_buf) - 1) {
     2088                match_buf[match_buf_len] = ic;
     2089                match_buf[match_buf_len + 1] = '\0';
     2090            }
     2091            break;
     2092        } /* switch (ic) */
     2093
     2094        /* Search in history for match_buf */
     2095        h = state->cur_history;
     2096        if (ic == CTRL('R'))
     2097            h--;
     2098        while (h >= 0) {
     2099            if (state->history[h]) {
     2100                char *match = strstr(state->history[h], match_buf);
     2101                if (match) {
     2102                    state->cur_history = h;
     2103                    matched_history_line = state->history[h];
     2104                    command_len = load_string(matched_history_line);
     2105                    cursor = match - matched_history_line;
     2106//FIXME: cursor position for Unicode case
     2107
     2108                    free((char*)cmdedit_prompt);
     2109 set_prompt:
     2110                    cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf);
     2111                    cmdedit_prmt_len = strlen(cmdedit_prompt);
     2112                    goto do_redraw;
     2113                }
     2114            }
     2115            h--;
     2116        }
     2117
     2118        /* Not found */
     2119        match_buf[match_buf_len] = '\0';
     2120        beep();
     2121        continue;
     2122
     2123 do_redraw:
     2124        redraw(cmdedit_y, command_len - cursor);
     2125    } /* while (1) */
     2126
     2127 ret:
     2128    if (matched_history_line)
     2129        command_len = load_string(matched_history_line);
     2130
     2131    free((char*)cmdedit_prompt);
     2132    cmdedit_prompt = saved_prompt;
     2133    cmdedit_prmt_len = strlen(cmdedit_prompt);
     2134    redraw(cmdedit_y, command_len - cursor);
     2135
     2136    return ic;
     2137}
     2138#endif
     2139
    19142140/* maxsize must be >= 2.
    19152141 * Returns:
     
    19182144 * >0 length of input string, including terminating '\n'
    19192145 */
    1920 int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, line_input_t *st)
     2146int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout)
    19212147{
    19222148    int len;
     
    19552181    S.maxsize = maxsize;
    19562182
    1957     /* With null flags, no other fields are ever used */
     2183    /* With zero flags, no other fields are ever used */
    19582184    state = st ? st : (line_input_t*) &const_int_0;
    19592185#if MAX_HISTORY > 0
    19602186# if ENABLE_FEATURE_EDITING_SAVEHISTORY
    1961     if ((state->flags & SAVE_HISTORY) && state->hist_file)
     2187    if (state->hist_file)
    19622188        if (state->cnt_history == 0)
    19632189            load_history(state);
     
    19792205
    19802206    new_settings = initial_settings;
    1981     new_settings.c_lflag &= ~ICANON;        /* unbuffered input */
    1982     /* Turn off echoing and CTRL-C, so we can trap it */
    1983     new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG);
    1984     /* Hmm, in linux c_cc[] is not parsed if ICANON is off */
     2207    /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */
     2208    /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
     2209    /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
     2210    new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
     2211    /* reads would block only if < 1 char is available */
    19852212    new_settings.c_cc[VMIN] = 1;
     2213    /* no timeout (reads block forever) */
    19862214    new_settings.c_cc[VTIME] = 0;
    1987     /* Turn off CTRL-C, so we can trap it */
    1988 #ifndef _POSIX_VDISABLE
    1989 # define _POSIX_VDISABLE '\0'
    1990 #endif
    1991     new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
     2215    /* Should be not needed if ISIG is off: */
     2216    /* Turn off CTRL-C */
     2217    /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */
    19922218    tcsetattr_stdin_TCSANOW(&new_settings);
    19932219
    1994     /* Now initialize things */
    1995     previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
    1996     win_changed(0); /* do initial resizing */
    19972220#if ENABLE_USERNAME_OR_HOMEDIR
    19982221    {
     
    20082231
    20092232#if 0
    2010     for (i = 0; i <= MAX_HISTORY; i++)
     2233    for (i = 0; i <= state->max_history; i++)
    20112234        bb_error_msg("history[%d]:'%s'", i, state->history[i]);
    20122235    bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
     
    20162239    parse_and_put_prompt(prompt);
    20172240    ask_terminal();
     2241
     2242    /* Install window resize handler (NB: after *all* init is complete) */
     2243//FIXME: save entire sigaction!
     2244    previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
     2245    win_changed(0); /* get initial window size */
    20182246
    20192247    read_key_buffer[0] = 0;
     
    20272255         * in one place.
    20282256         */
    2029         enum {
    2030             VI_CMDMODE_BIT = 0x40000000,
    2031             /* 0x80000000 bit flags KEYCODE_xxx */
    2032         };
    20332257        int32_t ic, ic_raw;
    20342258
    20352259        fflush_all();
    2036         ic = ic_raw = lineedit_read_key(read_key_buffer);
    2037 
     2260        ic = ic_raw = lineedit_read_key(read_key_buffer, timeout);
     2261
     2262#if ENABLE_FEATURE_REVERSE_SEARCH
     2263 again:
     2264#endif
    20382265#if ENABLE_FEATURE_EDITING_VI
    20392266        newdelflag = 1;
     
    21392366                input_backspace();
    21402367            break;
     2368#if ENABLE_FEATURE_REVERSE_SEARCH
     2369        case CTRL('R'):
     2370            ic = ic_raw = reverse_i_search();
     2371            goto again;
     2372#endif
    21412373
    21422374#if ENABLE_FEATURE_EDITING_VI
     
    21952427            int nc, sc;
    21962428
    2197             ic = lineedit_read_key(read_key_buffer);
     2429            ic = lineedit_read_key(read_key_buffer, timeout);
    21982430            if (errno) /* error */
    21992431                goto return_error_indicator;
     
    22592491        case 'r'|VI_CMDMODE_BIT:
    22602492//FIXME: unicode case?
    2261             ic = lineedit_read_key(read_key_buffer);
     2493            ic = lineedit_read_key(read_key_buffer, timeout);
    22622494            if (errno) /* error */
    22632495                goto return_error_indicator;
     
    22762508                input_backward(1);
    22772509            }
     2510            /* Handle a few ESC-<key> combinations the same way
     2511             * standard readline bindings (IOW: bash) do.
     2512             * Often, Alt-<key> generates ESC-<key>.
     2513             */
     2514            ic = lineedit_read_key(read_key_buffer, timeout);
     2515            switch (ic) {
     2516                //case KEYCODE_LEFT: - bash doesn't do this
     2517                case 'b':
     2518                    ctrl_left();
     2519                    break;
     2520                //case KEYCODE_RIGHT: - bash doesn't do this
     2521                case 'f':
     2522                    ctrl_right();
     2523                    break;
     2524                //case KEYCODE_DELETE: - bash doesn't do this
     2525                case 'd':  /* Alt-D */
     2526                {
     2527                    /* Delete word forward */
     2528                    int nc, sc = cursor;
     2529                    ctrl_right();
     2530                    nc = cursor - sc;
     2531                    input_backward(nc);
     2532                    while (--nc >= 0)
     2533                        input_delete(1);
     2534                    break;
     2535                }
     2536                case '\b':   /* Alt-Backspace(?) */
     2537                case '\x7f': /* Alt-Backspace(?) */
     2538                //case 'w': - bash doesn't do this
     2539                {
     2540                    /* Delete word backward */
     2541                    int sc = cursor;
     2542                    ctrl_left();
     2543                    while (sc-- > cursor)
     2544                        input_delete(1);
     2545                    break;
     2546                }
     2547            }
    22782548            break;
    22792549#endif /* FEATURE_COMMAND_EDITING_VI */
     
    22922562            /* change command */
    22932563            command_len = load_string(state->history[state->cur_history] ?
    2294                     state->history[state->cur_history] : "", maxsize);
     2564                    state->history[state->cur_history] : "");
    22952565            /* redraw and go to eol (bol, in vi) */
    22962566            redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);
     
    23042574            break;
    23052575        case KEYCODE_CTRL_LEFT:
     2576        case KEYCODE_ALT_LEFT: /* bash doesn't do it */
    23062577            ctrl_left();
    23072578            break;
    23082579        case KEYCODE_CTRL_RIGHT:
     2580        case KEYCODE_ALT_RIGHT: /* bash doesn't do it */
    23092581            ctrl_right();
    23102582            break;
     
    24582730    fputs(prompt, stdout);
    24592731    fflush_all();
    2460     fgets(command, maxsize, stdin);
     2732    if (!fgets(command, maxsize, stdin))
     2733        return -1;
    24612734    return strlen(command);
    24622735}
  • branches/3.2/mindi-busybox/libbb/llist.c

    r2725 r3232  
    6363/* Recursively free all elements in the linked list.  If freeit != NULL
    6464 * call it on each datum in the list */
    65 void FAST_FUNC llist_free(llist_t *elm, void (*freeit) (void *data))
     65void FAST_FUNC llist_free(llist_t *elm, void (*freeit)(void *data))
    6666{
    6767    while (elm) {
  • branches/3.2/mindi-busybox/libbb/loop.c

    r2725 r3232  
    8585   file/offset if it finds one.
    8686 */
    87 int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset)
     87int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro)
    8888{
    8989    char dev[LOOP_NAMESIZE];
     
    9494
    9595    /* Open the file.  Barf if this doesn't work.  */
    96     mode = O_RDWR;
     96    mode = ro ? O_RDONLY : O_RDWR;
    9797    ffd = open(file, mode);
    9898    if (ffd < 0) {
    99         mode = O_RDONLY;
    100         ffd = open(file, mode);
     99        if (mode != O_RDONLY) {
     100            mode = O_RDONLY;
     101            ffd = open(file, mode);
     102        }
    101103        if (ffd < 0)
    102104            return -errno;
     
    149151
    150152        /* If this block device already set up right, re-use it.
    151            (Yes this is racy, but associating two loop devices with the same
    152            file isn't pretty either.  In general, mounting the same file twice
    153            without using losetup manually is problematic.)
     153         * (Yes this is racy, but associating two loop devices with the same
     154         * file isn't pretty either.  In general, mounting the same file twice
     155         * without using losetup manually is problematic.)
    154156         */
    155157        } else
  • branches/3.2/mindi-busybox/libbb/make_directory.c

    r2725 r3232  
    108108            if ((mode != -1) && (chmod(path, mode) < 0)) {
    109109                fail_msg = "set permissions of";
     110                if (flags & FILEUTILS_IGNORE_CHMOD_ERR) {
     111                    flags = 0;
     112                    goto print_err;
     113                }
    110114                break;
    111115            }
     
    117121    } /* while (1) */
    118122
     123    flags = -1;
     124 print_err:
    119125    bb_perror_msg("can't %s directory '%s'", fail_msg, path);
    120     flags = -1;
    121126    goto ret;
    122127 ret0:
  • branches/3.2/mindi-busybox/libbb/makedev.c

    r2725 r3232  
    99/* We do not include libbb.h - #define makedev() is there! */
    1010#include "platform.h"
    11 #include <features.h>
    12 #include <sys/sysmacros.h>
     11
     12/* Different Unixes want different headers for makedev */
     13#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
     14 || defined(__APPLE__)
     15# include <sys/types.h>
     16#else
     17# include <features.h>
     18# include <sys/sysmacros.h>
     19#endif
    1320
    1421#ifdef __GLIBC__
    15 /* At least glibc has horrendously large inline for this, so wrap it */
     22/* At least glibc has horrendously large inline for this, so wrap it. */
    1623/* uclibc people please check - do we need "&& !__UCLIBC__" above? */
    1724
    18 /* suppress gcc "no previous prototype" warning */
    19 unsigned long long FAST_FUNC bb_makedev(unsigned int major, unsigned int minor);
    20 unsigned long long FAST_FUNC bb_makedev(unsigned int major, unsigned int minor)
     25/* Suppress gcc "no previous prototype" warning */
     26unsigned long long FAST_FUNC bb_makedev(unsigned major, unsigned minor);
     27unsigned long long FAST_FUNC bb_makedev(unsigned major, unsigned minor)
    2128{
    2229    return makedev(major, minor);
  • branches/3.2/mindi-busybox/libbb/match_fstype.c

    r2725 r3232  
    1212
    1313#include "libbb.h"
     14
     15#ifdef HAVE_MNTENT_H
    1416
    1517int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype)
     
    4143    return !match;
    4244}
     45
     46#endif /* HAVE_MNTENT_H */
  • branches/3.2/mindi-busybox/libbb/messages.c

    r2725 r3232  
    2323
    2424
    25 const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted";
     25const char bb_msg_memory_exhausted[] ALIGN1 = "out of memory";
    2626const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'";
    2727const char bb_msg_unknown[] ALIGN1 = "(unknown)";
     
    4949const int const_int_0 = 0;
    5050
    51 #include <utmp.h>
     51#if ENABLE_FEATURE_WTMP
    5252/* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */
    5353const char bb_path_wtmp_file[] ALIGN1 =
    54 #if defined _PATH_WTMP
     54# if defined _PATH_WTMP
    5555    _PATH_WTMP;
    56 #elif defined WTMP_FILE
     56# elif defined WTMP_FILE
    5757    WTMP_FILE;
    58 #else
    59 #error unknown path to wtmp file
     58# else
     59#  error unknown path to wtmp file
     60# endif
    6061#endif
    6162
  • branches/3.2/mindi-busybox/libbb/obscure.c

    r2725 r3232  
    110110        return "similar to username";
    111111    }
     112#ifndef __BIONIC__
    112113    /* no gecos as-is, as sub-string, reversed, capitalized, doubled */
    113114    if (pw->pw_gecos[0] && string_checker(new_p, pw->pw_gecos)) {
    114115        return "similar to gecos";
    115116    }
     117#endif
    116118    /* hostname as-is, as sub-string, reversed, capitalized, doubled */
    117119    hostname = safe_gethostname();
  • branches/3.2/mindi-busybox/libbb/parse_config.c

    r2725 r3232  
    99 */
    1010
     11/* Uncomment to enable test applet */
     12////config:config PARSE
     13////config: bool "Uniform config file parser debugging applet: parse"
     14////config: default n
     15////config: help
     16////config:   Typical usage of parse API:
     17////config:     char *t[3];
     18////config:     parser_t *p = config_open(filename);
     19////config:     while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens
     20////config:         bb_error_msg("TOKENS: '%s''%s''%s'", t[0], t[1], t[2]);
     21////config:     }
     22////config:     config_close(p);
     23
     24////applet:IF_PARSE(APPLET(parse, BB_DIR_USR_BIN, BB_SUID_DROP))
     25
     26//kbuild:lib-y += parse_config.o
     27
     28//usage:#define parse_trivial_usage
     29//usage:       "[-x] [-n MAXTOKENS] [-m MINTOKENS] [-d DELIMS] [-f FLAGS] FILE..."
     30//usage:#define parse_full_usage "\n\n"
     31//usage:       "    -x  Suppress output (for benchmarking)"
     32
    1133#include "libbb.h"
    1234
     
    1638{
    1739    const char *delims = "# \t";
     40    char **t;
    1841    unsigned flags = PARSE_NORMAL;
    1942    int mintokens = 0, ntokens = 128;
     43    unsigned noout;
    2044
    2145    opt_complementary = "-1:n+:m+:f+";
    22     getopt32(argv, "n:m:d:f:", &ntokens, &mintokens, &delims, &flags);
     46    noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags);
    2347    //argc -= optind;
    2448    argv += optind;
     49
     50    t = xmalloc(sizeof(t[0]) * ntokens);
    2551    while (*argv) {
     52        int n;
    2653        parser_t *p = config_open(*argv);
    27         if (p) {
    28             int n;
    29             char **t = xmalloc(sizeof(char *) * ntokens);
    30             while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
     54        while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
     55            if (!noout) {
    3156                for (int i = 0; i < n; ++i)
    3257                    printf("[%s]", t[i]);
    3358                puts("");
    3459            }
    35             config_close(p);
    36         }
     60        }
     61        config_close(p);
    3762        argv++;
    3863    }
     
    4065}
    4166#endif
    42 
    43 /*
    44 
    45 Typical usage:
    46 
    47 ----- CUT -----
    48     char *t[3];  // tokens placeholder
    49     parser_t *p = config_open(filename);
    50     if (p) {
    51         // parse line-by-line
    52         while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens
    53             // use tokens
    54             bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);
    55         }
    56         ...
    57         // free parser
    58         config_close(p);
    59     }
    60 ----- CUT -----
    61 
    62 */
    6367
    6468parser_t* FAST_FUNC config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path))
     
    8084}
    8185
    82 static void config_free_data(parser_t *parser)
    83 {
    84     free(parser->line);
    85     parser->line = NULL;
    86     if (PARSE_KEEP_COPY) { /* compile-time constant */
    87         free(parser->data);
    88         parser->data = NULL;
    89     }
    90 }
    91 
    9286void FAST_FUNC config_close(parser_t *parser)
    9387{
    9488    if (parser) {
    95         config_free_data(parser);
     89        if (PARSE_KEEP_COPY) /* compile-time constant */
     90            free(parser->data);
    9691        fclose(parser->fp);
     92        free(parser->line);
     93        free(parser->nline);
    9794        free(parser);
    9895    }
    9996}
     97
     98/* This function reads an entire line from a text file,
     99 * up to a newline, exclusive.
     100 * Trailing '\' is recognized as line continuation.
     101 * Returns -1 if EOF/error.
     102 */
     103static int get_line_with_continuation(parser_t *parser)
     104{
     105    ssize_t len, nlen;
     106    char *line;
     107
     108    len = getline(&parser->line, &parser->line_alloc, parser->fp);
     109    if (len <= 0)
     110        return len;
     111
     112    line = parser->line;
     113    for (;;) {
     114        parser->lineno++;
     115        if (line[len - 1] == '\n')
     116            len--;
     117        if (len == 0 || line[len - 1] != '\\')
     118            break;
     119        len--;
     120
     121        nlen = getline(&parser->nline, &parser->nline_alloc, parser->fp);
     122        if (nlen <= 0)
     123            break;
     124
     125        if (parser->line_alloc < len + nlen + 1) {
     126            parser->line_alloc = len + nlen + 1;
     127            line = parser->line = xrealloc(line, parser->line_alloc);
     128        }
     129        memcpy(&line[len], parser->nline, nlen);
     130        len += nlen;
     131    }
     132
     133    line[len] = '\0';
     134    return len;
     135}
     136
    100137
    101138/*
     
    127164    char *line;
    128165    int ntokens, mintokens;
    129     int t, len;
     166    int t;
     167
     168    if (!parser)
     169        return 0;
    130170
    131171    ntokens = (uint8_t)flags;
    132172    mintokens = (uint8_t)(flags >> 8);
    133173
    134     if (parser == NULL)
     174 again:
     175    memset(tokens, 0, sizeof(tokens[0]) * ntokens);
     176
     177    /* Read one line (handling continuations with backslash) */
     178    if (get_line_with_continuation(parser) < 0)
    135179        return 0;
    136180
    137 again:
    138     memset(tokens, 0, sizeof(tokens[0]) * ntokens);
    139     config_free_data(parser);
    140 
    141     /* Read one line (handling continuations with backslash) */
    142     line = bb_get_chunk_with_continuation(parser->fp, &len, &parser->lineno);
    143     if (line == NULL)
    144         return 0;
    145     parser->line = line;
    146 
    147     /* Strip trailing line-feed if any */
    148     if (len && line[len-1] == '\n')
    149         line[len-1] = '\0';
     181    line = parser->line;
    150182
    151183    /* Skip token in the start of line? */
     
    156188        goto again;
    157189
    158     if (flags & PARSE_KEEP_COPY)
     190    if (flags & PARSE_KEEP_COPY) {
     191        free(parser->data);
    159192        parser->data = xstrdup(line);
     193    }
    160194
    161195    /* Tokenize the line */
     
    171205        } else {
    172206            /* Combining, find comment char if any */
    173             line = strchrnul(line, delims[0]);
     207            line = strchrnul(line, PARSE_EOL_COMMENTS ? delims[0] : '\0');
    174208
    175209            /* Trim any extra delimiters from the end */
     
    203237        if (flags & PARSE_MIN_DIE)
    204238            xfunc_die();
    205         if (flags & PARSE_KEEP_COPY)
    206             free(parser->data);
    207239        goto again;
    208240    }
  • branches/3.2/mindi-busybox/libbb/platform.c

    r2725 r3232  
    4343#endif
    4444
    45 #ifndef HAVE_FDPRINTF
    46 /* dprintf is now actually part of POSIX.1, but was only added in 2008 */
    47 int fdprintf(int fd, const char *format, ...)
     45#ifndef HAVE_DPRINTF
     46/* dprintf is now part of POSIX.1, but was only added in 2008 */
     47int dprintf(int fd, const char *format, ...)
    4848{
    4949    va_list p;
     
    135135}
    136136#endif
     137
     138#ifndef HAVE_STPCPY
     139char* FAST_FUNC stpcpy(char *p, const char *to_add)
     140{
     141    while ((*p = *to_add) != '\0') {
     142        p++;
     143        to_add++;
     144    }
     145    return p;
     146}
     147#endif
     148
     149#ifndef HAVE_GETLINE
     150ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream)
     151{
     152    int ch;
     153    char *line = *lineptr;
     154    size_t alloced = *n;
     155    size_t len = 0;
     156
     157    do {
     158        ch = fgetc(stream);
     159        if (ch == EOF)
     160            break;
     161        if (len + 1 >= alloced) {
     162            alloced += alloced/4 + 64;
     163            line = xrealloc(line, alloced);
     164        }
     165        line[len++] = ch;
     166    } while (ch != '\n');
     167
     168    if (len == 0)
     169        return -1;
     170
     171    line[len] = '\0';
     172    *lineptr = line;
     173    *n = alloced;
     174    return len;
     175}
     176#endif
  • branches/3.2/mindi-busybox/libbb/procps.c

    r2725 r3232  
    1313
    1414
    15 typedef struct unsigned_to_name_map_t {
    16     long id;
     15typedef struct id_to_name_map_t {
     16    uid_t id;
    1717    char name[USERNAME_MAX_SIZE];
    18 } unsigned_to_name_map_t;
     18} id_to_name_map_t;
    1919
    2020typedef struct cache_t {
    21     unsigned_to_name_map_t *cache;
     21    id_to_name_map_t *cache;
    2222    int size;
    2323} cache_t;
     
    4040/* Returns -N-1 if not found. */
    4141/* cp->cache[N] is allocated and must be filled in this case */
    42 static int get_cached(cache_t *cp, unsigned id)
     42static int get_cached(cache_t *cp, uid_t id)
    4343{
    4444    int i;
     
    5353#endif
    5454
    55 static char* get_cached(cache_t *cp, long id,
    56             char* FAST_FUNC x2x_utoa(long id))
     55static char* get_cached(cache_t *cp, uid_t id,
     56            char* FAST_FUNC x2x_utoa(uid_t id))
    5757{
    5858    int i;
     
    128128    unsigned long n = 0;
    129129
    130     while ((c = *str++) != ' ') {
     130    /* Need to stop on both ' ' and '\n' */
     131    while ((c = *str++) > ' ') {
    131132        c = ((c|0x20) - '0');
    132133        if (c > 9)
    133             // c = c + '0' - 'a' + 10:
     134            /* c = c + '0' - 'a' + 10: */
    134135            c = c - ('a' - '0' - 10);
    135136        n = n*16 + c;
     
    144145static unsigned long fast_strtoul_10(char **endptr)
    145146{
    146     char c;
     147    unsigned char c;
    147148    char *str = *endptr;
    148149    unsigned long n = *str - '0';
    149150
    150     while ((c = *++str) != ' ')
     151    /* Need to stop on both ' ' and '\n' */
     152    while ((c = *++str) > ' ')
    151153        n = n*10 + (c - '0');
    152154
     
    179181#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
    180182int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
    181               void (*cb)(struct smaprec *, void *), void *data)
     183        void (*cb)(struct smaprec *, void *), void *data)
    182184{
    183185    FILE *file;
     
    199201    while (fgets(buf, PROCPS_BUFSIZE, file)) {
    200202        // Each mapping datum has this form:
    201         // f7d29000-f7d39000 rw-s ADR M:m OFS FILE
     203        // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME
    202204        // Size:                nnn kB
    203205        // Rss:                 nnn kB
     
    224226        if (tp) {
    225227            // We reached next mapping - the line of this form:
    226             // f7d29000-f7d39000 rw-s ADR M:m OFS FILE
     228            // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME
    227229
    228230            if (cb) {
     
    243245            strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1);
    244246
    245             // skipping "rw-s ADR M:m OFS "
     247            // skipping "rw-s FILEOFS M:m INODE "
    246248            tp = skip_whitespace(skip_fields(tp, 4));
    247249            // filter out /dev/something (something != zero)
     
    285287procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
    286288{
    287     struct dirent *entry;
    288     char buf[PROCPS_BUFSIZE];
    289     char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
    290     char *filename_tail;
    291     long tasknice;
    292     unsigned pid;
    293     int n;
    294     struct stat sb;
    295 
    296289    if (!sp)
    297290        sp = alloc_procps_scan();
    298291
    299292    for (;;) {
     293        struct dirent *entry;
     294        char buf[PROCPS_BUFSIZE];
     295        long tasknice;
     296        unsigned pid;
     297        int n;
     298        char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2];
     299        char *filename_tail;
     300
    300301#if ENABLE_FEATURE_SHOW_THREADS
    301         if ((flags & PSSCAN_TASKS) && sp->task_dir) {
     302        if (sp->task_dir) {
    302303            entry = readdir(sp->task_dir);
    303304            if (entry)
     
    321322             * there will be /proc/PID/task/PID (same PID!),
    322323             * so just go ahead and dive into /proc/PID/task. */
    323             char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3];
    324             sprintf(task_dir, "/proc/%u/task", pid);
    325             sp->task_dir = xopendir(task_dir);
     324            sprintf(filename, "/proc/%u/task", pid);
     325            /* Note: if opendir fails, we just go to next /proc/XXX */
     326            sp->task_dir = opendir(filename);
     327            sp->main_thread_pid = pid;
    326328            continue;
    327329        }
     
    346348#endif
    347349
    348         filename_tail = filename + sprintf(filename, "/proc/%u/", pid);
     350#if ENABLE_FEATURE_SHOW_THREADS
     351        if (sp->task_dir)
     352            filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid);
     353        else
     354#endif
     355            filename_tail = filename + sprintf(filename, "/proc/%u/", pid);
    349356
    350357        if (flags & PSSCAN_UIDGID) {
     358            struct stat sb;
    351359            if (stat(filename, &sb))
    352360                continue; /* process probably exited */
     
    356364        }
    357365
    358         if (flags & PSSCAN_STAT) {
     366        /* These are all retrieved from proc/NN/stat in one go: */
     367        if (flags & (PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
     368            | PSSCAN_COMM | PSSCAN_STATE
     369            | PSSCAN_VSZ | PSSCAN_RSS
     370            | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
     371            | PSSCAN_TTY | PSSCAN_NICE
     372            | PSSCAN_CPU)
     373        ) {
    359374            char *cp, *comm1;
    360375            int tty;
     
    411426                continue; /* bogus data, get next /proc/XXX */
    412427# if ENABLE_FEATURE_TOP_SMP_PROCESS
    413             if (n < 11+15)
     428            if (n == 11)
    414429                sp->last_seen_on_cpu = 0;
    415430# endif
     
    558573{
    559574    int sz;
    560     char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
     575    char filename[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
    561576
    562577    sprintf(filename, "/proc/%u/cmdline", pid);
    563578    sz = open_read_close(filename, buf, col - 1);
    564579    if (sz > 0) {
     580        const char *base;
     581        int comm_len;
     582
    565583        buf[sz] = '\0';
    566584        while (--sz >= 0 && buf[sz] == '\0')
    567585            continue;
    568         do {
     586        /* Prevent basename("process foo/bar") = "bar" */
     587        strchrnul(buf, ' ')[0] = '\0';
     588        base = bb_basename(buf); /* before we replace argv0's NUL with space */
     589        while (sz >= 0) {
    569590            if ((unsigned char)(buf[sz]) < ' ')
    570591                buf[sz] = ' ';
    571         } while (--sz >= 0);
     592            sz--;
     593        }
     594
     595        /* If comm differs from argv0, prepend "{comm} ".
     596         * It allows to see thread names set by prctl(PR_SET_NAME).
     597         */
     598        if (base[0] == '-') /* "-sh" (login shell)? */
     599            base++;
     600        comm_len = strlen(comm);
     601        /* Why compare up to comm_len, not COMM_LEN-1?
     602         * Well, some processes rewrite argv, and use _spaces_ there
     603         * while rewriting. (KDE is observed to do it).
     604         * I prefer to still treat argv0 "process foo bar"
     605         * as 'equal' to comm "process".
     606         */
     607        if (strncmp(base, comm, comm_len) != 0) {
     608            comm_len += 3;
     609            if (col > comm_len)
     610                memmove(buf + comm_len, buf, col - comm_len);
     611            snprintf(buf, col, "{%s}", comm);
     612            if (col <= comm_len)
     613                return;
     614            buf[comm_len - 1] = ' ';
     615            buf[col - 1] = '\0';
     616        }
     617
    572618    } else {
    573619        snprintf(buf, col, "[%s]", comm);
  • branches/3.2/mindi-busybox/libbb/progress.c

    r2725 r3232  
    5353}
    5454
    55 void FAST_FUNC bb_progress_init(bb_progress_t *p)
     55void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile)
    5656{
     57#if ENABLE_UNICODE_SUPPORT
     58    init_unicode();
     59    p->curfile = unicode_conv_to_printable_fixedwidth(/*NULL,*/ curfile, 20);
     60#else
     61    p->curfile = curfile;
     62#endif
    5763    p->start_sec = monotonic_sec();
    58     p->lastupdate_sec = p->start_sec;
    59     p->lastsize = 0;
    60     p->inited = 1;
     64    p->last_update_sec = p->start_sec;
     65    p->last_change_sec = p->start_sec;
     66    p->last_size = 0;
    6167}
    6268
     69/* File already had beg_size bytes.
     70 * Then we started downloading.
     71 * We downloaded "transferred" bytes so far.
     72 * Download is expected to stop when total size (beg_size + transferred)
     73 * will be "totalsize" bytes.
     74 * If totalsize == 0, then it is unknown.
     75 */
    6376void FAST_FUNC bb_progress_update(bb_progress_t *p,
    64         const char *curfile,
    65         off_t beg_range,
    66         off_t transferred,
    67         off_t totalsize)
     77        uoff_t beg_size,
     78        uoff_t transferred,
     79        uoff_t totalsize)
    6880{
    6981    uoff_t beg_and_transferred;
    7082    unsigned since_last_update, elapsed;
    71     unsigned ratio;
    72     int barlength, i;
    73 
    74     /* totalsize == 0 if it is unknown */
     83    int barlength;
     84    int kiloscale;
     85
     86    //transferred = 1234; /* use for stall detection testing */
     87    //totalsize = 0; /* use for unknown size download testing */
    7588
    7689    elapsed = monotonic_sec();
    77     since_last_update = elapsed - p->lastupdate_sec;
    78     /* Do not update on every call
    79      * (we can be called on every network read!) */
    80     if (since_last_update == 0 && !totalsize)
    81             return;
    82 
    83     beg_and_transferred = beg_range + transferred;
    84     ratio = 100;
    85     if (beg_and_transferred < totalsize) {
    86         /* Do not update on every call
    87          * (we can be called on every network read!) */
    88         if (since_last_update == 0)
    89             return;
    90         /* long long helps to have it working even if !LFS */
    91         ratio = 100ULL * beg_and_transferred / (uoff_t)totalsize;
    92     }
    93 
    94 #if ENABLE_UNICODE_SUPPORT
    95     init_unicode();
    96     /* libbb candidate? */
    97     {
    98         wchar_t wbuf21[21];
    99         char *buf = xstrdup(curfile);
    100         unsigned len;
    101 
    102         /* trim to 20 wide chars max (sets wbuf21[20] to 0)
    103          * also, in case mbstowcs fails, we at least
    104          * dont get garbage */
    105         memset(wbuf21, 0, sizeof(wbuf21));
    106         /* convert to wide chars, no more than 20 */
    107         len = mbstowcs(wbuf21, curfile, 20); /* NB: may return -1 */
    108         /* back to multibyte; cant overflow */
    109         wcstombs(buf, wbuf21, INT_MAX);
    110         len = (len > 20) ? 0 : 20 - len;
    111         fprintf(stderr, "\r%s%*s%4u%% ", buf, len, "", ratio);
    112         free(buf);
    113     }
    114 #else
    115     fprintf(stderr, "\r%-20.20s%4u%% ", curfile, ratio);
    116 #endif
    117 
    118     barlength = get_tty2_width() - 49;
    119     if (barlength > 0) {
    120         /* god bless gcc for variable arrays :) */
    121         char buf[barlength + 1];
    122         unsigned stars = (unsigned)barlength * ratio / (unsigned)100;
    123         memset(buf, ' ', barlength);
    124         buf[barlength] = '\0';
    125         memset(buf, '*', stars);
    126         fprintf(stderr, "|%s|", buf);
    127     }
    128 
    129     i = 0;
     90    since_last_update = elapsed - p->last_update_sec;
     91    p->last_update_sec = elapsed;
     92
     93    if (totalsize != 0 && transferred >= totalsize - beg_size) {
     94        /* Last call. Do not skip this update */
     95        transferred = totalsize - beg_size; /* sanitize just in case */
     96    }
     97    else if (since_last_update == 0) {
     98        /*
     99         * Do not update on every call
     100         * (we can be called on every network read!)
     101         */
     102        return;
     103    }
     104
     105    kiloscale = 0;
     106    /*
     107     * Scale sizes down if they are close to overflowing.
     108     * This allows calculations like (100 * transferred / totalsize)
     109     * without risking overflow: we guarantee 10 highest bits to be 0.
     110     * Introduced error is less than 1 / 2^12 ~= 0.025%
     111     */
     112    if (ULONG_MAX > 0xffffffff || sizeof(off_t) == 4 || sizeof(off_t) != 8) {
     113        /*
     114         * 64-bit CPU || small off_t: in either case,
     115         * >> is cheap, single-word operation.
     116         * ... || strange off_t: also use this code
     117         * (it is safe, just suboptimal wrt code size),
     118         * because 32/64 optimized one works only for 64-bit off_t.
     119         */
     120        if (totalsize >= (1 << 22)) {
     121            totalsize >>= 10;
     122            beg_size >>= 10;
     123            transferred >>= 10;
     124            kiloscale = 1;
     125        }
     126    } else {
     127        /* 32-bit CPU and 64-bit off_t.
     128         * Use a 40-bit shift, it is easier to do on 32-bit CPU.
     129         */
     130/* ONE suppresses "warning: shift count >= width of type" */
     131#define ONE (sizeof(off_t) > 4)
     132        if (totalsize >= (uoff_t)(1ULL << 54*ONE)) {
     133            totalsize = (uint32_t)(totalsize >> 32*ONE) >> 8;
     134            beg_size = (uint32_t)(beg_size >> 32*ONE) >> 8;
     135            transferred = (uint32_t)(transferred >> 32*ONE) >> 8;
     136            kiloscale = 4;
     137        }
     138    }
     139
     140    if (ENABLE_UNICODE_SUPPORT)
     141        fprintf(stderr, "\r%s", p->curfile);
     142    else
     143        fprintf(stderr, "\r%-20.20s", p->curfile);
     144
     145    beg_and_transferred = beg_size + transferred;
     146
     147    if (totalsize != 0) {
     148        unsigned ratio = 100 * beg_and_transferred / totalsize;
     149        fprintf(stderr, "%4u%%", ratio);
     150
     151        barlength = get_tty2_width() - 49;
     152        if (barlength > 0) {
     153            /* god bless gcc for variable arrays :) */
     154            char buf[barlength + 1];
     155            unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize;
     156            memset(buf, ' ', barlength);
     157            buf[barlength] = '\0';
     158            memset(buf, '*', stars);
     159            fprintf(stderr, " |%s|", buf);
     160        }
     161    }
     162
    130163    while (beg_and_transferred >= 100000) {
    131         i++;
    132164        beg_and_transferred >>= 10;
     165        kiloscale++;
    133166    }
    134167    /* see http://en.wikipedia.org/wiki/Tera */
    135     fprintf(stderr, "%6u%c ", (unsigned)beg_and_transferred, " kMGTPEZY"[i]);
    136 #define beg_and_transferred dont_use_beg_and_transferred_below
    137 
    138     if (transferred > p->lastsize) {
    139         p->lastupdate_sec = elapsed;
    140         p->lastsize = transferred;
     168    fprintf(stderr, "%6u%c", (unsigned)beg_and_transferred, " kMGTPEZY"[kiloscale]);
     169#define beg_and_transferred dont_use_beg_and_transferred_below()
     170
     171    since_last_update = elapsed - p->last_change_sec;
     172    if ((unsigned)transferred != p->last_size) {
     173        p->last_change_sec = elapsed;
     174        p->last_size = (unsigned)transferred;
    141175        if (since_last_update >= STALLTIME) {
    142             /* We "cut off" these seconds from elapsed time
     176            /* We "cut out" these seconds from elapsed time
    143177             * by adjusting start time */
    144178            p->start_sec += since_last_update;
     
    146180        since_last_update = 0; /* we are un-stalled now */
    147181    }
     182
    148183    elapsed -= p->start_sec; /* now it's "elapsed since start" */
    149184
    150185    if (since_last_update >= STALLTIME) {
    151         fprintf(stderr, " - stalled -");
     186        fprintf(stderr, "  - stalled -");
     187    } else if (!totalsize || !transferred || (int)elapsed < 0) {
     188        fprintf(stderr, " --:--:-- ETA");
    152189    } else {
    153         off_t to_download = totalsize - beg_range;
    154         if (!totalsize || transferred <= 0 || (int)elapsed <= 0 || transferred > to_download) {
    155             fprintf(stderr, "--:--:-- ETA");
    156         } else {
    157             /* to_download / (transferred/elapsed) - elapsed: */
    158             /* (long long helps to have working ETA even if !LFS) */
    159             unsigned eta = (unsigned long long)to_download*elapsed/(uoff_t)transferred - elapsed;
    160             unsigned secs = eta % 3600;
    161             fprintf(stderr, "%02u:%02u:%02u ETA", eta / 3600, secs / 60, secs % 60);
    162         }
     190        unsigned eta, secs, hours;
     191
     192        totalsize -= beg_size; /* now it's "total to upload" */
     193
     194        /* Estimated remaining time =
     195         * estimated_sec_to_dl_totalsize_bytes - elapsed_sec =
     196         * totalsize / average_bytes_sec_so_far - elapsed =
     197         * totalsize / (transferred/elapsed) - elapsed =
     198         * totalsize * elapsed / transferred - elapsed
     199         */
     200        eta = totalsize * elapsed / transferred - elapsed;
     201        if (eta >= 1000*60*60)
     202            eta = 1000*60*60 - 1;
     203        secs = eta % 3600;
     204        hours = eta / 3600;
     205        fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60);
    163206    }
    164207}
  • branches/3.2/mindi-busybox/libbb/pw_encrypt.c

    r2725 r3232  
    2828}
    2929
    30 int FAST_FUNC crypt_make_salt(char *p, int cnt, int x)
     30int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */)
    3131{
    32     x += getpid() + time(NULL);
     32    /* was: x += ... */
     33    int x = getpid() + monotonic_us();
    3334    do {
    3435        /* x = (x*1664525 + 1013904223) % 2^32 generator is lame
     
    4647    *p = '\0';
    4748    return x;
     49}
     50
     51char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo)
     52{
     53    int len = 2/2;
     54    char *salt_ptr = salt;
     55    if (algo[0] != 'd') { /* not des */
     56        len = 8/2; /* so far assuming md5 */
     57        *salt_ptr++ = '$';
     58        *salt_ptr++ = '1';
     59        *salt_ptr++ = '$';
     60#if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA
     61        if (algo[0] == 's') { /* sha */
     62            salt[1] = '5' + (strcmp(algo, "sha512") == 0);
     63            len = 16/2;
     64        }
     65#endif
     66    }
     67    crypt_make_salt(salt_ptr, len);
     68    return salt_ptr;
    4869}
    4970
  • branches/3.2/mindi-busybox/libbb/read_key.c

    r2725 r3232  
    1616    int n;
    1717
    18     /* Known escape sequences for cursor and function keys */
     18    /* Known escape sequences for cursor and function keys.
     19     * See "Xterm Control Sequences"
     20     * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
     21     */
    1922    static const char esccmds[] ALIGN1 = {
    2023        'O','A'        |0x80,KEYCODE_UP      ,
     
    4144        '[','D'        |0x80,KEYCODE_LEFT    ,
    4245        /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */
    43         /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> */
     46        /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> - implemented below */
    4447        /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */
    4548        /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */
    4649        /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */
     50        /* ESC [ 1 ; 7 x, where x = A/B/C/D: Ctrl-Alt-<arrow> */
     51        /* ESC [ 1 ; 8 x, where x = A/B/C/D: Ctrl-Alt-Shift-<arrow> */
    4752        '[','H'        |0x80,KEYCODE_HOME    , /* xterm */
    48         /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */
    4953        '[','F'        |0x80,KEYCODE_END     , /* xterm */
     54        /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */
     55        /* '[','Z'        |0x80,KEYCODE_SHIFT_TAB, */
    5056        '[','1','~'    |0x80,KEYCODE_HOME    , /* vt100? linux vt? or what? */
    5157        '[','2','~'    |0x80,KEYCODE_INSERT  ,
     
    6470        '[','8','~'    |0x80,KEYCODE_END     , /* vt100? linux vt? or what? */
    6571#if 0
    66         '[','1','1','~'|0x80,KEYCODE_FUN1    ,
    67         '[','1','2','~'|0x80,KEYCODE_FUN2    ,
    68         '[','1','3','~'|0x80,KEYCODE_FUN3    ,
    69         '[','1','4','~'|0x80,KEYCODE_FUN4    ,
     72        '[','1','1','~'|0x80,KEYCODE_FUN1    , /* old xterm, deprecated by ESC O P */
     73        '[','1','2','~'|0x80,KEYCODE_FUN2    , /* old xterm... */
     74        '[','1','3','~'|0x80,KEYCODE_FUN3    , /* old xterm... */
     75        '[','1','4','~'|0x80,KEYCODE_FUN4    , /* old xterm... */
    7076        '[','1','5','~'|0x80,KEYCODE_FUN5    ,
    7177        /* [ESC] ESC [ 1 5 [;2] ~ - [Alt-][Shift-]F5 */
     
    8793        '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT,
    8894        '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT ,
     95        /* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP    , - unused */
     96        /* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN  , - unused */
     97        '[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT,
     98        '[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT ,
     99        /* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */
    89100        0
    90         /* ESC [ Z - Shift-Tab */
    91101    };
    92102
     
    215225        n++;
    216226        /* Try to decipher "ESC [ NNN ; NNN R" sequence */
    217         if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL || ENABLE_FEATURE_VI_ASK_TERMINAL)
     227        if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL
     228            || ENABLE_FEATURE_VI_ASK_TERMINAL
     229            || ENABLE_FEATURE_LESS_ASK_TERMINAL
     230            )
    218231         && n >= 5
    219232         && buffer[0] == '['
  • branches/3.2/mindi-busybox/libbb/read_printf.c

    r2725 r3232  
    88 */
    99#include "libbb.h"
    10 
    11 #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \
    12     || ENABLE_FEATURE_SEAMLESS_BZ2 \
    13     || ENABLE_FEATURE_SEAMLESS_GZ \
    14     /* || ENABLE_FEATURE_SEAMLESS_Z */ \
    15 )
    16 
    17 #if ZIPPED
    18 # include "archive.h"
    19 #endif
    2010
    2111
     
    5646 * Thankfully, poll() doesn't care about O_NONBLOCK flag.
    5747 */
    58 ssize_t FAST_FUNC nonblock_safe_read(int fd, void *buf, size_t count)
     48ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR)
    5949{
    6050    struct pollfd pfd[1];
     
    6252
    6353    while (1) {
    64         n = safe_read(fd, buf, count);
     54        n = loop_on_EINTR ? safe_read(fd, buf, count) : read(fd, buf, count);
    6555        if (n >= 0 || errno != EAGAIN)
    6656            return n;
     
    6858        pfd[0].fd = fd;
    6959        pfd[0].events = POLLIN;
    70         safe_poll(pfd, 1, -1); /* note: this pulls in printf */
     60        /* note: safe_poll pulls in printf */
     61        loop_on_EINTR ? safe_poll(pfd, 1, -1) : poll(pfd, 1, -1);
    7162    }
    7263}
     
    7566// Reads byte-by-byte. Useful when it is important to not read ahead.
    7667// Bytes are appended to pfx (which must be malloced, or NULL).
    77 char* FAST_FUNC xmalloc_reads(int fd, char *buf, size_t *maxsz_p)
     68char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p)
    7869{
    7970    char *p;
    80     size_t sz = buf ? strlen(buf) : 0;
     71    char *buf = NULL;
     72    size_t sz = 0;
    8173    size_t maxsz = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
    8274
    8375    goto jump_in;
     76
    8477    while (sz < maxsz) {
    8578        if ((size_t)(p - buf) == sz) {
     
    8982            sz += 128;
    9083        }
    91         /* nonblock_safe_read() because we are used by e.g. shells */
    92         if (nonblock_safe_read(fd, p, 1) != 1) { /* EOF/error */
     84        if (nonblock_immune_read(fd, p, 1, /*loop_on_EINTR:*/ 1) != 1) {
     85            /* EOF/error */
    9386            if (p == buf) { /* we read nothing */
    9487                free(buf);
     
    242235    return buf;
    243236}
    244 
    245 /* Used by e.g. rpm which gives us a fd without filename,
    246  * thus we can't guess the format from filename's extension.
    247  */
    248 #if ZIPPED
    249 void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
    250 {
    251     const int fail_if_not_detected = 1;
    252     union {
    253         uint8_t b[4];
    254         uint16_t b16[2];
    255         uint32_t b32[1];
    256     } magic;
    257     int offset = -2;
    258 # if BB_MMU
    259     IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
    260     enum { xformer_prog = 0 };
    261 # else
    262     enum { xformer = 0 };
    263     const char *xformer_prog;
    264 # endif
    265 
    266     /* .gz and .bz2 both have 2-byte signature, and their
    267      * unpack_XXX_stream wants this header skipped. */
    268     xread(fd, magic.b16, sizeof(magic.b16[0]));
    269     if (ENABLE_FEATURE_SEAMLESS_GZ
    270      && magic.b16[0] == GZIP_MAGIC
    271     ) {
    272 # if BB_MMU
    273         xformer = unpack_gz_stream;
    274 # else
    275         xformer_prog = "gunzip";
    276 # endif
    277         goto found_magic;
    278     }
    279     if (ENABLE_FEATURE_SEAMLESS_BZ2
    280      && magic.b16[0] == BZIP2_MAGIC
    281     ) {
    282 # if BB_MMU
    283         xformer = unpack_bz2_stream;
    284 # else
    285         xformer_prog = "bunzip2";
    286 # endif
    287         goto found_magic;
    288     }
    289     if (ENABLE_FEATURE_SEAMLESS_XZ
    290      && magic.b16[0] == XZ_MAGIC1
    291     ) {
    292         offset = -6;
    293         xread(fd, magic.b32, sizeof(magic.b32[0]));
    294         if (magic.b32[0] == XZ_MAGIC2) {
    295 # if BB_MMU
    296             xformer = unpack_xz_stream;
    297             /* unpack_xz_stream wants fd at position 6, no need to seek */
    298             //xlseek(fd, offset, SEEK_CUR);
    299 # else
    300             xformer_prog = "unxz";
    301 # endif
    302             goto found_magic;
    303         }
    304     }
    305 
    306     /* No known magic seen */
    307     if (fail_if_not_detected)
    308         bb_error_msg_and_die("no gzip"
    309             IF_FEATURE_SEAMLESS_BZ2("/bzip2")
    310             IF_FEATURE_SEAMLESS_XZ("/xz")
    311             " magic");
    312     xlseek(fd, offset, SEEK_CUR);
    313     return;
    314 
    315  found_magic:
    316 # if !BB_MMU
    317     /* NOMMU version of open_transformer execs
    318      * an external unzipper that wants
    319      * file position at the start of the file */
    320     xlseek(fd, offset, SEEK_CUR);
    321 # endif
    322     open_transformer(fd, xformer, xformer_prog);
    323 }
    324 #endif /* ZIPPED */
    325 
    326 int FAST_FUNC open_zipped(const char *fname)
    327 {
    328 #if !ZIPPED
    329     return open(fname, O_RDONLY);
    330 #else
    331     char *sfx;
    332     int fd;
    333 
    334     fd = open(fname, O_RDONLY);
    335     if (fd < 0)
    336         return fd;
    337 
    338     sfx = strrchr(fname, '.');
    339     if (sfx) {
    340         sfx++;
    341         if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)
    342             /* .lzma has no header/signature, just trust it */
    343             open_transformer(fd, unpack_lzma_stream, "unlzma");
    344         else
    345         if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)
    346          || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)
    347          || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)
    348         ) {
    349             setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);
    350         }
    351     }
    352 
    353     return fd;
    354 #endif
    355 }
    356 
    357 void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
    358 {
    359     int fd;
    360     char *image;
    361 
    362     fd = open_zipped(fname);
    363     if (fd < 0)
    364         return NULL;
    365 
    366     image = xmalloc_read(fd, maxsz_p);
    367     if (!image)
    368         bb_perror_msg("read error from '%s'", fname);
    369     close(fd);
    370 
    371     return image;
    372 }
  • branches/3.2/mindi-busybox/libbb/remove_file.c

    r2725 r3232  
    3434
    3535        if (!(flags & FILEUTILS_RECUR)) {
    36             bb_error_msg("%s: is a directory", path);
     36            bb_error_msg("'%s' is a directory", path);
    3737            return -1;
    3838        }
  • branches/3.2/mindi-busybox/libbb/safe_gethostname.c

    r2725 r3232  
    5151    return xstrndup(!uts.nodename[0] ? "?" : uts.nodename, sizeof(uts.nodename));
    5252}
    53 
    54 /*
    55  * On success return the current malloced and NUL terminated domainname.
    56  * On error return malloced and NUL terminated string "?".
    57  * This is an illegal first character for a domainname.
    58  * The returned malloced string must be freed by the caller.
    59  */
    60 char* FAST_FUNC safe_getdomainname(void)
    61 {
    62 #if defined(__linux__)
    63 /* The field domainname of struct utsname is Linux specific. */
    64     struct utsname uts;
    65     uname(&uts);
    66     return xstrndup(!uts.domainname[0] ? "?" : uts.domainname, sizeof(uts.domainname));
    67 #else
    68     /* We really don't care about people with domain names wider than most screens */
    69     char buf[256];
    70     int r = getdomainname(buf, sizeof(buf));
    71     buf[sizeof(buf)-1] = '\0';
    72     return xstrdup(r < 0 ? "?" : buf);
    73 #endif
    74 }
  • branches/3.2/mindi-busybox/libbb/selinux_common.c

    r2725 r3232  
    1111
    1212context_t FAST_FUNC set_security_context_component(security_context_t cur_context,
    13                      char *user, char *role, char *type, char *range)
     13            char *user, char *role, char *type, char *range)
    1414{
    1515    context_t con = context_new(cur_context);
  • branches/3.2/mindi-busybox/libbb/setup_environment.c

    r2725 r3232  
    3333void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw)
    3434{
     35    if (!shell || !shell[0])
     36        shell = DEFAULT_SHELL;
     37
    3538    /* Change the current working directory to be the home directory
    3639     * of the user */
    37     if (chdir(pw->pw_dir)) {
    38         xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/");
    39         bb_error_msg("can't chdir to home directory '%s'", pw->pw_dir);
     40    if (!(flags & SETUP_ENV_NO_CHDIR)) {
     41        if (chdir(pw->pw_dir) != 0) {
     42            bb_error_msg("can't change directory to '%s'", pw->pw_dir);
     43            xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/");
     44        }
    4045    }
    4146
  • branches/3.2/mindi-busybox/libbb/signals.c

    r2725 r3232  
    4040    while (sigs) {
    4141        if (sigs & bit) {
    42             sigs &= ~bit;
     42            sigs -= bit;
    4343            signal(sig_no, f);
    4444        }
     
    6161    while (sigs) {
    6262        if (sigs & bit) {
    63             sigs &= ~bit;
     63            sigs -= bit;
    6464            sigaction_set(sig_no, &sa);
    6565        }
     
    9898    sig_unblock(sig);
    9999    raise(sig);
    100     _exit(EXIT_FAILURE); /* Should not reach it */
     100    _exit(sig | 128); /* Should not reach it */
    101101}
    102102
  • branches/3.2/mindi-busybox/libbb/single_argv.c

    r2725 r3232  
    1111char* FAST_FUNC single_argv(char **argv)
    1212{
     13    if (argv[1] && strcmp(argv[1], "--") == 0)
     14        argv++;
    1315    if (!argv[1] || argv[2])
    1416        bb_show_usage();
  • branches/3.2/mindi-busybox/libbb/time.c

    r2725 r3232  
    9292         * Everything but the minutes is optional
    9393         *
    94          * This coincides with the format of "touch -t TIME"
     94         * "touch -t DATETIME" format: [[[[[YY]YY]MM]DD]hh]mm[.ss]
     95         * Some, but not all, Unix "date DATETIME" commands
     96         * move [[YY]YY] past minutes mm field (!).
     97         * Coreutils date does it, and SUS mandates it.
     98         * (date -s DATETIME does not support this format. lovely!)
     99         * In bbox, this format is special-cased in date applet
     100         * (IOW: this function assumes "touch -t" format).
    95101         */
     102        unsigned cur_year = ptm->tm_year;
    96103        int len = strchrnul(date_str, '.') - date_str;
    97104
     
    134141            /* Adjust month from 1-12 to 0-11 */
    135142            ptm->tm_mon -= 1;
     143            if ((int)cur_year >= 50) { /* >= 1950 */
     144                /* Adjust year: */
     145                /* 1. Put it in the current century */
     146                ptm->tm_year += (cur_year / 100) * 100;
     147                /* 2. If too far in the past, +100 years */
     148                if (ptm->tm_year < cur_year - 50)
     149                    ptm->tm_year += 100;
     150                /* 3. If too far in the future, -100 years */
     151                if (ptm->tm_year > cur_year + 50)
     152                    ptm->tm_year -= 100;
     153            }
    136154        } else
    137155        /* ccyymmddHHMM[.SS] */
  • branches/3.2/mindi-busybox/libbb/u_signal_names.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//config:config FEATURE_RTMINMAX
     11//config:   bool "Support RTMIN[+n] and RTMAX[-n] signal names"
     12//config:   default y
     13//config:   help
     14//config:     Support RTMIN[+n] and RTMAX[-n] signal names
     15//config:     in kill, killall etc. This costs ~250 bytes.
    916
    1017#include "libbb.h"
     
    118125    [SIGSYS   ] = "SYS",
    119126#endif
     127#if ENABLE_FEATURE_RTMINMAX
     128# ifdef __SIGRTMIN
     129    [__SIGRTMIN] = "RTMIN",
     130# endif
     131// This makes array about x2 bigger.
     132// More compact approach is to special-case SIGRTMAX in print_signames()
     133//# ifdef __SIGRTMAX
     134//  [__SIGRTMAX] = "RTMAX",
     135//# endif
     136#endif
    120137};
    121138
     
    135152            return i;
    136153
    137 #if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO))
     154#if ENABLE_DESKTOP
     155# if defined(SIGIOT) || defined(SIGIO)
    138156    /* SIGIO[T] are aliased to other names,
    139157     * thus cannot be stored in the signals[] array.
    140158     * Need special code to recognize them */
    141159    if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
    142 #ifdef SIGIO
     160#  ifdef SIGIO
    143161        if (!name[2])
    144162            return SIGIO;
    145 #endif
    146 #ifdef SIGIOT
     163#  endif
     164#  ifdef SIGIOT
    147165        if ((name[2] | 0x20) == 't' && !name[3])
    148166            return SIGIOT;
    149 #endif
    150     }
     167#  endif
     168    }
     169# endif
     170#endif
     171
     172#if ENABLE_FEATURE_RTMINMAX
     173# if defined(SIGRTMIN) && defined(SIGRTMAX)
     174/* libc may use some rt sigs for pthreads and therefore "remap" SIGRTMIN/MAX,
     175 * but we want to use "raw" SIGRTMIN/MAX. Underscored names, if exist, provide
     176 * them. If they don't exist, fall back to non-underscored ones: */
     177#  if !defined(__SIGRTMIN)
     178#   define __SIGRTMIN SIGRTMIN
     179#  endif
     180#  if !defined(__SIGRTMAX)
     181#   define __SIGRTMAX SIGRTMAX
     182#  endif
     183    if (strncasecmp(name, "RTMIN", 5) == 0) {
     184        if (!name[5])
     185            return __SIGRTMIN;
     186        if (name[5] == '+') {
     187            i = bb_strtou(name + 6, NULL, 10);
     188            if (!errno && i <= __SIGRTMAX - __SIGRTMIN)
     189                return __SIGRTMIN + i;
     190        }
     191    }
     192    else if (strncasecmp(name, "RTMAX", 5) == 0) {
     193        if (!name[5])
     194            return __SIGRTMAX;
     195        if (name[5] == '-') {
     196            i = bb_strtou(name + 6, NULL, 10);
     197            if (!errno && i <= __SIGRTMAX - __SIGRTMIN)
     198                return __SIGRTMAX - i;
     199        }
     200    }
     201# endif
    151202#endif
    152203
     
    176227        const char *name = signals[signo];
    177228        if (name[0])
    178             puts(name);
    179     }
     229            printf("%2u) %s\n", signo, name);
     230    }
     231#if ENABLE_FEATURE_RTMINMAX
     232# ifdef __SIGRTMAX
     233    printf("%2u) %s\n", __SIGRTMAX, "RTMAX");
     234# endif
     235#endif
    180236}
  • branches/3.2/mindi-busybox/libbb/udp_io.c

    r2725 r3232  
    1414 */
    1515void FAST_FUNC
    16 socket_want_pktinfo(int fd)
     16socket_want_pktinfo(int fd UNUSED_PARAM)
    1717{
    1818#ifdef IP_PKTINFO
  • branches/3.2/mindi-busybox/libbb/unicode.c

    r2725 r3232  
    2424/* Unicode support using libc locale support. */
    2525
    26 void FAST_FUNC init_unicode(void)
     26void FAST_FUNC reinit_unicode(const char *LANG)
    2727{
    2828    static const char unicode_0x394[] = { 0xce, 0x94, 0 };
    2929    size_t width;
    3030
    31     if (unicode_status != UNICODE_UNKNOWN)
    32         return;
     31//TODO: avoid repeated calls by caching last string?
     32    setlocale(LC_ALL, (LANG && LANG[0]) ? LANG : "C");
     33
    3334    /* In unicode, this is a one character string */
    3435// can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
     
    3738}
    3839
     40void FAST_FUNC init_unicode(void)
     41{
     42    if (unicode_status == UNICODE_UNKNOWN)
     43        reinit_unicode(getenv("LANG"));
     44}
     45
    3946#else
    4047
     
    4249
    4350# if ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
    44 void FAST_FUNC init_unicode(void)
    45 {
    46     char *lang;
    47 
    48     if (unicode_status != UNICODE_UNKNOWN)
    49         return;
    50 
     51void FAST_FUNC reinit_unicode(const char *LANG)
     52{
    5153    unicode_status = UNICODE_OFF;
    52     lang = getenv("LANG");
    53     if (!lang || !(strstr(lang, ".utf") || strstr(lang, ".UTF")))
     54    if (!LANG || !(strstr(LANG, ".utf") || strstr(LANG, ".UTF")))
    5455        return;
    5556    unicode_status = UNICODE_ON;
     57}
     58
     59void FAST_FUNC init_unicode(void)
     60{
     61    if (unicode_status == UNICODE_UNKNOWN)
     62        reinit_unicode(getenv("LANG"));
    5663}
    5764# endif
     
    11081115    return unicode_conv_to_printable2(stats, src, INT_MAX, 0);
    11091116}
     1117char* FAST_FUNC unicode_conv_to_printable_fixedwidth(/*uni_stat_t *stats,*/ const char *src, unsigned width)
     1118{
     1119    return unicode_conv_to_printable2(/*stats:*/ NULL, src, width, UNI_FLAG_PAD);
     1120}
     1121
     1122#ifdef UNUSED
    11101123char* FAST_FUNC unicode_conv_to_printable_maxwidth(uni_stat_t *stats, const char *src, unsigned maxwidth)
    11111124{
    11121125    return unicode_conv_to_printable2(stats, src, maxwidth, 0);
    11131126}
    1114 char* FAST_FUNC unicode_conv_to_printable_fixedwidth(uni_stat_t *stats, const char *src, unsigned width)
    1115 {
    1116     return unicode_conv_to_printable2(stats, src, width, UNI_FLAG_PAD);
    1117 }
    1118 
    1119 #ifdef UNUSED
     1127
    11201128unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src)
    11211129{
  • branches/3.2/mindi-busybox/libbb/utmp.c

    r2725 r3232  
    88 */
    99#include "libbb.h"
    10 #include <utmp.h>
    1110
    1211static void touch(const char *filename)
  • branches/3.2/mindi-busybox/libbb/uuencode.c

    r2725 r3232  
    1111
    1212/* Conversion table.  for base 64 */
    13 const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = {
     13const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = {
    1414    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
    1515    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
     
    2121    '4', '5', '6', '7', '8', '9', '+', '/',
    2222    '=' /* termination character */,
    23     '\n', '\0' /* needed for uudecode.c */
     23    '\0' /* needed for uudecode.c only */
    2424};
    2525
     
    7474
    7575/*
     76 * Decode base64 encoded string. Stops on '\0'.
     77 *
     78 * Returns: pointer to the undecoded part of source.
     79 * If points to '\0', then the source was fully decoded.
     80 * (*pp_dst): advanced past the last written byte.
     81 */
     82const char* FAST_FUNC decode_base64(char **pp_dst, const char *src)
     83{
     84    char *dst = *pp_dst;
     85    const char *src_tail;
     86
     87    while (1) {
     88        unsigned char six_bit[4];
     89        int count = 0;
     90
     91        /* Fetch up to four 6-bit values */
     92        src_tail = src;
     93        while (count < 4) {
     94            char *table_ptr;
     95            int ch;
     96
     97            /* Get next _valid_ character.
     98             * bb_uuenc_tbl_base64[] contains this string:
     99             *  0         1         2         3         4         5         6
     100             *  01234567890123456789012345678901234567890123456789012345678901234
     101             * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
     102             */
     103            do {
     104                ch = *src;
     105                if (ch == '\0') {
     106                    if (count == 0) {
     107                        /* Example:
     108                         * If we decode "QUJD <NUL>", we want
     109                         * to return ptr to NUL, not to ' ',
     110                         * because we did fully decode
     111                         * the string (to "ABC").
     112                         */
     113                        src_tail = src;
     114                    }
     115                    goto ret;
     116                }
     117                src++;
     118                table_ptr = strchr(bb_uuenc_tbl_base64, ch);
     119//TODO: add BASE64_FLAG_foo to die on bad char?
     120            } while (!table_ptr);
     121
     122            /* Convert encoded character to decimal */
     123            ch = table_ptr - bb_uuenc_tbl_base64;
     124
     125            /* ch is 64 if char was '=', otherwise 0..63 */
     126            if (ch == 64)
     127                break;
     128            six_bit[count] = ch;
     129            count++;
     130        }
     131
     132        /* Transform 6-bit values to 8-bit ones.
     133         * count can be < 4 when we decode the tail:
     134         * "eQ==" -> "y", not "y NUL NUL".
     135         * Note that (count > 1) is always true,
     136         * "x===" encoding is not valid:
     137         * even a single zero byte encodes as "AA==".
     138         * However, with current logic we come here with count == 1
     139         * when we decode "==" tail.
     140         */
     141        if (count > 1)
     142            *dst++ = six_bit[0] << 2 | six_bit[1] >> 4;
     143        if (count > 2)
     144            *dst++ = six_bit[1] << 4 | six_bit[2] >> 2;
     145        if (count > 3)
     146            *dst++ = six_bit[2] << 6 | six_bit[3];
     147        /* Note that if we decode "AA==" and ate first '=',
     148         * we just decoded one char (count == 2) and now we'll
     149         * do the loop once more to decode second '='.
     150         */
     151    } /* while (1) */
     152 ret:
     153    *pp_dst = dst;
     154    return src_tail;
     155}
     156
     157/*
    76158 * Decode base64 encoded stream.
    77159 * Can stop on EOF, specified char, or on uuencode-style "====" line:
     
    84166#define uu_style_end (flags & BASE64_FLAG_UU_STOP)
    85167
    86     int term_count = 0;
     168    /* uuencoded files have 61 byte lines. Use 64 byte buffer
     169     * to process line at a time.
     170     */
     171    enum { BUFFER_SIZE = 64 };
     172
     173    char in_buf[BUFFER_SIZE + 2];
     174    char out_buf[BUFFER_SIZE / 4 * 3 + 2];
     175    char *out_tail;
     176    const char *in_tail;
     177    int term_seen = 0;
     178    int in_count = 0;
    87179
    88180    while (1) {
    89         unsigned char translated[4];
    90         int count = 0;
    91 
    92         /* Process one group of 4 chars */
    93         while (count < 4) {
    94             char *table_ptr;
    95             int ch;
    96 
    97             /* Get next _valid_ character.
    98              * bb_uuenc_tbl_base64[] contains this string:
    99              *  0         1         2         3         4         5         6
    100              *  012345678901234567890123456789012345678901234567890123456789012345
    101              * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
     181        while (in_count < BUFFER_SIZE) {
     182            int ch = fgetc(src_stream);
     183            if (ch == exit_char) {
     184                if (in_count == 0)
     185                    return;
     186                term_seen = 1;
     187                break;
     188            }
     189            if (ch == EOF) {
     190                term_seen = 1;
     191                break;
     192            }
     193            /* Prevent "====" line to be split: stop if we see '\n'.
     194             * We can also skip other whitespace and skirt the problem
     195             * of files with NULs by stopping on any control char or space:
    102196             */
    103             do {
    104                 ch = fgetc(src_stream);
    105                 if (ch == exit_char && count == 0)
    106                     return;
    107                 if (ch == EOF)
    108                     bb_error_msg_and_die("truncated base64 input");
    109                 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
    110 //TODO: add BASE64_FLAG_foo to die on bad char?
    111 //Note that then we may need to still allow '\r' (for mail processing)
    112             } while (!table_ptr);
    113 
    114             /* Convert encoded character to decimal */
    115             ch = table_ptr - bb_uuenc_tbl_base64;
    116 
    117             if (ch == 65 /* '\n' */) {
    118                 /* Terminating "====" line? */
    119                 if (uu_style_end && term_count == 4)
    120                     return; /* yes */
    121                 term_count = 0;
    122                 continue;
    123             }
    124             /* ch is 64 if char was '=', otherwise 0..63 */
    125             translated[count] = ch & 63; /* 64 -> 0 */
    126             if (ch == 64) {
    127                 term_count++;
    128                 break;
    129             }
    130             count++;
    131             term_count = 0;
    132         }
    133 
    134         /* Merge 6 bit chars to 8 bit.
    135          * count can be < 4 when we decode the tail:
    136          * "eQ==" -> "y", not "y NUL NUL"
    137          */
    138         if (count > 1)
    139             fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
    140         if (count > 2)
    141             fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
    142         if (count > 3)
    143             fputc(translated[2] << 6 | translated[3], dst_stream);
    144     } /* while (1) */
     197            if (ch <= ' ')
     198                break;
     199            in_buf[in_count++] = ch;
     200        }
     201        in_buf[in_count] = '\0';
     202
     203        /* Did we encounter "====" line? */
     204        if (uu_style_end && strcmp(in_buf, "====") == 0)
     205            return;
     206
     207        out_tail = out_buf;
     208        in_tail = decode_base64(&out_tail, in_buf);
     209
     210        fwrite(out_buf, (out_tail - out_buf), 1, dst_stream);
     211
     212        if (term_seen) {
     213            /* Did we consume ALL characters? */
     214            if (*in_tail == '\0')
     215                return;
     216            /* No */
     217            bb_error_msg_and_die("truncated base64 input");
     218        }
     219
     220        /* It was partial decode */
     221        in_count = strlen(in_tail);
     222        memmove(in_buf, in_tail, in_count);
     223    }
    145224}
  • branches/3.2/mindi-busybox/libbb/vdprintf.c

    r2725 r3232  
    1313int FAST_FUNC vdprintf(int d, const char *format, va_list ap)
    1414{
    15     char buf[BUF_SIZE];
     15    char buf[8 * 1024];
    1616    int len;
    1717
    18     len = vsnprintf(buf, BUF_SIZE, format, ap);
     18    len = vsnprintf(buf, sizeof(buf), format, ap);
    1919    return write(d, buf, len);
    2020}
  • branches/3.2/mindi-busybox/libbb/vfork_daemon_rexec.c

    r2725 r3232  
    7070
    7171#if ENABLE_FEATURE_PREFER_APPLETS
    72 void FAST_FUNC save_nofork_data(struct nofork_save_area *save)
     72struct nofork_save_area {
     73    jmp_buf die_jmp;
     74    const char *applet_name;
     75    uint32_t option_mask32;
     76    int die_sleep;
     77    uint8_t xfunc_error_retval;
     78};
     79static void save_nofork_data(struct nofork_save_area *save)
    7380{
    7481    memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
     
    7784    save->option_mask32 = option_mask32;
    7885    save->die_sleep = die_sleep;
    79     save->saved = 1;
    80 }
    81 
    82 void FAST_FUNC restore_nofork_data(struct nofork_save_area *save)
     86}
     87static void restore_nofork_data(struct nofork_save_area *save)
    8388{
    8489    memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
     
    8994}
    9095
    91 int FAST_FUNC run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv)
     96int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
    9297{
    9398    int rc, argc;
     99    struct nofork_save_area old;
     100
     101    save_nofork_data(&old);
    94102
    95103    applet_name = APPLET_NAME(applet_no);
    96104
    97105    xfunc_error_retval = EXIT_FAILURE;
    98 
    99     /* Special flag for xfunc_die(). If xfunc will "die"
    100      * in NOFORK applet, xfunc_die() sees negative
    101      * die_sleep and longjmp here instead. */
    102     die_sleep = -1;
    103106
    104107    /* In case getopt() or getopt32() was already called:
     
    131134        argc++;
    132135
     136    /* Special flag for xfunc_die(). If xfunc will "die"
     137     * in NOFORK applet, xfunc_die() sees negative
     138     * die_sleep and longjmp here instead. */
     139    die_sleep = -1;
     140
    133141    rc = setjmp(die_jmp);
    134142    if (!rc) {
     
    139147        /* Finally we can call NOFORK applet's main() */
    140148        rc = applet_main[applet_no](argc, tmp_argv);
    141 
    142     /* The whole reason behind nofork_save_area is that <applet>_main
    143      * may exit non-locally! For example, in hush Ctrl-Z tries
    144      * (modulo bugs) to dynamically create a child (backgrounded task)
    145      * if it detects that Ctrl-Z was pressed when a NOFORK was running.
    146      * Testcase: interactive "rm -i".
    147      * Don't fool yourself into thinking "and <applet>_main() returns
    148      * quickly here" and removing "useless" nofork_save_area code. */
    149 
    150149    } else { /* xfunc died in NOFORK applet */
    151150        /* in case they meant to return 0... */
     
    155154
    156155    /* Restoring some globals */
    157     restore_nofork_data(old);
     156    restore_nofork_data(&old);
    158157
    159158    /* Other globals can be simply reset to defaults */
     
    166165    return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
    167166}
    168 
    169 int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
    170 {
    171     struct nofork_save_area old;
    172 
    173     /* Saving globals */
    174     save_nofork_data(&old);
    175     return run_nofork_applet_prime(&old, applet_no, argv);
    176 }
    177167#endif /* FEATURE_PREFER_APPLETS */
    178168
     
    184174
    185175    if (a >= 0 && (APPLET_IS_NOFORK(a)
    186 #if BB_MMU
     176# if BB_MMU
    187177            || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */
    188 #endif
     178# endif
    189179    )) {
    190 #if BB_MMU
     180# if BB_MMU
    191181        if (APPLET_IS_NOFORK(a))
    192 #endif
     182# endif
    193183        {
    194184            return run_nofork_applet(a, argv);
    195185        }
    196 #if BB_MMU
     186# if BB_MMU
    197187        /* MMU only */
    198188        /* a->noexec is true */
     
    203193        xfunc_error_retval = EXIT_FAILURE;
    204194        run_applet_no_and_exit(a, argv);
    205 #endif
     195# endif
    206196    }
    207197#endif /* FEATURE_PREFER_APPLETS */
     
    264254        if (fork_or_rexec(argv))
    265255            exit(EXIT_SUCCESS); /* parent */
    266         /* if daemonizing, make sure we detach from stdio & ctty */
     256        /* if daemonizing, detach from stdio & ctty */
    267257        setsid();
    268258        dup2(fd, 0);
    269259        dup2(fd, 1);
    270260        dup2(fd, 2);
     261        if (flags & DAEMON_DOUBLE_FORK) {
     262            /* On Linux, session leader can acquire ctty
     263             * unknowingly, by opening a tty.
     264             * Prevent this: stop being a session leader.
     265             */
     266            if (fork_or_rexec(argv))
     267                exit(EXIT_SUCCESS); /* parent */
     268        }
    271269    }
    272270    while (fd > 2) {
  • branches/3.2/mindi-busybox/libbb/xatonum_template.c

    r2725 r3232  
    6060
    6161    /* Note: trailing space is an error.
    62        It would be easy enough to allow though if desired. */
     62     * It would be easy enough to allow though if desired. */
    6363    if (*e)
    6464        goto inval;
  • branches/3.2/mindi-busybox/libbb/xconnect.c

    r2725 r3232  
    135135}
    136136
    137 void FAST_FUNC set_nport(len_and_sockaddr *lsa, unsigned port)
    138 {
    139 #if ENABLE_FEATURE_IPV6
    140     if (lsa->u.sa.sa_family == AF_INET6) {
    141         lsa->u.sin6.sin6_port = port;
     137void FAST_FUNC set_nport(struct sockaddr *sa, unsigned port)
     138{
     139#if ENABLE_FEATURE_IPV6
     140    if (sa->sa_family == AF_INET6) {
     141        struct sockaddr_in6 *sin6 = (void*) sa;
     142        sin6->sin6_port = port;
    142143        return;
    143144    }
    144145#endif
    145     if (lsa->u.sa.sa_family == AF_INET) {
    146         lsa->u.sin.sin_port = port;
     146    if (sa->sa_family == AF_INET) {
     147        struct sockaddr_in *sin = (void*) sa;
     148        sin->sin_port = port;
    147149        return;
    148150    }
     
    256258    memset(&hint, 0 , sizeof(hint));
    257259    hint.ai_family = af;
    258     /* Needed. Or else we will get each address thrice (or more)
     260    /* Need SOCK_STREAM, or else we get each address thrice (or more)
    259261     * for each possible socket type (tcp,udp,raw...): */
    260262    hint.ai_socktype = SOCK_STREAM;
     
    284286
    285287 set_port:
    286     set_nport(r, htons(port));
     288    set_nport(&r->u.sa, htons(port));
    287289 ret:
    288     freeaddrinfo(result);
     290    if (result)
     291        freeaddrinfo(result);
    289292    return r;
    290293}
     
    320323}
    321324
    322 #undef xsocket_type
    323 int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, IF_FEATURE_IPV6(int family,) int sock_type)
    324 {
    325     IF_NOT_FEATURE_IPV6(enum { family = AF_INET };)
     325int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, int family, int sock_type)
     326{
    326327    len_and_sockaddr *lsa;
    327328    int fd;
    328329    int len;
    329330
    330 #if ENABLE_FEATURE_IPV6
    331331    if (family == AF_UNSPEC) {
     332#if ENABLE_FEATURE_IPV6
    332333        fd = socket(AF_INET6, sock_type, 0);
    333334        if (fd >= 0) {
     
    335336            goto done;
    336337        }
     338#endif
    337339        family = AF_INET;
    338340    }
    339 #endif
     341
    340342    fd = xsocket(family, sock_type, 0);
     343
    341344    len = sizeof(struct sockaddr_in);
     345    if (family == AF_UNIX)
     346        len = sizeof(struct sockaddr_un);
    342347#if ENABLE_FEATURE_IPV6
    343348    if (family == AF_INET6) {
     
    355360int FAST_FUNC xsocket_stream(len_and_sockaddr **lsap)
    356361{
    357     return xsocket_type(lsap, IF_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM);
     362    return xsocket_type(lsap, AF_UNSPEC, SOCK_STREAM);
    358363}
    359364
     
    368373        fd = xsocket(lsa->u.sa.sa_family, sock_type, 0);
    369374    } else {
    370         fd = xsocket_type(&lsa, IF_FEATURE_IPV6(AF_UNSPEC,) sock_type);
    371         set_nport(lsa, htons(port));
     375        fd = xsocket_type(&lsa, AF_UNSPEC, sock_type);
     376        set_nport(&lsa->u.sa, htons(port));
    372377    }
    373378    setsockopt_reuseaddr(fd);
  • branches/3.2/mindi-busybox/libbb/xfuncs.c

    r2725 r3232  
    2626
    2727/* Turn on nonblocking I/O on a fd */
    28 int FAST_FUNC ndelay_on(int fd)
    29 {
    30     return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
    31 }
    32 
    33 int FAST_FUNC ndelay_off(int fd)
    34 {
    35     return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
    36 }
    37 
    38 int FAST_FUNC close_on_exec_on(int fd)
    39 {
    40     return fcntl(fd, F_SETFD, FD_CLOEXEC);
     28void FAST_FUNC ndelay_on(int fd)
     29{
     30    int flags = fcntl(fd, F_GETFL);
     31    if (flags & O_NONBLOCK)
     32        return;
     33    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
     34}
     35
     36void FAST_FUNC ndelay_off(int fd)
     37{
     38    int flags = fcntl(fd, F_GETFL);
     39    if (!(flags & O_NONBLOCK))
     40        return;
     41    fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
     42}
     43
     44void FAST_FUNC close_on_exec_on(int fd)
     45{
     46    fcntl(fd, F_SETFD, FD_CLOEXEC);
    4147}
    4248
     
    235241        if (s) {
    236242            value = atoi(s);
    237             /* If LINES/COLUMNS are set, pretent that there is
     243            /* If LINES/COLUMNS are set, pretend that there is
    238244             * no error getting w/h, this prevents some ugly
    239245             * cursor tricks by our callers */
  • branches/3.2/mindi-busybox/libbb/xfuncs_printf.c

    r2725 r3232  
    356356{
    357357    if (chdir(path))
    358         bb_perror_msg_and_die("chdir(%s)", path);
     358        bb_perror_msg_and_die("can't change directory to '%s'", path);
    359359}
    360360
     
    362362{
    363363    if (chroot(path))
    364         bb_perror_msg_and_die("can't change root directory to %s", path);
     364        bb_perror_msg_and_die("can't change root directory to '%s'", path);
     365    xchdir("/");
    365366}
    366367
Note: See TracChangeset for help on using the changeset viewer.