Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/libbb


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
13 added
14 deleted
54 edited
1 copied

Legend:

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

    r3232 r3621  
    1717config MD5_SMALL
    1818    int "MD5: Trade bytes for speed (0:fast, 3:slow)"
    19     default 1
     19    default 1  # all "fast or small" options default to small
    2020    range 0 3
    2121    help
     
    3131config SHA3_SMALL
    3232    int "SHA3: Trade bytes for speed (0:fast, 1:slow)"
    33     default 1
     33    default 1  # all "fast or small" options default to small
    3434    range 0 1
    3535    help
     
    4141config FEATURE_FAST_TOP
    4242    bool "Faster /proc scanning code (+100 bytes)"
    43     default y
     43    default n  # all "fast or small" options default to small
    4444    help
    4545      This option makes top (and ps) ~20% faster (or 20% less CPU hungry),
     
    115115    bool "Reverse history search"
    116116    default y
    117     depends on FEATURE_EDITING_SAVEHISTORY
     117    depends on FEATURE_EDITING
    118118    help
    119119      Enable readline-like Ctrl-R combination for reverse history search.
     
    209209config MONOTONIC_SYSCALL
    210210    bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
    211     default n
     211    default y
    212212    select PLATFORM_LINUX
    213213    help
  • branches/3.3/mindi-busybox/libbb/Kbuild.src

    r3232 r3621  
    2828lib-y += copyfd.o
    2929lib-y += crc32.o
    30 lib-y += create_icmp6_socket.o
    31 lib-y += create_icmp_socket.o
    3230lib-y += default_error_retval.o
    3331lib-y += device_open.o
    3432lib-y += dump.o
    35 lib-y += execable.o
     33lib-y += executable.o
    3634lib-y += fclose_nonstdin.o
    3735lib-y += fflush_stdout_and_exit.o
     
    4947lib-y += human_readable.o
    5048lib-y += inet_common.o
    51 lib-y += info_msg.o
    5249lib-y += inode_hash.o
    5350lib-y += isdirectory.o
     
    9592lib-y += str_tolower.o
    9693lib-y += strrstr.o
     94lib-y += sysconf.o
    9795lib-y += time.o
    9896lib-y += trim.o
     
    144142lib-$(CONFIG_DELUSER) += update_passwd.o
    145143
     144lib-$(CONFIG_FTPD) += correct_password.o
    146145lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o
    147146lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o
    148147lib-$(CONFIG_CRYPTPW) += pw_encrypt.o
    149 lib-$(CONFIG_SULOGIN) += pw_encrypt.o
     148lib-$(CONFIG_MKPASSWD) += pw_encrypt.o
     149lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o
    150150lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o
    151151lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o
    152152lib-$(CONFIG_LOGIN) += pw_encrypt.o correct_password.o
    153153lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o
     154lib-$(CONFIG_FEATURE_FTP_AUTHENTICATION) += pw_encrypt.o
    154155
    155156lib-$(CONFIG_DF) += find_mount_point.o
     
    188189lib-$(CONFIG_DEVFSD) += xregcomp.o
    189190lib-$(CONFIG_FEATURE_FIND_REGEX) += xregcomp.o
     191
     192# Add the experimental logging functionality, only used by zcip
     193lib-$(CONFIG_ZCIP) += logenv.o
  • branches/3.3/mindi-busybox/libbb/appletlib.c

    r3232 r3621  
    3030
    3131#if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
    32         || defined(__APPLE__) \
     32    || defined(__APPLE__) \
    3333    )
    3434# include <malloc.h> /* for mallopt */
     
    5353#include "usage_compressed.h"
    5454
     55static void run_applet_and_exit(const char *name, char **argv) NORETURN;
    5556
    5657#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
     
    131132            full_write2_str(" ");
    132133            full_write2_str(p);
    133             full_write2_str("\n\n");
     134            full_write2_str("\n");
    134135        }
    135136        if (ENABLE_FEATURE_CLEAN_UP)
     
    140141}
    141142
    142 #if NUM_APPLETS > 8
    143 static int applet_name_compare(const void *name, const void *idx)
    144 {
    145     int i = (int)(ptrdiff_t)idx - 1;
    146     return strcmp(name, APPLET_NAME(i));
    147 }
    148 #endif
    149143int FAST_FUNC find_applet_by_name(const char *name)
    150144{
    151 #if NUM_APPLETS > 8
    152     /* Do a binary search to find the applet entry given the name. */
     145    unsigned i, max;
     146    int j;
    153147    const char *p;
    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;
     148
     149/* The commented-out word-at-a-time code is ~40% faster, but +160 bytes.
     150 * "Faster" here saves ~0.5 microsecond of real time - not worth it.
     151 */
     152#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/
     153    uint32_t n32;
     154
     155    /* Handle all names < 2 chars long early */
     156    if (name[0] == '\0')
     157        return -1; /* "" is not a valid applet name */
     158    if (name[1] == '\0') {
     159        if (!ENABLE_TEST)
     160            return -1; /* 1-char name is not valid */
     161        if (name[0] != ']')
     162            return -1; /* 1-char name which isn't "[" is not valid */
     163        /* applet "[" is always applet #0: */
     164        return 0;
     165    }
     166#endif
     167
     168    p = applet_names;
     169    i = 0;
     170#if KNOWN_APPNAME_OFFSETS <= 0
     171    max = NUM_APPLETS;
    160172#else
    161     /* A version which does not pull in bsearch */
    162     int i = 0;
    163     const char *p = applet_names;
    164     while (i < NUM_APPLETS) {
    165         if (strcmp(name, p) == 0)
     173    max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS;
     174    for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) {
     175        const char *pp = applet_names + applet_nameofs[j];
     176        if (strcmp(name, pp) >= 0) {
     177            //bb_error_msg("name:'%s' >= pp:'%s'", name, pp);
     178            p = pp;
     179            i = max - NUM_APPLETS;
     180            break;
     181        }
     182        max -= NUM_APPLETS;
     183    }
     184    max /= (unsigned)KNOWN_APPNAME_OFFSETS;
     185    i /= (unsigned)KNOWN_APPNAME_OFFSETS;
     186    //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max);
     187#endif
     188
     189    /* Open-coded linear search without strcmp/strlen calls for speed */
     190
     191#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/
     192    /* skip "[\0" name, it's surely not it */
     193    if (ENABLE_TEST && LONE_CHAR(p, '['))
     194        i++, p += 2;
     195    /* All remaining applet names in p[] are at least 2 chars long */
     196    /* name[] is also at least 2 chars long */
     197
     198    n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16);
     199    while (i < max) {
     200        uint32_t p32;
     201        char ch;
     202
     203        /* Quickly check match of the first 3 bytes */
     204        move_from_unaligned32(p32, p);
     205        p += 3;
     206        if ((p32 & 0x00ffffff) != n32) {
     207            /* Most likely case: 3 first bytes do not match */
     208            i++;
     209            if ((p32 & 0x00ff0000) == '\0')
     210                continue; // p[2] was NUL
     211            p++;
     212            if ((p32 & 0xff000000) == '\0')
     213                continue; // p[3] was NUL
     214            /* p[0..3] aren't matching and none is NUL, check the rest */
     215            while (*p++ != '\0')
     216                continue;
     217            continue;
     218        }
     219
     220        /* Unlikely branch: first 3 bytes ([0..2]) match */
     221        if ((p32 & 0x00ff0000) == '\0') {
     222            /* name is 2-byte long, it is full match */
     223            //bb_error_msg("found:'%s' i:%u", name, i);
    166224            return i;
    167         p += strlen(p) + 1;
     225        }
     226        /* Check remaining bytes [3..NUL] */
     227        ch = (p32 >> 24);
     228        j = 3;
     229        while (ch == name[j]) {
     230            if (ch == '\0') {
     231                //bb_error_msg("found:'%s' i:%u", name, i);
     232                return i;
     233            }
     234            ch = *++p;
     235            j++;
     236        }
     237        /* Not a match. Skip it, including NUL */
     238        while (ch != '\0')
     239            ch = *++p;
     240        p++;
     241        i++;
     242    }
     243    return -1;
     244#else
     245    while (i < max) {
     246        char ch;
     247        j = 0;
     248        /* Do we see "name\0" in applet_names[p] position? */
     249        while ((ch = *p) == name[j]) {
     250            if (ch == '\0') {
     251                //bb_error_msg("found:'%s' i:%u", name, i);
     252                return i; /* yes */
     253            }
     254            p++;
     255            j++;
     256        }
     257        /* No.
     258         * p => 1st non-matching char in applet_names[],
     259         * skip to and including NUL.
     260         */
     261        while (ch != '\0')
     262            ch = *++p;
     263        p++;
    168264        i++;
    169265    }
     
    185281    applet_name = applet;
    186282
    187     /* Set locale for everybody except 'init' */
    188     if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
     283    if (ENABLE_LOCALE_SUPPORT)
    189284        setlocale(LC_ALL, "");
    190285
     
    195290     && !argv[2]
    196291     && strcmp(argv[1], "--help") == 0
    197      && strncmp(applet, "busybox", 7) != 0
     292     && !is_prefixed_with(applet, "busybox")
    198293    ) {
    199294        /* Special case. POSIX says "test --help"
     
    439534                    }
    440535                    *e = ':'; /* get_uidgid needs USER:GROUP syntax */
    441                     if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) {
     536                    if (get_uidgid(&sct->m_ugid, s) == 0) {
    442537                        errmsg = "unknown user/group";
    443538                        goto pe_label;
     
    459554            goto pe_label;
    460555        }
    461 
    462556    } /* while (1) */
    463557
     
    586680    int (*lf)(const char *, const char *);
    587681    char *fpc;
     682        const char *appname = applet_names;
    588683    unsigned i;
    589684    int rc;
     
    596691        fpc = concat_path_file(
    597692                custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)],
    598                 APPLET_NAME(i));
     693                appname);
    599694        // debug: bb_error_msg("%slinking %s to busybox",
    600695        //      use_symbolic_links ? "sym" : "", fpc);
     
    604699        }
    605700        free(fpc);
    606     }
    607 }
    608 # else
    609 #  define install_links(x,y,z) ((void)0)
     701        while (*appname++ != '\0')
     702            continue;
     703    }
     704}
     705# elif ENABLE_BUSYBOX
     706static void install_links(const char *busybox UNUSED_PARAM,
     707        int use_symbolic_links UNUSED_PARAM,
     708        char *custom_install_dir UNUSED_PARAM)
     709{
     710}
    610711# endif
    611712
     713# if ENABLE_BUSYBOX
    612714/* If we were called as "busybox..." */
    613715static int busybox_main(char **argv)
     
    622724        if (ENABLE_FEATURE_AUTOWIDTH) {
    623725            /* Obtain the terminal width */
    624             get_terminal_width_height(0, &output_width, NULL);
     726            output_width = get_terminal_width(2);
    625727        }
    626728
     
    629731        full_write2_str(" multi-call binary.\n"); /* reuse */
    630732        full_write2_str(
    631             "BusyBox is copyrighted by many authors between 1998-2012.\n"
     733            "BusyBox is copyrighted by many authors between 1998-2015.\n"
    632734            "Licensed under GPLv2. See source distribution for detailed\n"
    633735            "copyright notices.\n"
     
    640742            "   or: function [arguments]...\n"
    641743            "\n"
     744            IF_NOT_FEATURE_SH_STANDALONE(
    642745            "\tBusyBox is a multi-call binary that combines many common Unix\n"
    643746            "\tutilities into a single executable.  Most people will create a\n"
    644747            "\tlink to busybox for each function they wish to use and BusyBox\n"
    645748            "\twill act like whatever it was invoked as.\n"
     749            )
     750            IF_FEATURE_SH_STANDALONE(
     751            "\tBusyBox is a multi-call binary that combines many common Unix\n"
     752            "\tutilities into a single executable.  The shell in this build\n"
     753            "\tis configured to run built-in utilities without $PATH search.\n"
     754            "\tYou don't need to install a link to busybox for each utility.\n"
     755            "\tTo run external program, use full path (/sbin/ip instead of ip).\n"
     756            )
    646757            "\n"
    647758            "Currently defined functions:\n"
     
    671782    }
    672783
    673     if (strncmp(argv[1], "--list", 6) == 0) {
     784    if (is_prefixed_with(argv[1], "--list")) {
    674785        unsigned i = 0;
    675786        const char *a = applet_names;
    676787        dup2(1, 2);
    677788        while (*a) {
    678 # if ENABLE_FEATURE_INSTALLER
     789#  if ENABLE_FEATURE_INSTALLER
    679790            if (argv[1][6]) /* --list-full? */
    680791                full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1);
    681 # endif
     792#  endif
    682793            full_write2_str(a);
    683794            full_write2_str("\n");
    684795            i++;
    685             a += strlen(a) + 1;
     796            while (*a++ != '\0')
     797                continue;
    686798        }
    687799        return 0;
     
    727839    applet_name = bb_get_last_path_component_nostrip(argv[0]);
    728840    run_applet_and_exit(applet_name, argv);
    729 
    730     /*bb_error_msg_and_die("applet not found"); - sucks in printf */
    731     full_write2_str(applet_name);
    732     full_write2_str(": applet not found\n");
    733     xfunc_die();
    734 }
     841}
     842# endif
    735843
    736844void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv)
     
    743851    /* Reinit some shared global data */
    744852    xfunc_error_retval = EXIT_FAILURE;
    745 
    746     applet_name = APPLET_NAME(applet_no);
    747     if (argc == 2 && strcmp(argv[1], "--help") == 0) {
    748         /* Special case. POSIX says "test --help"
    749          * should be no different from e.g. "test --foo".  */
    750 //TODO: just compare applet_no with APPLET_NO_test
    751         if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) {
    752             /* If you want "foo --help" to return 0: */
    753             /*xfunc_error_retval = 0;*/
     853    applet_name = bb_get_last_path_component_nostrip(argv[0]);
     854
     855    /* Special case. POSIX says "test --help"
     856     * should be no different from e.g. "test --foo".
     857     * Thus for "test", we skip --help check.
     858     * "true" and "false" are also special.
     859     */
     860    if (1
     861#if defined APPLET_NO_test
     862     && applet_no != APPLET_NO_test
     863#endif
     864#if defined APPLET_NO_true
     865     && applet_no != APPLET_NO_true
     866#endif
     867#if defined APPLET_NO_false
     868     && applet_no != APPLET_NO_false
     869#endif
     870    ) {
     871        if (argc == 2 && strcmp(argv[1], "--help") == 0) {
     872            /* Make "foo --help" exit with 0: */
     873            xfunc_error_retval = 0;
    754874            bb_show_usage();
    755875        }
     
    760880}
    761881
    762 void FAST_FUNC run_applet_and_exit(const char *name, char **argv)
    763 {
    764     int applet = find_applet_by_name(name);
     882static NORETURN void run_applet_and_exit(const char *name, char **argv)
     883{
     884    int applet;
     885
     886# if ENABLE_BUSYBOX
     887    if (is_prefixed_with(name, "busybox"))
     888        exit(busybox_main(argv));
     889# endif
     890    /* find_applet_by_name() search is more expensive, so goes second */
     891    applet = find_applet_by_name(name);
    765892    if (applet >= 0)
    766893        run_applet_no_and_exit(applet, argv);
    767     if (strncmp(name, "busybox", 7) == 0)
    768         exit(busybox_main(argv));
     894
     895    /*bb_error_msg_and_die("applet not found"); - links in printf */
     896    full_write2_str(applet_name);
     897    full_write2_str(": applet not found\n");
     898    /* POSIX: "If a command is not found, the exit status shall be 127" */
     899    exit(127);
    769900}
    770901
     
    779910#endif
    780911{
     912#if 0
     913    /* TODO: find a use for a block of memory between end of .bss
     914     * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes"
     915     * - more than 2k of wasted memory (in this particular build)
     916     * *per each running process*!
     917     * (If your linker does not generate "_end" name, weak attribute
     918     * makes &_end == NULL, end_len == 0 here.)
     919     */
     920    extern char _end[] __attribute__((weak));
     921    unsigned end_len = (-(int)_end) & 0xfff;
     922    printf("_end:%p %u bytes\n", &_end, end_len);
     923#endif
     924
    781925    /* Tweak malloc for reduced memory consumption */
    782926#ifdef M_TRIM_THRESHOLD
     
    804948#if defined(SINGLE_APPLET_MAIN)
    805949    /* Only one applet is selected in .config */
    806     if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) {
     950    if (argv[1] && is_prefixed_with(argv[0], "busybox")) {
    807951        /* "busybox <applet> <params>" should still work as expected */
    808952        argv++;
     
    814958    lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
    815959
     960#if !ENABLE_BUSYBOX
     961    if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox"))
     962        argv++;
     963#endif
    816964    applet_name = argv[0];
    817965    if (applet_name[0] == '-')
     
    822970
    823971    run_applet_and_exit(applet_name, argv);
    824 
    825     /*bb_error_msg_and_die("applet not found"); - sucks in printf */
    826     full_write2_str(applet_name);
    827     full_write2_str(": applet not found\n");
    828     xfunc_die();
    829 #endif
    830 }
     972#endif
     973}
  • branches/3.3/mindi-busybox/libbb/bb_askpass.c

    r3232 r3621  
    22/*
    33 * Ask for a password
    4  * I use a static buffer in this function.  Plan accordingly.
    54 *
    65 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
     
    2423    /* Was static char[BIGNUM] */
    2524    enum { sizeof_passwd = 128 };
    26     static char *passwd;
    2725
     26    char *passwd;
    2827    char *ret;
    2928    int i;
     
    3130    struct termios tio, oldtio;
    3231
     32    tcflush(fd, TCIFLUSH);
     33    /* Was buggy: was printing prompt *before* flushing input,
     34     * which was upsetting "expect" based scripts of some users.
     35     */
    3336    fputs(prompt, stdout);
    3437    fflush_all();
    35     tcflush(fd, TCIFLUSH);
    3638
    3739    tcgetattr(fd, &oldtio);
     
    6062    }
    6163
    62     if (!passwd)
    63         passwd = xmalloc(sizeof_passwd);
     64    passwd = auto_string(xmalloc(sizeof_passwd));
    6465    ret = passwd;
    6566    i = 0;
    6667    while (1) {
    6768        int r = read(fd, &ret[i], 1);
    68         if (r < 0) {
     69        if ((i == 0 && r == 0) /* EOF (^D) with no password */
     70         || r < 0
     71        ) {
    6972            /* read is interrupted by timeout or ^C */
    7073            ret = NULL;
  • branches/3.3/mindi-busybox/libbb/change_identity.c

    r2725 r3621  
    3434void FAST_FUNC change_identity(const struct passwd *pw)
    3535{
    36     if (initgroups(pw->pw_name, pw->pw_gid) == -1)
     36    int res;
     37
     38    res = initgroups(pw->pw_name, pw->pw_gid);
     39    endgrent(); /* helps to close a fd used internally by libc */
     40
     41    if (res != 0) {
     42        /*
     43         * If initgroups() fails because a system call is unimplemented
     44         * then we are running on a Linux kernel compiled without multiuser
     45         * support (CONFIG_MULTIUSER is not defined).
     46         *
     47         * If we are running without multiuser support *and* the target uid
     48         * already matches the current uid then we can skip the change of
     49         * identity.
     50         */
     51        if (errno == ENOSYS && pw->pw_uid == getuid()) {
     52            return;
     53        }
     54
    3755        bb_perror_msg_and_die("can't set groups");
    38     endgrent(); /* helps to close a fd used internally by libc */
     56    }
     57
    3958    xsetgid(pw->pw_gid);
    4059    xsetuid(pw->pw_uid);
  • branches/3.3/mindi-busybox/libbb/compare_string_array.c

    r2725 r3621  
    55
    66#include "libbb.h"
     7
     8/*
     9 * Return NULL if string is not prefixed with key. Return pointer to the
     10 * first character in string after the prefix key. If key is an empty string,
     11 * return pointer to the beginning of string.
     12 */
     13char* FAST_FUNC is_prefixed_with(const char *string, const char *key)
     14{
     15#if 0   /* Two passes over key - probably slower */
     16    int len = strlen(key);
     17    if (strncmp(string, key, len) == 0)
     18        return string + len;
     19    return NULL;
     20#else   /* Open-coded */
     21    while (*key != '\0') {
     22        if (*key != *string)
     23            return NULL;
     24        key++;
     25        string++;
     26    }
     27    return (char*)string;
     28#endif
     29}
     30
     31/*
     32 * Return NULL if string is not suffixed with key. Return pointer to the
     33 * beginning of prefix key in string. If key is an empty string return pointer
     34 * to the end of string.
     35 */
     36char* FAST_FUNC is_suffixed_with(const char *string, const char *key)
     37{
     38    size_t key_len = strlen(key);
     39    ssize_t len_diff = strlen(string) - key_len;
     40
     41    if (len_diff >= 0) {
     42        string += len_diff;
     43        if (strcmp(string, key) == 0) {
     44            return (char*)string;
     45        }
     46    }
     47
     48    return NULL;
     49}
    750
    851/* returns the array index of the string */
     
    4083{
    4184    int i;
    42     int len = strlen(key);
    43     if (len) {
     85    if (key[0]) {
    4486        for (i = 0; string_array[i] != 0; i++) {
    45             if (strncmp(string_array[i], key, len) == 0) {
     87            if (is_prefixed_with(string_array[i], key)) {
    4688                return i;
    4789            }
     
    94136}
    95137#endif
     138
     139#if ENABLE_UNIT_TEST
     140
     141BBUNIT_DEFINE_TEST(is_prefixed_with)
     142{
     143    BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo"));
     144    BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo "));
     145    BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo"));
     146    BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", ""));
     147    BBUNIT_ASSERT_STREQ("", is_prefixed_with("", ""));
     148
     149    BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo"));
     150    BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar"));
     151    BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo"));
     152
     153    BBUNIT_ENDTEST;
     154}
     155
     156BBUNIT_DEFINE_TEST(is_suffixed_with)
     157{
     158    BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar"));
     159    BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo"));
     160    BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", ""));
     161    BBUNIT_ASSERT_STREQ("", is_suffixed_with("", ""));
     162    BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo"));
     163
     164    BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo"));
     165    BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar"));
     166    BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo"));
     167
     168    BBUNIT_ENDTEST;
     169}
     170
     171#endif /* ENABLE_UNIT_TEST */
  • branches/3.3/mindi-busybox/libbb/copy_file.c

    r3232 r3621  
    6565        return -1; /* error */
    6666    }
     67#if ENABLE_FEATURE_CP_LONG_OPTIONS
     68    if (flags & FILEUTILS_RMDEST)
     69        if (flags & FILEUTILS_VERBOSE)
     70            printf("removed '%s'\n", dest);
     71#endif
    6772    return 1; /* ok (to try again) */
    6873}
     
    211216    }
    212217
     218    if (dest_exists) {
     219        if (flags & FILEUTILS_UPDATE) {
     220            if (source_stat.st_mtime <= dest_stat.st_mtime) {
     221                return 0; /* source file must be newer */
     222            }
     223        }
     224#if ENABLE_FEATURE_CP_LONG_OPTIONS
     225        if (flags & FILEUTILS_RMDEST) {
     226            ovr = ask_and_unlink(dest, flags);
     227            if (ovr <= 0)
     228                return ovr;
     229            dest_exists = 0;
     230        }
     231#endif
     232    }
     233
    213234    if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) {
    214235        int (*lf)(const char *oldpath, const char *newpath);
     
    390411    }
    391412
     413    if (flags & FILEUTILS_VERBOSE) {
     414        printf("'%s' -> '%s'\n", source, dest);
     415    }
     416
    392417    return retval;
    393418}
  • branches/3.3/mindi-busybox/libbb/copyfd.c

    r2725 r3621  
    99
    1010#include "libbb.h"
     11#if ENABLE_FEATURE_USE_SENDFILE
     12# include <sys/sendfile.h>
     13#else
     14# define sendfile(a,b,c,d) (-1)
     15#endif
     16
     17/*
     18 * We were using 0x7fff0000 as sendfile chunk size, but it
     19 * was seen to cause largish delays when user tries to ^C a file copy.
     20 * Let's use a saner size.
     21 * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB),
     22 * or else "copy to eof" code will use neddlesly short reads.
     23 */
     24#define SENDFILE_BIGBUF (16*1024*1024)
    1125
    1226/* Used by NOFORK applets (e.g. cat) - must not use xmalloc.
     
    1933    off_t total = 0;
    2034    bool continue_on_write_error = 0;
    21 #if CONFIG_FEATURE_COPYBUF_KB <= 4
     35    ssize_t sendfile_sz;
     36#if CONFIG_FEATURE_COPYBUF_KB > 4
     37    char *buffer = buffer; /* for compiler */
     38    int buffer_size = 0;
     39#else
    2240    char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024];
    2341    enum { buffer_size = sizeof(buffer) };
    24 #else
    25     char *buffer;
    26     int buffer_size;
    2742#endif
    2843
     
    3247    }
    3348
    34 #if CONFIG_FEATURE_COPYBUF_KB > 4
    35     if (size > 0 && size <= 4 * 1024)
    36         goto use_small_buf;
    37     /* We want page-aligned buffer, just in case kernel is clever
    38      * and can do page-aligned io more efficiently */
    39     buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,
    40             PROT_READ | PROT_WRITE,
    41             MAP_PRIVATE | MAP_ANON,
    42             /* ignored: */ -1, 0);
    43     buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;
    44     if (buffer == MAP_FAILED) {
    45  use_small_buf:
    46         buffer = alloca(4 * 1024);
    47         buffer_size = 4 * 1024;
    48     }
    49 #endif
    50 
    5149    if (src_fd < 0)
    5250        goto out;
    5351
     52    sendfile_sz = !ENABLE_FEATURE_USE_SENDFILE
     53        ? 0
     54        : SENDFILE_BIGBUF;
    5455    if (!size) {
    55         size = buffer_size;
     56        size = SENDFILE_BIGBUF;
    5657        status = 1; /* copy until eof */
    5758    }
     
    6061        ssize_t rd;
    6162
    62         rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size);
    63 
     63        if (sendfile_sz) {
     64            rd = sendfile(dst_fd, src_fd, NULL,
     65                size > sendfile_sz ? sendfile_sz : size);
     66            if (rd >= 0)
     67                goto read_ok;
     68            sendfile_sz = 0; /* do not try sendfile anymore */
     69        }
     70#if CONFIG_FEATURE_COPYBUF_KB > 4
     71        if (buffer_size == 0) {
     72            if (size > 0 && size <= 4 * 1024)
     73                goto use_small_buf;
     74            /* We want page-aligned buffer, just in case kernel is clever
     75             * and can do page-aligned io more efficiently */
     76            buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,
     77                    PROT_READ | PROT_WRITE,
     78                    MAP_PRIVATE | MAP_ANON,
     79                    /* ignored: */ -1, 0);
     80            buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;
     81            if (buffer == MAP_FAILED) {
     82 use_small_buf:
     83                buffer = alloca(4 * 1024);
     84                buffer_size = 4 * 1024;
     85            }
     86        }
     87#endif
     88        rd = safe_read(src_fd, buffer,
     89            size > buffer_size ? buffer_size : size);
     90        if (rd < 0) {
     91            bb_perror_msg(bb_msg_read_error);
     92            break;
     93        }
     94 read_ok:
    6495        if (!rd) { /* eof - all done */
    6596            status = 0;
    6697            break;
    6798        }
    68         if (rd < 0) {
    69             bb_perror_msg(bb_msg_read_error);
    70             break;
    71         }
    7299        /* dst_fd == -1 is a fake, else... */
    73         if (dst_fd >= 0) {
     100        if (dst_fd >= 0 && !sendfile_sz) {
    74101            ssize_t wr = full_write(dst_fd, buffer, rd);
    75102            if (wr < rd) {
     
    93120 out:
    94121
    95 #if CONFIG_FEATURE_COPYBUF_KB > 4
    96     if (buffer_size != 4 * 1024)
     122    if (buffer_size > 4 * 1024)
    97123        munmap(buffer, buffer_size);
    98 #endif
    99124    return status ? -1 : total;
    100125}
  • branches/3.3/mindi-busybox/libbb/correct_password.c

    r3232 r3621  
    3131#include "libbb.h"
    3232
    33 /* Ask the user for a password.
    34  * Return 1 if the user gives the correct password for entry PW,
    35  * 0 if not.  Return 1 without asking if PW has an empty password.
    36  *
    37  * NULL pw means "just fake it for login with bad username" */
     33#define SHADOW_BUFSIZE 256
    3834
    39 int FAST_FUNC correct_password(const struct passwd *pw)
     35/* Retrieve encrypted password string for pw.
     36 * If pw == NULL, return a string which fails password check against any
     37 * password.
     38 */
     39#if !ENABLE_FEATURE_SHADOWPASSWDS
     40#define get_passwd(pw, buffer) get_passwd(pw)
     41#endif
     42static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZE])
    4043{
    41     char *unencrypted, *encrypted;
    42     const char *correct;
    43     int r;
    44     /* fake salt. crypt() can choke otherwise. */
    45     correct = "aa";
    46     if (!pw) {
    47         /* "aa" will never match */
    48         goto fake_it;
    49     }
    50     correct = pw->pw_passwd;
     44    const char *pass;
     45
     46    if (!pw)
     47        return "aa"; /* "aa" will never match */
     48
     49    pass = pw->pw_passwd;
    5150#if ENABLE_FEATURE_SHADOWPASSWDS
    5251    /* Using _r function to avoid pulling in static buffers */
    53     if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) {
     52    if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) {
    5453        struct spwd spw;
    55         char buffer[256];
     54        int r;
    5655        /* getspnam_r may return 0 yet set result to NULL.
    5756         * At least glibc 2.4 does this. Be extra paranoid here. */
    5857        struct spwd *result = NULL;
    59         r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result);
    60         correct = (r || !result) ? "aa" : result->sp_pwdp;
     58        r = getspnam_r(pw->pw_name, &spw, buffer, SHADOW_BUFSIZE, &result);
     59        pass = (r || !result) ? "aa" : result->sp_pwdp;
    6160    }
    6261#endif
     62    return pass;
     63}
    6364
    64     if (!correct[0]) /* empty password field? */
     65/*
     66 * Return 1 if PW has an empty password.
     67 * Return 1 if the user gives the correct password for entry PW,
     68 * 0 if not.
     69 * NULL pw means "just fake it for login with bad username"
     70 */
     71int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext)
     72{
     73    IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];)
     74    char *encrypted;
     75    const char *pw_pass;
     76    int r;
     77
     78    pw_pass = get_passwd(pw, buffer);
     79    if (!pw_pass[0]) { /* empty password field? */
     80        return 1;
     81    }
     82
     83    encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1);
     84    r = (strcmp(encrypted, pw_pass) == 0);
     85    free(encrypted);
     86    return r;
     87}
     88
     89
     90/* Ask the user for a password.
     91 * Return 1 without asking if PW has an empty password.
     92 * Return -1 on EOF, error while reading input, or timeout.
     93 * Return 1 if the user gives the correct password for entry PW,
     94 * 0 if not.
     95 *
     96 * NULL pw means "just fake it for login with bad username"
     97 */
     98int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw,
     99        int timeout, const char *prompt)
     100{
     101    IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];)
     102    char *plaintext;
     103    const char *pw_pass;
     104    int r;
     105
     106    pw_pass = get_passwd(pw, buffer);
     107    if (!pw_pass[0]) /* empty password field? */
    65108        return 1;
    66109
    67  fake_it:
    68     unencrypted = bb_ask_stdin("Password: ");
    69     if (!unencrypted) {
    70         return 0;
     110    plaintext = bb_ask(STDIN_FILENO, timeout, prompt);
     111    if (!plaintext) {
     112        /* EOF (such as ^D) or error (such as ^C) or timeout */
     113        return -1;
    71114    }
    72     encrypted = pw_encrypt(unencrypted, correct, 1);
    73     r = (strcmp(encrypted, correct) == 0);
    74     free(encrypted);
    75     memset(unencrypted, 0, strlen(unencrypted));
     115
     116    r = check_password(pw, plaintext);
     117    nuke_str(plaintext);
    76118    return r;
    77119}
     120
     121int FAST_FUNC ask_and_check_password(const struct passwd *pw)
     122{
     123    return ask_and_check_password_extended(pw, 0, "Password: ");
     124}
  • branches/3.3/mindi-busybox/libbb/dump.c

    r3232 r3621  
    334334        }
    335335    }
    336     if (fseek(stdin, dumper->pub.dump_skip, SEEK_SET)) {
     336    if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) {
    337337        bb_simple_perror_msg_and_die(fname);
    338338    }
  • branches/3.3/mindi-busybox/libbb/fclose_nonstdin.c

    r2725 r3621  
    1919    /* Some more paranoid applets want ferror() check too */
    2020    int r = ferror(f); /* NB: does NOT set errno! */
    21     if (r) errno = EIO; /* so we'll help it */
     21    if (r)
     22        errno = EIO; /* so we'll help it */
    2223    if (f != stdin)
    2324        return (r | fclose(f)); /* fclose does set errno on error */
  • branches/3.3/mindi-busybox/libbb/fflush_stdout_and_exit.c

    r2725 r3621  
    1616void FAST_FUNC fflush_stdout_and_exit(int retval)
    1717{
     18    xfunc_error_retval = retval;
    1819    if (fflush(stdout))
    1920        bb_perror_msg_and_die(bb_msg_standard_output);
    20 
    21     if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) {
    22         /* We are in NOFORK applet. Do not exit() directly,
    23          * but use xfunc_die() */
    24         xfunc_error_retval = retval;
    25         xfunc_die();
    26     }
    27 
    28     exit(retval);
     21    /* In case we are in NOFORK applet. Do not exit() directly,
     22     * but use xfunc_die() */
     23    xfunc_die();
    2924}
  • branches/3.3/mindi-busybox/libbb/getpty.c

    r3232 r3621  
    1717#if ENABLE_FEATURE_DEVPTS
    1818    p = open("/dev/ptmx", O_RDWR);
    19     if (p > 0) {
     19    if (p >= 0) {
    2020        grantpt(p); /* chmod+chown corresponding slave pty */
    2121        unlockpt(p); /* (what does this do?) */
  • branches/3.3/mindi-busybox/libbb/hash_md5_sha.c

    r3232 r3621  
    8585                t = bb_bswap_64(t);
    8686            /* wbuffer is suitably aligned for this */
    87             *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
     87            *(bb__aliased_uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
    8888        }
    8989        ctx->process_block(ctx);
     
    138138    /* Before we start, one word to the strange constants.
    139139       They are defined in RFC 1321 as
    140        T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
     140       T[i] = (int)(2^32 * fabs(sin(i))), i=1..64
    141141     */
    142142    static const uint32_t C_array[] = {
     
    214214            temp += FH(B, C, D);
    215215            break;
    216         case 3:
     216        default: /* case 3 */
    217217            temp += FI(B, C, D);
    218218        }
     
    278278#else  /* MD5_SMALL == 0 or 1 */
    279279
    280     uint32_t A_save = A;
    281     uint32_t B_save = B;
    282     uint32_t C_save = C;
    283     uint32_t D_save = D;
    284280# if MD5_SMALL == 1
    285281    const uint32_t *pc;
     
    426422# endif
    427423    /* Add checksum to the starting values */
    428     ctx->hash[0] = A_save + A;
    429     ctx->hash[1] = B_save + B;
    430     ctx->hash[2] = C_save + C;
    431     ctx->hash[3] = D_save + D;
     424    ctx->hash[0] += A;
     425    ctx->hash[1] += B;
     426    ctx->hash[2] += C;
     427    ctx->hash[3] += D;
    432428#endif
    433429}
     
    884880            t = ctx->total64[0] << 3;
    885881            t = SWAP_BE64(t);
    886             *(uint64_t *) (&ctx->wbuffer[128 - 8]) = t;
     882            *(bb__aliased_uint64_t *) (&ctx->wbuffer[128 - 8]) = t;
    887883            t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61);
    888884            t = SWAP_BE64(t);
    889             *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
     885            *(bb__aliased_uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
    890886        }
    891887        sha512_process_block128(ctx);
     
    927923#endif
    928924
     925#define OPTIMIZE_SHA3_FOR_32 0
     926/*
     927 * SHA3 can be optimized for 32-bit CPUs with bit-slicing:
     928 * every 64-bit word of state[] can be split into two 32-bit words
     929 * by even/odd bits. In this form, all rotations of sha3 round
     930 * are 32-bit - and there are lots of them.
     931 * However, it requires either splitting/combining state words
     932 * before/after sha3 round (code does this now)
     933 * or shuffling bits before xor'ing them into state and in sha3_end.
     934 * Without shuffling, bit-slicing results in -130 bytes of code
     935 * and marginal speedup (but of course it gives wrong result).
     936 * With shuffling it works, but +260 code bytes, and slower.
     937 * Disabled for now:
     938 */
     939#if 0 /* LONG_MAX == 0x7fffffff */
     940# undef OPTIMIZE_SHA3_FOR_32
     941# define OPTIMIZE_SHA3_FOR_32 1
     942#endif
     943
    929944enum {
    930945    SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */
    931946};
     947
     948#if OPTIMIZE_SHA3_FOR_32
     949/* This splits every 64-bit word into a pair of 32-bit words,
     950 * even bits go into first word, odd bits go to second one.
     951 * The conversion is done in-place.
     952 */
     953static void split_halves(uint64_t *state)
     954{
     955    /* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */
     956    uint32_t *s32 = (uint32_t*)state;
     957    uint32_t t, x0, x1;
     958    int i;
     959    for (i = 24; i >= 0; --i) {
     960        x0 = s32[0];
     961        t = (x0 ^ (x0 >> 1)) & 0x22222222; x0 = x0 ^ t ^ (t << 1);
     962        t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0C; x0 = x0 ^ t ^ (t << 2);
     963        t = (x0 ^ (x0 >> 4)) & 0x00F000F0; x0 = x0 ^ t ^ (t << 4);
     964        t = (x0 ^ (x0 >> 8)) & 0x0000FF00; x0 = x0 ^ t ^ (t << 8);
     965        x1 = s32[1];
     966        t = (x1 ^ (x1 >> 1)) & 0x22222222; x1 = x1 ^ t ^ (t << 1);
     967        t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0C; x1 = x1 ^ t ^ (t << 2);
     968        t = (x1 ^ (x1 >> 4)) & 0x00F000F0; x1 = x1 ^ t ^ (t << 4);
     969        t = (x1 ^ (x1 >> 8)) & 0x0000FF00; x1 = x1 ^ t ^ (t << 8);
     970        *s32++ = (x0 & 0x0000FFFF) | (x1 << 16);
     971        *s32++ = (x0 >> 16) | (x1 & 0xFFFF0000);
     972    }
     973}
     974/* The reverse operation */
     975static void combine_halves(uint64_t *state)
     976{
     977    uint32_t *s32 = (uint32_t*)state;
     978    uint32_t t, x0, x1;
     979    int i;
     980    for (i = 24; i >= 0; --i) {
     981        x0 = s32[0];
     982        x1 = s32[1];
     983        t = (x0 & 0x0000FFFF) | (x1 << 16);
     984        x1 = (x0 >> 16) | (x1 & 0xFFFF0000);
     985        x0 = t;
     986        t = (x0 ^ (x0 >> 8)) & 0x0000FF00; x0 = x0 ^ t ^ (t << 8);
     987        t = (x0 ^ (x0 >> 4)) & 0x00F000F0; x0 = x0 ^ t ^ (t << 4);
     988        t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0C; x0 = x0 ^ t ^ (t << 2);
     989        t = (x0 ^ (x0 >> 1)) & 0x22222222; x0 = x0 ^ t ^ (t << 1);
     990        *s32++ = x0;
     991        t = (x1 ^ (x1 >> 8)) & 0x0000FF00; x1 = x1 ^ t ^ (t << 8);
     992        t = (x1 ^ (x1 >> 4)) & 0x00F000F0; x1 = x1 ^ t ^ (t << 4);
     993        t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0C; x1 = x1 ^ t ^ (t << 2);
     994        t = (x1 ^ (x1 >> 1)) & 0x22222222; x1 = x1 ^ t ^ (t << 1);
     995        *s32++ = x1;
     996    }
     997}
     998#endif
    932999
    9331000/*
     
    9381005    enum { NROUNDS = 24 };
    9391006
    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      */
     1007#if OPTIMIZE_SHA3_FOR_32
     1008    /*
     1009    static const uint32_t IOTA_CONST_0[NROUNDS] = {
     1010        0x00000001UL,
     1011        0x00000000UL,
     1012        0x00000000UL,
     1013        0x00000000UL,
     1014        0x00000001UL,
     1015        0x00000001UL,
     1016        0x00000001UL,
     1017        0x00000001UL,
     1018        0x00000000UL,
     1019        0x00000000UL,
     1020        0x00000001UL,
     1021        0x00000000UL,
     1022        0x00000001UL,
     1023        0x00000001UL,
     1024        0x00000001UL,
     1025        0x00000001UL,
     1026        0x00000000UL,
     1027        0x00000000UL,
     1028        0x00000000UL,
     1029        0x00000000UL,
     1030        0x00000001UL,
     1031        0x00000000UL,
     1032        0x00000001UL,
     1033        0x00000000UL,
     1034    };
     1035    ** bits are in lsb: 0101 0000 1111 0100 1111 0001
     1036    */
     1037    uint32_t IOTA_CONST_0bits = (uint32_t)(0x0050f4f1);
     1038    static const uint32_t IOTA_CONST_1[NROUNDS] = {
     1039        0x00000000UL,
     1040        0x00000089UL,
     1041        0x8000008bUL,
     1042        0x80008080UL,
     1043        0x0000008bUL,
     1044        0x00008000UL,
     1045        0x80008088UL,
     1046        0x80000082UL,
     1047        0x0000000bUL,
     1048        0x0000000aUL,
     1049        0x00008082UL,
     1050        0x00008003UL,
     1051        0x0000808bUL,
     1052        0x8000000bUL,
     1053        0x8000008aUL,
     1054        0x80000081UL,
     1055        0x80000081UL,
     1056        0x80000008UL,
     1057        0x00000083UL,
     1058        0x80008003UL,
     1059        0x80008088UL,
     1060        0x80000088UL,
     1061        0x00008000UL,
     1062        0x80008082UL,
     1063    };
     1064
     1065    uint32_t *const s32 = (uint32_t*)state;
     1066    unsigned round;
     1067
     1068    split_halves(state);
     1069
     1070    for (round = 0; round < NROUNDS; round++) {
     1071        unsigned x;
     1072
     1073        /* Theta */
     1074        {
     1075            uint32_t BC[20];
     1076            for (x = 0; x < 10; ++x) {
     1077                BC[x+10] = BC[x] = s32[x]^s32[x+10]^s32[x+20]^s32[x+30]^s32[x+40];
     1078            }
     1079            for (x = 0; x < 10; x += 2) {
     1080                uint32_t ta, tb;
     1081                ta = BC[x+8] ^ rotl32(BC[x+3], 1);
     1082                tb = BC[x+9] ^ BC[x+2];
     1083                s32[x+0] ^= ta;
     1084                s32[x+1] ^= tb;
     1085                s32[x+10] ^= ta;
     1086                s32[x+11] ^= tb;
     1087                s32[x+20] ^= ta;
     1088                s32[x+21] ^= tb;
     1089                s32[x+30] ^= ta;
     1090                s32[x+31] ^= tb;
     1091                s32[x+40] ^= ta;
     1092                s32[x+41] ^= tb;
     1093            }
     1094        }
     1095        /* RhoPi */
     1096        {
     1097            uint32_t t0a,t0b, t1a,t1b;
     1098            t1a = s32[1*2+0];
     1099            t1b = s32[1*2+1];
     1100
     1101#define RhoPi(PI_LANE, ROT_CONST) \
     1102    t0a = s32[PI_LANE*2+0];\
     1103    t0b = s32[PI_LANE*2+1];\
     1104    if (ROT_CONST & 1) {\
     1105        s32[PI_LANE*2+0] = rotl32(t1b, ROT_CONST/2+1);\
     1106        s32[PI_LANE*2+1] = ROT_CONST == 1 ? t1a : rotl32(t1a, ROT_CONST/2+0);\
     1107    } else {\
     1108        s32[PI_LANE*2+0] = rotl32(t1a, ROT_CONST/2);\
     1109        s32[PI_LANE*2+1] = rotl32(t1b, ROT_CONST/2);\
     1110    }\
     1111    t1a = t0a; t1b = t0b;
     1112
     1113            RhoPi(10, 1)
     1114            RhoPi( 7, 3)
     1115            RhoPi(11, 6)
     1116            RhoPi(17,10)
     1117            RhoPi(18,15)
     1118            RhoPi( 3,21)
     1119            RhoPi( 5,28)
     1120            RhoPi(16,36)
     1121            RhoPi( 8,45)
     1122            RhoPi(21,55)
     1123            RhoPi(24, 2)
     1124            RhoPi( 4,14)
     1125            RhoPi(15,27)
     1126            RhoPi(23,41)
     1127            RhoPi(19,56)
     1128            RhoPi(13, 8)
     1129            RhoPi(12,25)
     1130            RhoPi( 2,43)
     1131            RhoPi(20,62)
     1132            RhoPi(14,18)
     1133            RhoPi(22,39)
     1134            RhoPi( 9,61)
     1135            RhoPi( 6,20)
     1136            RhoPi( 1,44)
     1137#undef RhoPi
     1138        }
     1139        /* Chi */
     1140        for (x = 0; x <= 40;) {
     1141            uint32_t BC0, BC1, BC2, BC3, BC4;
     1142            BC0 = s32[x + 0*2];
     1143            BC1 = s32[x + 1*2];
     1144            BC2 = s32[x + 2*2];
     1145            s32[x + 0*2] = BC0 ^ ((~BC1) & BC2);
     1146            BC3 = s32[x + 3*2];
     1147            s32[x + 1*2] = BC1 ^ ((~BC2) & BC3);
     1148            BC4 = s32[x + 4*2];
     1149            s32[x + 2*2] = BC2 ^ ((~BC3) & BC4);
     1150            s32[x + 3*2] = BC3 ^ ((~BC4) & BC0);
     1151            s32[x + 4*2] = BC4 ^ ((~BC0) & BC1);
     1152            x++;
     1153            BC0 = s32[x + 0*2];
     1154            BC1 = s32[x + 1*2];
     1155            BC2 = s32[x + 2*2];
     1156            s32[x + 0*2] = BC0 ^ ((~BC1) & BC2);
     1157            BC3 = s32[x + 3*2];
     1158            s32[x + 1*2] = BC1 ^ ((~BC2) & BC3);
     1159            BC4 = s32[x + 4*2];
     1160            s32[x + 2*2] = BC2 ^ ((~BC3) & BC4);
     1161            s32[x + 3*2] = BC3 ^ ((~BC4) & BC0);
     1162            s32[x + 4*2] = BC4 ^ ((~BC0) & BC1);
     1163            x += 9;
     1164        }
     1165        /* Iota */
     1166        s32[0] ^= IOTA_CONST_0bits & 1;
     1167        IOTA_CONST_0bits >>= 1;
     1168        s32[1] ^= IOTA_CONST_1[round];
     1169    }
     1170
     1171    combine_halves(state);
     1172#else
     1173    /* Native 64-bit algorithm */
    9451174    static const uint16_t IOTA_CONST[NROUNDS] = {
     1175        /* Elements should be 64-bit, but top half is always zero
     1176         * or 0x80000000. We encode 63rd bits in a separate word below.
     1177         * Same is true for 31th bits, which lets us use 16-bit table
     1178         * instead of 64-bit. The speed penalty is lost in the noise.
     1179         */
    9461180        0x0001,
    9471181        0x8082,
     
    9841218    /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/
    9851219
    986     unsigned x, y;
     1220    unsigned x;
    9871221    unsigned round;
    9881222
     
    10461280#undef RhoPi_twice
    10471281        }
    1048 
    10491282        /* Chi */
    1050         for (y = 0; y <= 20; y += 5) {
     1283# if LONG_MAX > 0x7fffffff
     1284        for (x = 0; x <= 20; x += 5) {
    10511285            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);
     1286            BC0 = state[x + 0];
     1287            BC1 = state[x + 1];
     1288            BC2 = state[x + 2];
     1289            state[x + 0] = BC0 ^ ((~BC1) & BC2);
     1290            BC3 = state[x + 3];
     1291            state[x + 1] = BC1 ^ ((~BC2) & BC3);
     1292            BC4 = state[x + 4];
     1293            state[x + 2] = BC2 ^ ((~BC3) & BC4);
     1294            state[x + 3] = BC3 ^ ((~BC4) & BC0);
     1295            state[x + 4] = BC4 ^ ((~BC0) & BC1);
    10621296        }
    1063 
     1297# else
     1298        /* Reduced register pressure version
     1299         * for register-starved 32-bit arches
     1300         * (i386: -95 bytes, and it is _faster_)
     1301         */
     1302        for (x = 0; x <= 40;) {
     1303            uint32_t BC0, BC1, BC2, BC3, BC4;
     1304            uint32_t *const s32 = (uint32_t*)state;
     1305#  if SHA3_SMALL
     1306 do_half:
     1307#  endif
     1308            BC0 = s32[x + 0*2];
     1309            BC1 = s32[x + 1*2];
     1310            BC2 = s32[x + 2*2];
     1311            s32[x + 0*2] = BC0 ^ ((~BC1) & BC2);
     1312            BC3 = s32[x + 3*2];
     1313            s32[x + 1*2] = BC1 ^ ((~BC2) & BC3);
     1314            BC4 = s32[x + 4*2];
     1315            s32[x + 2*2] = BC2 ^ ((~BC3) & BC4);
     1316            s32[x + 3*2] = BC3 ^ ((~BC4) & BC0);
     1317            s32[x + 4*2] = BC4 ^ ((~BC0) & BC1);
     1318            x++;
     1319#  if SHA3_SMALL
     1320            if (x & 1)
     1321                goto do_half;
     1322            x += 8;
     1323#  else
     1324            BC0 = s32[x + 0*2];
     1325            BC1 = s32[x + 1*2];
     1326            BC2 = s32[x + 2*2];
     1327            s32[x + 0*2] = BC0 ^ ((~BC1) & BC2);
     1328            BC3 = s32[x + 3*2];
     1329            s32[x + 1*2] = BC1 ^ ((~BC2) & BC3);
     1330            BC4 = s32[x + 4*2];
     1331            s32[x + 2*2] = BC2 ^ ((~BC3) & BC4);
     1332            s32[x + 3*2] = BC3 ^ ((~BC4) & BC0);
     1333            s32[x + 4*2] = BC4 ^ ((~BC0) & BC1);
     1334            x += 9;
     1335#  endif
     1336        }
     1337# endif /* long is 32-bit */
    10641338        /* Iota */
    10651339        state[0] ^= IOTA_CONST[round]
     
    10731347        }
    10741348    }
     1349#endif
    10751350}
    10761351
  • branches/3.3/mindi-busybox/libbb/human_readable.c

    r2725 r3621  
    1515 *      The base ten "bytes" output could be handled similarly.
    1616 *
    17  *   2) This routine always outputs a decimal point and a tenths digit when
    18  *      display_unit != 0.  Hence, it isn't uncommon for the returned string
     17 *   2) This routine outputs a decimal point and a tenths digit when
     18 *      display_unit == 0.  Hence, it isn't uncommon for the returned string
    1919 *      to have a length of 5 or 6.
    2020 *
    21  *      It might be nice to add a flag to indicate no decimal digits in
    22  *      that case.  This could be either an additional parameter, or a
    23  *      special value of display_unit.  Such a flag would also be nice for du.
    24  *
    25  *      Some code to omit the decimal point and tenths digit is sketched out
    26  *      and "#if 0"'d below.
     21 *      If block_size is also 0, no decimal digits are printed.
    2722 *
    2823 * Licensed under GPLv2, see file LICENSE in this source tree.
     
    3732        '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
    3833    };
    39 
    40     static char *str;
    4134
    4235    unsigned frac; /* 0..9 - the fractional digit */
     
    8275    }
    8376
    84     if (!str) {
    85         /* sufficient for any width of val */
    86         str = xmalloc(sizeof(val)*3 + 2 + 3);
    87     }
    88     sprintf(str, fmt, val, frac, *u);
    89     return str;
     77    return auto_string(xasprintf(fmt, val, frac, *u));
    9078}
    9179
     
    9583/* Convert unsigned long long value into compact 5-char representation.
    9684 * String is not terminated (buf[5] is untouched) */
    97 void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale)
     85char* FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale)
    9886{
    9987    const char *fmt;
     
    146134        buf[4] = scale[idx]; /* typically scale = " kmgt..." */
    147135    }
     136    return buf + 5;
    148137}
    149138
     
    151140 * representation. Examples: "1234", "1.2k", " 27M", "123T"
    152141 * String is not terminated (buf[4] is untouched) */
    153 void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale)
     142char* FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale)
    154143{
    155144    const char *fmt;
     
    195184        buf[3] = scale[idx]; /* typically scale = " kmgt..." */
    196185    }
     186    return buf + 4;
    197187}
  • branches/3.3/mindi-busybox/libbb/inet_common.c

    r3232 r3621  
    3333    }
    3434    /* If we expect this to be a hostname, try hostname database first */
    35 #ifdef DEBUG
    3635    if (hostfirst) {
     36#ifdef DEBUG
    3737        bb_error_msg("gethostbyname(%s)", name);
    38     }
    39 #endif
    40     if (hostfirst) {
     38#endif
    4139        hp = gethostbyname(name);
    42         if (hp != NULL) {
     40        if (hp) {
    4341            memcpy(&s_in->sin_addr, hp->h_addr_list[0],
    4442                sizeof(struct in_addr));
     
    5250#endif
    5351    np = getnetbyname(name);
    54     if (np != NULL) {
     52    if (np) {
    5553        s_in->sin_addr.s_addr = htonl(np->n_net);
    5654        return 1;
     
    6765#endif
    6866    hp = gethostbyname(name);
    69     if (hp == NULL) {
     67    if (!hp) {
    7068        return -1;
    7169    }
     
    7573
    7674
    77 /* numeric: & 0x8000: default instead of *,
     75/* numeric: & 0x8000: "default" instead of "*",
    7876 *          & 0x4000: host instead of net,
    7977 *          & 0x0fff: don't resolve
     
    8482    struct addr {
    8583        struct addr *next;
    86         struct sockaddr_in addr;
    87         int host;
     84        uint32_t nip;
     85        smallint is_host;
    8886        char name[1];
    8987    };
     
    9290    struct addr *pn;
    9391    char *name;
    94     uint32_t ad, host_ad;
    95     int host = 0;
     92    uint32_t nip;
     93    smallint is_host;
    9694
    9795    if (s_in->sin_family != AF_INET) {
     
    103101        return NULL;
    104102    }
    105     ad = s_in->sin_addr.s_addr;
    106 #ifdef DEBUG
    107     bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric);
    108 #endif
    109     if (ad == INADDR_ANY) {
    110         if ((numeric & 0x0FFF) == 0) {
    111             if (numeric & 0x8000)
    112                 return xstrdup("default");
    113             return xstrdup("*");
    114         }
    115     }
     103    nip = s_in->sin_addr.s_addr;
     104#ifdef DEBUG
     105    bb_error_msg("rresolve: %08x mask:%08x num:%08x", (unsigned)nip, netmask, numeric);
     106#endif
    116107    if (numeric & 0x0FFF)
    117         return xstrdup(inet_ntoa(s_in->sin_addr));
    118 
    119     if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
    120         host = 1;
     108        return xmalloc_sockaddr2dotted_noport((void*)s_in);
     109    if (nip == INADDR_ANY) {
     110        if (numeric & 0x8000)
     111            return xstrdup("default");
     112        return xstrdup("*");
     113    }
     114
     115    is_host = ((nip & (~netmask)) != 0 || (numeric & 0x4000));
     116
    121117    pn = cache;
    122118    while (pn) {
    123         if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
     119        if (pn->nip == nip && pn->is_host == is_host) {
    124120#ifdef DEBUG
    125121            bb_error_msg("rresolve: found %s %08x in cache",
    126                       (host ? "host" : "net"), (unsigned)ad);
     122                (is_host ? "host" : "net"), (unsigned)nip);
    127123#endif
    128124            return xstrdup(pn->name);
     
    131127    }
    132128
    133     host_ad = ntohl(ad);
    134129    name = NULL;
    135     if (host) {
    136         struct hostent *ent;
    137 #ifdef DEBUG
    138         bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad);
    139 #endif
    140         ent = gethostbyaddr((char *) &ad, 4, AF_INET);
    141         if (ent)
    142             name = xstrdup(ent->h_name);
     130    if (is_host) {
     131#ifdef DEBUG
     132        bb_error_msg("sockaddr2host_noport(%08x)", (unsigned)nip);
     133#endif
     134        name = xmalloc_sockaddr2host_noport((void*)s_in);
    143135    } else if (ENABLE_FEATURE_ETC_NETWORKS) {
    144136        struct netent *np;
    145137#ifdef DEBUG
    146         bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad);
    147 #endif
    148         np = getnetbyaddr(host_ad, AF_INET);
     138        bb_error_msg("getnetbyaddr(%08x)", (unsigned)ntohl(nip));
     139#endif
     140        np = getnetbyaddr(ntohl(nip), AF_INET);
    149141        if (np)
    150142            name = xstrdup(np->n_name);
    151143    }
    152144    if (!name)
    153         name = xstrdup(inet_ntoa(s_in->sin_addr));
     145        name = xmalloc_sockaddr2dotted_noport((void*)s_in);
     146
    154147    pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */
    155148    pn->next = cache;
    156     pn->addr = *s_in;
    157     pn->host = host;
     149    pn->nip = nip;
     150    pn->is_host = is_host;
    158151    strcpy(pn->name, name);
    159152    cache = pn;
     153
    160154    return name;
    161155}
     
    176170    }
    177171    memcpy(sin6, ai->ai_addr, sizeof(*sin6));
    178     if (ai)
    179         freeaddrinfo(ai);
     172    freeaddrinfo(ai);
    180173    return 0;
    181174}
     
    190183char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
    191184{
    192     char name[128];
    193     int s;
    194 
    195185    if (sin6->sin6_family != AF_INET6) {
    196186#ifdef DEBUG
     
    202192    }
    203193    if (numeric & 0x7FFF) {
    204         inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name));
    205         return xstrdup(name);
     194        return xmalloc_sockaddr2dotted_noport((void*)sin6);
    206195    }
    207196    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
     
    211200    }
    212201
    213     s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6),
    214                 name, sizeof(name),
    215                 /*serv,servlen:*/ NULL, 0,
    216                 0);
    217     if (s != 0) {
    218         bb_error_msg("getnameinfo failed");
    219         return NULL;
    220     }
    221     return xstrdup(name);
     202    return xmalloc_sockaddr2host_noport((void*)sin6);
    222203}
    223204
  • branches/3.3/mindi-busybox/libbb/inode_hash.c

    r2725 r3621  
    1212
    1313typedef struct ino_dev_hash_bucket_struct {
    14     struct ino_dev_hash_bucket_struct *next;
    1514    ino_t ino;
    1615    dev_t dev;
     16    /*
     17     * Above fields can be 64-bit, while pointer may be 32-bit.
     18     * Putting "next" field here may reduce size of this struct:
     19     */
     20    struct ino_dev_hash_bucket_struct *next;
     21    /*
     22     * Reportedly, on cramfs a file and a dir can have same ino.
     23     * Need to also remember "file/dir" bit:
     24     */
     25    char isdir; /* bool */
    1726    char name[1];
    1827} ino_dev_hashtable_bucket_t;
    1928
    20 #define HASH_SIZE      311   /* Should be prime */
    21 #define hash_inode(i)  ((i) % HASH_SIZE)
     29#define HASH_SIZE      311u   /* Should be prime */
     30#define hash_inode(i)  ((unsigned)(i) % HASH_SIZE)
    2231
    2332/* array of [HASH_SIZE] elements */
     
    3948        if ((bucket->ino == statbuf->st_ino)
    4049         && (bucket->dev == statbuf->st_dev)
     50         && (bucket->isdir == !!S_ISDIR(statbuf->st_mode))
    4151        ) {
    4252            return bucket->name;
     
    5363    ino_dev_hashtable_bucket_t *bucket;
    5464
    55     i = hash_inode(statbuf->st_ino);
    5665    if (!name)
    5766        name = "";
     
    5968    bucket->ino = statbuf->st_ino;
    6069    bucket->dev = statbuf->st_dev;
     70    bucket->isdir = !!S_ISDIR(statbuf->st_mode);
    6171    strcpy(bucket->name, name);
    6272
     
    6474        ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable));
    6575
     76    i = hash_inode(statbuf->st_ino);
    6677    bucket->next = ino_dev_hashtable[i];
    6778    ino_dev_hashtable[i] = bucket;
     
    7384{
    7485    int i;
    75     ino_dev_hashtable_bucket_t *bucket;
     86    ino_dev_hashtable_bucket_t *bucket, *next;
    7687
    77     for (i = 0; ino_dev_hashtable && i < HASH_SIZE; i++) {
    78         while (ino_dev_hashtable[i] != NULL) {
    79             bucket = ino_dev_hashtable[i]->next;
    80             free(ino_dev_hashtable[i]);
    81             ino_dev_hashtable[i] = bucket;
     88    if (!ino_dev_hashtable)
     89        return;
     90
     91    for (i = 0; i < HASH_SIZE; i++) {
     92        bucket = ino_dev_hashtable[i];
     93
     94        while (bucket != NULL) {
     95            next = bucket->next;
     96            free(bucket);
     97            bucket = next;
    8298        }
    8399    }
  • branches/3.3/mindi-busybox/libbb/kernel_version.c

    r3232 r3621  
    2121{
    2222    struct utsname name;
    23     char *s, *t;
     23    char *t;
    2424    int i, r;
    2525
    2626    uname(&name); /* never fails */
    27     s = name.release;
     27    t = name.release;
    2828    r = 0;
    2929    for (i = 0; i < 3; i++) {
    30         t = strtok(s, ".");
     30        t = strtok(t, ".");
    3131        r = r * 256 + (t ? atoi(t) : 0);
    32         s = NULL;
     32        t = NULL;
    3333    }
    3434    return r;
  • branches/3.3/mindi-busybox/libbb/lineedit.c

    r3232 r3621  
    3939 *
    4040 * PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
     41 *
     42 * Unicode in PS1 is not fully supported: prompt length calulation is wrong,
     43 * resulting in line wrap problems with long (multi-line) input.
     44 *
     45 * Multi-line PS1 (e.g. PS1="\n[\w]\n$ ") has problems with history
     46 * browsing: up/down arrows result in scrolling.
     47 * It stems from simplistic "cmdedit_y = cmdedit_prmt_len / cmdedit_termw"
     48 * calculation of how many lines the prompt takes.
    4149 */
    42 #include "libbb.h"
     50#include "busybox.h"
     51#include "NUM_APPLETS.h"
    4352#include "unicode.h"
    4453#ifndef _POSIX_VDISABLE
     
    134143
    135144    const char *cmdedit_prompt;
    136 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
    137     int num_ok_lines; /* = 1; */
    138 #endif
    139145
    140146#if ENABLE_USERNAME_OR_HOMEDIR
     
    173179#define command_ps       (S.command_ps      )
    174180#define cmdedit_prompt   (S.cmdedit_prompt  )
    175 #define num_ok_lines     (S.num_ok_lines    )
    176181#define user_buf         (S.user_buf        )
    177182#define home_pwd_buf     (S.home_pwd_buf    )
     
    186191    barrier(); \
    187192    cmdedit_termw = 80; \
    188     IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \
    189193    IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \
     194    IF_FEATURE_EDITING_VI(delptr = delbuf;) \
    190195} while (0)
    191196
     
    669674static NOINLINE unsigned complete_username(const char *ud)
    670675{
    671     /* Using _r function to avoid pulling in static buffers */
    672     char line_buff[256];
    673     struct passwd pwd;
    674     struct passwd *result;
     676    struct passwd *pw;
    675677    unsigned userlen;
    676678
     
    679681
    680682    setpwent();
    681     while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) {
     683    while ((pw = getpwent()) != NULL) {
    682684        /* Null usernames should result in all users as possible completions. */
    683         if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) {
    684             add_match(xasprintf("~%s/", pwd.pw_name));
    685         }
    686     }
    687     endpwent();
     685        if (/* !ud[0] || */ is_prefixed_with(pw->pw_name, ud)) {
     686            add_match(xasprintf("~%s/", pw->pw_name));
     687        }
     688    }
     689    endpwent(); /* don't keep password file open */
    688690
    689691    return 1 + userlen;
     
    774776    pf_len = strlen(pfind);
    775777
     778#if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
     779    if (type == FIND_EXE_ONLY) {
     780        const char *p = applet_names;
     781
     782        while (*p) {
     783            if (strncmp(pfind, p, pf_len) == 0)
     784                add_match(xstrdup(p));
     785            while (*p++ != '\0')
     786                continue;
     787        }
     788    }
     789#endif
     790
    776791    for (i = 0; i < npaths; i++) {
    777792        DIR *dir;
     
    792807                continue;
    793808            /* match? */
    794             if (strncmp(name_found, pfind, pf_len) != 0)
     809            if (!is_prefixed_with(name_found, pfind))
    795810                continue; /* no */
    796811
     
    12521267    line_input_t *n = xzalloc(sizeof(*n));
    12531268    n->flags = flags;
     1269#if MAX_HISTORY > 0
    12541270    n->max_history = MAX_HISTORY;
     1271#endif
    12551272    return n;
    12561273}
     
    12591276#if MAX_HISTORY > 0
    12601277
    1261 unsigned size_from_HISTFILESIZE(const char *hp)
     1278unsigned FAST_FUNC size_from_HISTFILESIZE(const char *hp)
    12621279{
    12631280    int size = MAX_HISTORY;
     
    13121329    beep();
    13131330    return 0;
     1331}
     1332
     1333/* Lists command history. Used by shell 'history' builtins */
     1334void FAST_FUNC show_history(const line_input_t *st)
     1335{
     1336    int i;
     1337
     1338    if (!st)
     1339        return;
     1340    for (i = 0; i < st->cnt_history; i++)
     1341        printf("%4d %s\n", i, st->history[i]);
    13141342}
    13151343
     
    15321560    save_history(str);
    15331561# endif
    1534     IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
    15351562}
    15361563
     
    17541781#endif
    17551782
     1783/* Called just once at read_line_input() init time */
    17561784#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
    17571785static void parse_and_put_prompt(const char *prmt_ptr)
    17581786{
     1787    const char *p;
    17591788    cmdedit_prompt = prmt_ptr;
    1760     cmdedit_prmt_len = strlen(prmt_ptr);
     1789    p = strrchr(prmt_ptr, '\n');
     1790    cmdedit_prmt_len = unicode_strwidth(p ? p+1 : prmt_ptr);
    17611791    put_prompt();
    17621792}
     
    17641794static void parse_and_put_prompt(const char *prmt_ptr)
    17651795{
    1766     int prmt_len = 0;
    1767     size_t cur_prmt_len = 0;
     1796    int prmt_size = 0;
     1797    char *prmt_mem_ptr = xzalloc(1);
     1798# if ENABLE_USERNAME_OR_HOMEDIR
     1799    char *cwd_buf = NULL;
     1800# endif
    17681801    char flg_not_length = '[';
    1769     char *prmt_mem_ptr = xzalloc(1);
    1770     char *cwd_buf = xrealloc_getcwd_or_warn(NULL);
    17711802    char cbuf[2];
    1772     char c;
    1773     char *pbuf;
    1774 
    1775     cmdedit_prmt_len = 0;
    1776 
    1777     if (!cwd_buf) {
    1778         cwd_buf = (char *)bb_msg_unknown;
    1779     }
     1803
     1804    /*cmdedit_prmt_len = 0; - already is */
    17801805
    17811806    cbuf[1] = '\0'; /* never changes */
    17821807
    17831808    while (*prmt_ptr) {
     1809        char timebuf[sizeof("HH:MM:SS")];
    17841810        char *free_me = NULL;
     1811        char *pbuf;
     1812        char c;
    17851813
    17861814        pbuf = cbuf;
    17871815        c = *prmt_ptr++;
    17881816        if (c == '\\') {
    1789             const char *cp = prmt_ptr;
     1817            const char *cp;
    17901818            int l;
    1791 
    1792             c = bb_process_escape_sequence(&prmt_ptr);
     1819/*
     1820 * Supported via bb_process_escape_sequence:
     1821 * \a   ASCII bell character (07)
     1822 * \e   ASCII escape character (033)
     1823 * \n   newline
     1824 * \r   carriage return
     1825 * \\   backslash
     1826 * \nnn char with octal code nnn
     1827 * Supported:
     1828 * \$   if the effective UID is 0, a #, otherwise a $
     1829 * \w   current working directory, with $HOME abbreviated with a tilde
     1830 *  Note: we do not support $PROMPT_DIRTRIM=n feature
     1831 * \W   basename of the current working directory, with $HOME abbreviated with a tilde
     1832 * \h   hostname up to the first '.'
     1833 * \H   hostname
     1834 * \u   username
     1835 * \[   begin a sequence of non-printing characters
     1836 * \]   end a sequence of non-printing characters
     1837 * \T   current time in 12-hour HH:MM:SS format
     1838 * \@   current time in 12-hour am/pm format
     1839 * \A   current time in 24-hour HH:MM format
     1840 * \t   current time in 24-hour HH:MM:SS format
     1841 *  (all of the above work as \A)
     1842 * Not supported:
     1843 * \!   history number of this command
     1844 * \#   command number of this command
     1845 * \j   number of jobs currently managed by the shell
     1846 * \l   basename of the shell's terminal device name
     1847 * \s   name of the shell, the basename of $0 (the portion following the final slash)
     1848 * \V   release of bash, version + patch level (e.g., 2.00.0)
     1849 * \d   date in "Weekday Month Date" format (e.g., "Tue May 26")
     1850 * \D{format}
     1851 *  format is passed to strftime(3).
     1852 *  An empty format results in a locale-specific time representation.
     1853 *  The braces are required.
     1854 * Mishandled by bb_process_escape_sequence:
     1855 * \v   version of bash (e.g., 2.00)
     1856 */
     1857            cp = prmt_ptr;
     1858            c = *cp;
     1859            if (c != 't') /* don't treat \t as tab */
     1860                c = bb_process_escape_sequence(&prmt_ptr);
    17931861            if (prmt_ptr == cp) {
    17941862                if (*cp == '\0')
     
    18021870                    break;
    18031871# endif
     1872                case 'H':
    18041873                case 'h':
    18051874                    pbuf = free_me = safe_gethostname();
    1806                     *strchrnul(pbuf, '.') = '\0';
     1875                    if (c == 'h')
     1876                        strchrnul(pbuf, '.')[0] = '\0';
    18071877                    break;
    18081878                case '$':
    18091879                    c = (geteuid() == 0 ? '#' : '$');
    18101880                    break;
     1881                case 'T': /* 12-hour HH:MM:SS format */
     1882                case '@': /* 12-hour am/pm format */
     1883                case 'A': /* 24-hour HH:MM format */
     1884                case 't': /* 24-hour HH:MM:SS format */
     1885                    /* We show all of them as 24-hour HH:MM */
     1886                    strftime_HHMMSS(timebuf, sizeof(timebuf), NULL)[-3] = '\0';
     1887                    pbuf = timebuf;
     1888                    break;
    18111889# if ENABLE_USERNAME_OR_HOMEDIR
    1812                 case 'w':
    1813                     /* /home/user[/something] -> ~[/something] */
     1890                case 'w': /* current dir */
     1891                case 'W': /* basename of cur dir */
     1892                    if (!cwd_buf) {
     1893                        cwd_buf = xrealloc_getcwd_or_warn(NULL);
     1894                        if (!cwd_buf)
     1895                            cwd_buf = (char *)bb_msg_unknown;
     1896                        else if (home_pwd_buf[0]) {
     1897                            char *after_home_user;
     1898
     1899                            /* /home/user[/something] -> ~[/something] */
     1900                            after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf);
     1901                            if (after_home_user
     1902                             && (*after_home_user == '/' || *after_home_user == '\0')
     1903                            ) {
     1904                                cwd_buf[0] = '~';
     1905                                overlapping_strcpy(cwd_buf + 1, after_home_user);
     1906                            }
     1907                        }
     1908                    }
    18141909                    pbuf = cwd_buf;
    1815                     l = strlen(home_pwd_buf);
    1816                     if (l != 0
    1817                      && strncmp(home_pwd_buf, cwd_buf, l) == 0
    1818                      && (cwd_buf[l]=='/' || cwd_buf[l]=='\0')
    1819                      && strlen(cwd_buf + l) < PATH_MAX
    1820                     ) {
    1821                         pbuf = free_me = xasprintf("~%s", cwd_buf + l);
    1822                     }
     1910                    if (c == 'w')
     1911                        break;
     1912                    cp = strrchr(pbuf, '/');
     1913                    if (cp)
     1914                        pbuf = (char*)cp + 1;
    18231915                    break;
    18241916# endif
    1825                 case 'W':
    1826                     pbuf = cwd_buf;
    1827                     cp = strrchr(pbuf, '/');
    1828                     if (cp != NULL && cp != pbuf)
    1829                         pbuf += (cp-pbuf) + 1;
    1830                     break;
    1831                 case '!':
    1832                     pbuf = free_me = xasprintf("%d", num_ok_lines);
    1833                     break;
    1834                 case 'e': case 'E':     /* \e \E = \033 */
    1835                     c = '\033';
    1836                     break;
     1917// bb_process_escape_sequence does this now:
     1918//              case 'e': case 'E':     /* \e \E = \033 */
     1919//                  c = '\033';
     1920//                  break;
    18371921                case 'x': case 'X': {
    18381922                    char buf2[4];
     
    18561940                case '[': case ']':
    18571941                    if (c == flg_not_length) {
    1858                         flg_not_length = (flg_not_length == '[' ? ']' : '[');
     1942                        /* Toggle '['/']' hex 5b/5d */
     1943                        flg_not_length ^= 6;
    18591944                        continue;
    18601945                    }
     
    18641949        } /* if */
    18651950        cbuf[0] = c;
    1866         cur_prmt_len = strlen(pbuf);
    1867         prmt_len += cur_prmt_len;
    1868         if (flg_not_length != ']')
    1869             cmdedit_prmt_len += cur_prmt_len;
    1870         prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
     1951        {
     1952            int n = strlen(pbuf);
     1953            prmt_size += n;
     1954            if (c == '\n')
     1955                cmdedit_prmt_len = 0;
     1956            else if (flg_not_length != ']') {
     1957#if 0 /*ENABLE_UNICODE_SUPPORT*/
     1958/* Won't work, pbuf is one BYTE string here instead of an one Unicode char string. */
     1959/* FIXME */
     1960                cmdedit_prmt_len += unicode_strwidth(pbuf);
     1961#else
     1962                cmdedit_prmt_len += n;
     1963#endif
     1964            }
     1965        }
     1966        prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf);
    18711967        free(free_me);
    18721968    } /* while */
    18731969
     1970# if ENABLE_USERNAME_OR_HOMEDIR
    18741971    if (cwd_buf != (char *)bb_msg_unknown)
    18751972        free(cwd_buf);
     1973# endif
    18761974    cmdedit_prompt = prmt_mem_ptr;
    18771975    put_prompt();
     
    19352033            if (cursor == 0) { /* otherwise it may be bogus */
    19362034                int col = ((ic >> 32) & 0x7fff) - 1;
    1937                 if (col > cmdedit_prmt_len) {
     2035                /*
     2036                 * Is col > cmdedit_prmt_len?
     2037                 * If yes (terminal says cursor is farther to the right
     2038                 * of where we think it should be),
     2039                 * the prompt wasn't printed starting at col 1,
     2040                 * there was additional text before it.
     2041                 */
     2042                if ((int)(col - cmdedit_prmt_len) > 0) {
     2043                    /* Fix our understanding of current x position */
    19382044                    cmdedit_x += (col - cmdedit_prmt_len);
    19392045                    while (cmdedit_x >= cmdedit_termw) {
     
    20262132    const char *matched_history_line;
    20272133    const char *saved_prompt;
     2134    unsigned saved_prmt_len;
    20282135    int32_t ic;
    20292136
     
    20342141    /* Save and replace the prompt */
    20352142    saved_prompt = cmdedit_prompt;
     2143    saved_prmt_len = cmdedit_prmt_len;
    20362144    goto set_prompt;
    20372145
     
    21092217 set_prompt:
    21102218                    cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf);
    2111                     cmdedit_prmt_len = strlen(cmdedit_prompt);
     2219                    cmdedit_prmt_len = unicode_strwidth(cmdedit_prompt);
    21122220                    goto do_redraw;
    21132221                }
     
    21312239    free((char*)cmdedit_prompt);
    21322240    cmdedit_prompt = saved_prompt;
    2133     cmdedit_prmt_len = strlen(cmdedit_prompt);
     2241    cmdedit_prmt_len = saved_prmt_len;
    21342242    redraw(cmdedit_y, command_len - cursor);
    21352243
     
    21612269
    21622270    if (tcgetattr(STDIN_FILENO, &initial_settings) < 0
    2163      || !(initial_settings.c_lflag & ECHO)
     2271     || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON
    21642272    ) {
    2165         /* Happens when e.g. stty -echo was run before */
     2273        /* Happens when e.g. stty -echo was run before.
     2274         * But if ICANON is not set, we don't come here.
     2275         * (example: interactive python ^Z-backgrounded,
     2276         * tty is still in "raw mode").
     2277         */
    21662278        parse_and_put_prompt(prompt);
    21672279        /* fflush_all(); - done by parse_and_put_prompt */
     
    25122624             * Often, Alt-<key> generates ESC-<key>.
    25132625             */
    2514             ic = lineedit_read_key(read_key_buffer, timeout);
     2626            ic = lineedit_read_key(read_key_buffer, 50);
    25152627            switch (ic) {
    25162628                //case KEYCODE_LEFT: - bash doesn't do this
     
    26992811#endif
    27002812
    2701     if (command_len > 0)
     2813    if (command_len > 0) {
    27022814        remember_in_history(command);
     2815    }
    27032816
    27042817    if (break_out > 0) {
  • branches/3.3/mindi-busybox/libbb/login.c

    r2725 r3621  
    1717
    1818static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y";
    19 static const char fmtstr_t[] ALIGN1 = "%H:%M:%S";
    2019
    2120void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
     
    7473                break;
    7574            case 't':
    76                 strftime(buf, sizeof(buf), fmtstr_t, localtime(&t));
     75                strftime_HHMMSS(buf, sizeof(buf), &t);
    7776                break;
    7877            case 'l':
  • branches/3.3/mindi-busybox/libbb/loop.c

    r3232 r3621  
    9595    /* Open the file.  Barf if this doesn't work.  */
    9696    mode = ro ? O_RDONLY : O_RDWR;
     97 open_ffd:
    9798    ffd = open(file, mode);
    9899    if (ffd < 0) {
    99100        if (mode != O_RDONLY) {
    100101            mode = O_RDONLY;
    101             ffd = open(file, mode);
     102            goto open_ffd;
    102103        }
    103         if (ffd < 0)
    104             return -errno;
     104        return -errno;
    105105    }
    106106
    107107    /* Find a loop device.  */
    108108    try = *device ? *device : dev;
    109     /* 1048575 is a max possible minor number in Linux circa 2010 */
     109    /* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */
    110110    for (i = 0; rc && i < 1048576; i++) {
    111111        sprintf(dev, LOOP_FORMAT, i);
     
    122122            }
    123123            /* Ran out of block devices, return failure.  */
    124             rc = -ENOENT;
     124            rc = -1;
    125125            break;
    126126        }
     
    132132            dfd = open(try, mode);
    133133        }
    134         if (dfd < 0)
     134        if (dfd < 0) {
     135            if (errno == ENXIO) {
     136                /* Happens if loop module is not loaded */
     137                rc = -1;
     138                break;
     139            }
    135140            goto try_again;
     141        }
    136142
    137143        rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);
     
    149155                    ioctl(dfd, LOOP_CLR_FD, 0);
    150156            }
    151 
    152         /* If this block device already set up right, re-use it.
    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.)
    156          */
    157         } else
    158         if (strcmp(file, (char *)loopinfo.lo_file_name) != 0
    159          || offset != loopinfo.lo_offset
    160         ) {
     157        } else {
    161158            rc = -1;
    162159        }
  • branches/3.3/mindi-busybox/libbb/make_directory.c

    r3232 r3621  
    100100                goto ret0;
    101101            }
     102        } else {
     103            if (flags & FILEUTILS_VERBOSE) {
     104                printf("created directory: '%s'\n", path);
     105            }
    102106        }
    103107
  • branches/3.3/mindi-busybox/libbb/match_fstype.c

    r3232 r3621  
    1818{
    1919    int match = 1;
    20     int len;
    2120
    2221    if (!t_fstype)
     
    2827    }
    2928
    30     len = strlen(mt->mnt_type);
    3129    while (1) {
    32         if (strncmp(mt->mnt_type, t_fstype, len) == 0
    33          && (t_fstype[len] == '\0' || t_fstype[len] == ',')
     30        char *after_mnt_type = is_prefixed_with(t_fstype, mt->mnt_type);
     31        if (after_mnt_type
     32         && (*after_mnt_type == '\0' || *after_mnt_type == ',')
    3433        ) {
    3534            return match;
  • branches/3.3/mindi-busybox/libbb/messages.c

    r3232 r3621  
    3030const char bb_msg_you_must_be_root[] ALIGN1 = "you must be root";
    3131const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument";
    32 const char bb_msg_invalid_arg[] ALIGN1 = "invalid argument '%s' to '%s'";
     32const char bb_msg_invalid_arg_to[] ALIGN1 = "invalid argument '%s' to '%s'";
    3333const char bb_msg_standard_input[] ALIGN1 = "standard input";
    3434const char bb_msg_standard_output[] ALIGN1 = "standard output";
     
    4444
    4545
    46 const int const_int_1 = 1;
     46//const int const_int_1 = 1;
    4747/* explicitly = 0, otherwise gcc may make it a common variable
    4848 * and it will end up in bss */
     
    6060# endif
    6161#endif
    62 
    63 /* We use it for "global" data via *(struct global*)&bb_common_bufsiz1.
    64  * Since gcc insists on aligning struct global's members, it would be a pity
    65  * (and an alignment fault on some CPUs) to mess it up. */
    66 char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long));
  • branches/3.3/mindi-busybox/libbb/mode_string.c

    r2725 r3621  
    8888/* The previous version used "0pcCd?bB-?l?s???".  However, the '0', 'C',
    8989 * and 'B' types don't appear to be available on linux.  So I removed them. */
    90 static const char type_chars[16] = "?pc?d?b?-?l?s???";
     90static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???";
    9191/********************************** 0123456789abcdef */
    92 static const char mode_chars[7] = "rwxSTst";
     92static const char mode_chars[7] ALIGN1 = "rwxSTst";
    9393
    9494const char* FAST_FUNC bb_mode_string(mode_t mode)
  • branches/3.3/mindi-busybox/libbb/obscure.c

    r3232 r3621  
    7777
    7878    /* clean up */
    79     memset(p, 0, size);
     79    nuke_str(p);
    8080    free(p);
    8181
     
    183183    return 0;
    184184}
     185
     186#if ENABLE_UNIT_TEST
     187
     188/* Test obscure_msg() instead of obscure() in order not to print anything. */
     189
     190static const struct passwd pw = {
     191    .pw_name = (char *)"johndoe",
     192    .pw_gecos = (char *)"John Doe",
     193};
     194
     195BBUNIT_DEFINE_TEST(obscure_weak_pass)
     196{
     197    /* Empty password */
     198    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "", &pw));
     199    /* Pure numbers */
     200    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "23577315", &pw));
     201    /* Similar to pw_name */
     202    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "johndoe123%", &pw));
     203    /* Similar to pw_gecos, reversed */
     204    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "eoD nhoJ^44@", &pw));
     205    /* Similar to the old password */
     206    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "d4#21?'S", &pw));
     207    /* adjacent letters */
     208    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "qwerty123", &pw));
     209    /* Many similar chars */
     210    BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "^33Daaaaaa1", &pw));
     211
     212    BBUNIT_ENDTEST;
     213}
     214
     215BBUNIT_DEFINE_TEST(obscure_strong_pass)
     216{
     217    BBUNIT_ASSERT_NULL(obscure_msg("Rt4##2&:'|", "}(^#rrSX3S*22", &pw));
     218
     219    BBUNIT_ENDTEST;
     220}
     221
     222#endif /* ENABLE_UNIT_TEST */
  • branches/3.3/mindi-busybox/libbb/parse_mode.c

    r2725 r3621  
    1616#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
    1717
    18 int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
     18int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode)
    1919{
    2020    static const mode_t who_mask[] = {
     
    4747        tmp = strtoul(s, &e, 8);
    4848        if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
    49             return 0;
     49            return -1;
    5050        }
    51         *current_mode = tmp;
    52         return 1;
     51        return tmp;
    5352    }
    5453
    55     new_mode = *current_mode;
     54    new_mode = current_mode;
    5655
    5756    /* Note: we allow empty clauses, and hence empty modes.
     
    7271                wholist |= who_mask[(int)(p-who_chars)];
    7372                if (!*++s) {
    74                     return 0;
     73                    return -1;
    7574                }
    7675                goto WHO_LIST;
     
    8180            if ((*s != '+') && (*s != '-')) {
    8281                if (*s != '=') {
    83                     return 0;
     82                    return -1;
    8483                }
    8584                /* Since op is '=', clear all bits corresponding to the
     
    146145    }
    147146
    148     *current_mode = new_mode;
    149     return 1;
     147    return new_mode;
    150148}
  • branches/3.3/mindi-busybox/libbb/platform.c

    r3232 r3621  
    1818#endif
    1919
     20#ifndef HAVE_USLEEP
     21int FAST_FUNC usleep(unsigned usec)
     22{
     23    struct timespec ts;
     24    ts.tv_sec = usec / 1000000u;
     25    ts.tv_nsec = (usec % 1000000u) * 1000u;
     26    /*
     27     * If a signal has non-default handler, nanosleep returns early.
     28     * Our version of usleep doesn't return early
     29     * if interrupted by such signals:
     30     *
     31     */
     32    while (nanosleep(&ts, &ts) != 0)
     33        continue;
     34    return 0;
     35}
     36#endif
     37
    2038#ifndef HAVE_VASPRINTF
    2139int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p)
     
    2947    va_end(p);
    3048
     49    /* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */
     50
    3151    if (r < 128) {
    3252        va_end(p2);
    33         *string_ptr = xstrdup(buf);
    34         return r;
    35     }
    36 
    37     *string_ptr = xmalloc(r+1);
    38     r = vsnprintf(*string_ptr, r+1, format, p2);
     53        *string_ptr = strdup(buf);
     54        return (*string_ptr ? r : -1);
     55    }
     56
     57    *string_ptr = malloc(r+1);
     58    r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1);
    3959    va_end(p2);
    4060
     
    175195}
    176196#endif
     197
     198#ifndef HAVE_TTYNAME_R
     199int ttyname_r(int fd, char *buf, size_t buflen)
     200{
     201    int r;
     202    char path[sizeof("/proc/self/fd/%d") + sizeof(int)*3];
     203
     204    if (!isatty(fd))
     205        return errno == EINVAL ? ENOTTY : errno;
     206    sprintf(path, "/proc/self/fd/%d", fd);
     207    r = readlink(path, buf, buflen);
     208    if (r < 0)
     209        return errno;
     210    if (r >= buflen)
     211        return ERANGE;
     212    buf[r] = '\0';
     213    return 0;
     214}
     215#endif
  • branches/3.3/mindi-busybox/libbb/printable.c

    r2725 r3621  
    3333    fputc(ch, file);
    3434}
     35
     36void FAST_FUNC visible(unsigned ch, char *buf, int flags)
     37{
     38    if (ch == '\t' && !(flags & VISIBLE_SHOW_TABS)) {
     39        goto raw;
     40    }
     41    if (ch == '\n') {
     42        if (flags & VISIBLE_ENDLINE)
     43            *buf++ = '$';
     44    } else {
     45        if (ch >= 128) {
     46            ch -= 128;
     47            *buf++ = 'M';
     48            *buf++ = '-';
     49        }
     50        if (ch < 32 || ch == 127) {
     51            *buf++ = '^';
     52            ch ^= 0x40;
     53        }
     54    }
     55 raw:
     56    *buf++ = ch;
     57    *buf = '\0';
     58}
  • branches/3.3/mindi-busybox/libbb/printable_string.c

    r2725 r3621  
    1212const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
    1313{
    14     static char *saved[4];
    15     static unsigned cur_saved; /* = 0 */
    16 
    1714    char *dst;
    1815    const char *s;
     
    5754    }
    5855#endif
    59 
    60     free(saved[cur_saved]);
    61     saved[cur_saved] = dst;
    62     cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1);
    63 
    64     return dst;
     56    return auto_string(dst);
    6557}
  • branches/3.3/mindi-busybox/libbb/procps.c

    r3232 r3621  
    206206        // .....
    207207
    208         char *tp = buf, *p;
     208        char *tp, *p;
    209209
    210210#define SCAN(S, X) \
    211         if (strncmp(tp, S, sizeof(S)-1) == 0) {              \
    212             tp = skip_whitespace(tp + sizeof(S)-1);      \
     211        if ((tp = is_prefixed_with(buf, S)) != NULL) {       \
     212            tp = skip_whitespace(tp);                    \
    213213            total->X += currec.X = fast_strtoul_10(&tp); \
    214214            continue;                                    \
     
    248248            tp = skip_whitespace(skip_fields(tp, 4));
    249249            // filter out /dev/something (something != zero)
    250             if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) {
     250            if (!is_prefixed_with(tp, "/dev/") || strcmp(tp, "/dev/zero\n") == 0) {
    251251                if (currec.smap_mode[1] == 'w') {
    252252                    currec.mapped_rw = currec.smap_size;
     
    284284#endif
    285285
    286 void BUG_comm_size(void);
    287286procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
    288287{
     
    386385                continue;*/
    387386            cp[0] = '\0';
    388             if (sizeof(sp->comm) < 16)
    389                 BUG_comm_size();
     387            BUILD_BUG_ON(sizeof(sp->comm) < 16);
    390388            comm1 = strchr(buf, '(');
    391389            /*if (comm1)*/
     
    498496                    char *tp;
    499497#define SCAN_TWO(str, name, statement) \
    500     if (strncmp(buf, str, sizeof(str)-1) == 0) { \
    501         tp = skip_whitespace(buf + sizeof(str)-1); \
     498    if ((tp = is_prefixed_with(buf, str)) != NULL) { \
     499        tp = skip_whitespace(tp); \
    502500        sscanf(tp, "%u", &sp->name); \
    503501        statement; \
     
    555553            if (flags & PSSCAN_ARGVN) {
    556554                sp->argv_len = n;
    557                 sp->argv0 = xmalloc(n + 1);
    558                 memcpy(sp->argv0, buf, n + 1);
     555                sp->argv0 = xmemdup(buf, n + 1);
    559556                /* sp->argv0[n] = '\0'; - buf has it */
    560557            } else {
     
    592589            sz--;
    593590        }
     591        if (base[0] == '-') /* "-sh" (login shell)? */
     592            base++;
    594593
    595594        /* If comm differs from argv0, prepend "{comm} ".
    596595         * It allows to see thread names set by prctl(PR_SET_NAME).
    597596         */
    598         if (base[0] == '-') /* "-sh" (login shell)? */
    599             base++;
     597        if (!comm)
     598            return;
    600599        comm_len = strlen(comm);
    601600        /* Why compare up to comm_len, not COMM_LEN-1?
     
    615614            buf[col - 1] = '\0';
    616615        }
    617 
    618616    } else {
    619         snprintf(buf, col, "[%s]", comm);
     617        snprintf(buf, col, "[%s]", comm ? comm : "?");
    620618    }
    621619}
  • branches/3.3/mindi-busybox/libbb/progress.c

    r3232 r3621  
    4545    STALLTIME = 5
    4646};
    47 
    48 static unsigned int get_tty2_width(void)
    49 {
    50     unsigned width;
    51     get_terminal_width_height(2, &width, NULL);
    52     return width;
    53 }
    5447
    5548void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile)
     
    8174    uoff_t beg_and_transferred;
    8275    unsigned since_last_update, elapsed;
    83     int barlength;
     76    int notty;
    8477    int kiloscale;
    8578
     
    138131    }
    139132
     133    notty = !isatty(STDERR_FILENO);
     134
    140135    if (ENABLE_UNICODE_SUPPORT)
    141         fprintf(stderr, "\r%s", p->curfile);
     136        fprintf(stderr, "\r%s" + notty, p->curfile);
    142137    else
    143         fprintf(stderr, "\r%-20.20s", p->curfile);
     138        fprintf(stderr, "\r%-20.20s" + notty, p->curfile);
    144139
    145140    beg_and_transferred = beg_size + transferred;
    146141
    147142    if (totalsize != 0) {
     143        int barlength;
    148144        unsigned ratio = 100 * beg_and_transferred / totalsize;
    149145        fprintf(stderr, "%4u%%", ratio);
    150146
    151         barlength = get_tty2_width() - 49;
     147        barlength = get_terminal_width(2) - 49;
    152148        if (barlength > 0) {
    153149            /* god bless gcc for variable arrays :) */
     
    205201        fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60);
    206202    }
     203    if (notty)
     204        fputc('\n', stderr);
    207205}
  • branches/3.3/mindi-busybox/libbb/pw_encrypt.c

    r3232 r3621  
    1010#include "libbb.h"
    1111
    12 /* static const uint8_t ascii64[] =
     12/* static const uint8_t ascii64[] ALIGN1 =
    1313 * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    1414 */
     
    5353    int len = 2/2;
    5454    char *salt_ptr = salt;
    55     if (algo[0] != 'd') { /* not des */
     55
     56    /* Standard chpasswd uses uppercase algos ("MD5", not "md5").
     57     * Need to be case-insensitive in the code below.
     58     */
     59    if ((algo[0]|0x20) != 'd') { /* not des */
    5660        len = 8/2; /* so far assuming md5 */
    5761        *salt_ptr++ = '$';
     
    5963        *salt_ptr++ = '$';
    6064#if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA
    61         if (algo[0] == 's') { /* sha */
    62             salt[1] = '5' + (strcmp(algo, "sha512") == 0);
     65        if ((algo[0]|0x20) == 's') { /* sha */
     66            salt[1] = '5' + (strcasecmp(algo, "sha512") == 0);
    6367            len = 16/2;
    6468        }
     
    143147char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
    144148{
    145     return xstrdup(crypt(clear, salt));
     149    char *s;
     150
     151    s = crypt(clear, salt);
     152    /*
     153     * glibc used to return "" on malformed salts (for example, ""),
     154     * but since 2.17 it returns NULL.
     155     */
     156    return xstrdup(s ? s : "");
    146157}
    147158
  • branches/3.3/mindi-busybox/libbb/pw_encrypt_md5.c

    r2725 r3621  
    8787    /* Get the length of the salt including "$1$" */
    8888    sl = 3;
    89     while (salt[sl] && salt[sl] != '$' && sl < (3 + 8))
     89    while (sl < (3 + 8) && salt[sl] && salt[sl] != '$')
    9090        sl++;
    9191
  • branches/3.3/mindi-busybox/libbb/read_printf.c

    r3232 r3621  
    4646 * Thankfully, poll() doesn't care about O_NONBLOCK flag.
    4747 */
    48 ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR)
     48ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count)
    4949{
    5050    struct pollfd pfd[1];
     
    5252
    5353    while (1) {
    54         n = loop_on_EINTR ? safe_read(fd, buf, count) : read(fd, buf, count);
     54        n = safe_read(fd, buf, count);
    5555        if (n >= 0 || errno != EAGAIN)
    5656            return n;
     
    5959        pfd[0].events = POLLIN;
    6060        /* note: safe_poll pulls in printf */
    61         loop_on_EINTR ? safe_poll(pfd, 1, -1) : poll(pfd, 1, -1);
     61        safe_poll(pfd, 1, -1);
    6262    }
    6363}
     
    8282            sz += 128;
    8383        }
    84         if (nonblock_immune_read(fd, p, 1, /*loop_on_EINTR:*/ 1) != 1) {
     84        if (nonblock_immune_read(fd, p, 1) != 1) {
    8585            /* EOF/error */
    8686            if (p == buf) { /* we read nothing */
  • branches/3.3/mindi-busybox/libbb/remove_file.c

    r3232 r3621  
    7979        }
    8080
     81        if (flags & FILEUTILS_VERBOSE) {
     82            printf("removed directory: '%s'\n", path);
     83        }
     84
    8185        return status;
    8286    }
     
    99103    }
    100104
     105    if (flags & FILEUTILS_VERBOSE) {
     106        printf("removed '%s'\n", path);
     107    }
     108
    101109    return 0;
    102110}
  • branches/3.3/mindi-busybox/libbb/rtc.c

    r2725 r3621  
    2323
    2424        while (fgets(buffer, sizeof(buffer), f)) {
    25             if (strncmp(buffer, "UTC", 3) == 0) {
     25            if (is_prefixed_with(buffer, "UTC")) {
    2626                utc = 1;
    2727                break;
     
    3434}
    3535
     36/* rtc opens are exclusive.
     37 * Try to run two "hwclock -w" at the same time to see it.
     38 * Users wouldn't expect that to fail merely because /dev/rtc
     39 * was momentarily busy, let's try a bit harder on errno == EBUSY.
     40 */
     41static int open_loop_on_busy(const char *name, int flags)
     42{
     43    int rtc;
     44    /*
     45     * Tested with two parallel "hwclock -w" loops.
     46     * With try = 10, no failures with 2x1000000 loop iterations.
     47     */
     48    int try = 1000 / 20;
     49 again:
     50    errno = 0;
     51    rtc = open(name, flags);
     52    if (errno == EBUSY) {
     53        usleep(20 * 1000);
     54        if (--try != 0)
     55            goto again;
     56        /* EBUSY. Last try, exit on error instead of returning -1 */
     57        return xopen(name, flags);
     58    }
     59    return rtc;
     60}
     61
     62/* Never fails */
    3663int FAST_FUNC rtc_xopen(const char **default_rtc, int flags)
    3764{
    3865    int rtc;
     66    const char *name =
     67        "/dev/rtc""\0"
     68        "/dev/rtc0""\0"
     69        "/dev/misc/rtc""\0";
    3970
    40     if (!*default_rtc) {
    41         *default_rtc = "/dev/rtc";
    42         rtc = open(*default_rtc, flags);
     71    if (!*default_rtc)
     72        goto try_name;
     73    name = ""; /*else: we have rtc name, don't try other names */
     74
     75    for (;;) {
     76        rtc = open_loop_on_busy(*default_rtc, flags);
    4377        if (rtc >= 0)
    4478            return rtc;
    45         *default_rtc = "/dev/rtc0";
    46         rtc = open(*default_rtc, flags);
    47         if (rtc >= 0)
    48             return rtc;
    49         *default_rtc = "/dev/misc/rtc";
     79        if (!name[0])
     80            return xopen(*default_rtc, flags);
     81 try_name:
     82        *default_rtc = name;
     83        name += strlen(name) + 1;
    5084    }
    51 
    52     return xopen(*default_rtc, flags);
    5385}
    5486
  • branches/3.3/mindi-busybox/libbb/skip_whitespace.c

    r2725 r3621  
    3434char* FAST_FUNC skip_dev_pfx(const char *tty_name)
    3535{
    36     if (strncmp(tty_name, "/dev/", 5) == 0)
     36    if (is_prefixed_with(tty_name, "/dev/"))
    3737        tty_name += 5;
    3838    return (char*)tty_name;
  • branches/3.3/mindi-busybox/libbb/speed_table.c

    r2725 r3621  
    1111
    1212struct speed_map {
     13#if defined __FreeBSD__
     14    /* On FreeBSD, B<num> constants don't fit into a short */
     15    unsigned speed;
     16#else
    1317    unsigned short speed;
     18#endif
    1419    unsigned short value;
    1520};
  • branches/3.3/mindi-busybox/libbb/strrstr.c

    r2725 r3621  
    88 */
    99
    10 #ifdef __DO_STRRSTR_TEST
    11 #include <stdlib.h>
    12 #include <string.h>
    13 #include <stdio.h>
    14 #else
    1510#include "libbb.h"
    16 #endif
    1711
    1812/*
     
    3529}
    3630
    37 #ifdef __DO_STRRSTR_TEST
    38 int main(int argc, char **argv)
     31#if ENABLE_UNIT_TEST
     32
     33BBUNIT_DEFINE_TEST(strrstr)
    3934{
    4035    static const struct {
     
    6055    while (i < sizeof(test_array) / sizeof(test_array[0])) {
    6156        const char *r = strrstr(test_array[i].h, test_array[i].n);
    62         printf("'%s' vs. '%s': '%s' - ", test_array[i].h, test_array[i].n, r);
    6357        if (r == NULL)
    6458            r = test_array[i].h - 1;
    65         printf("%s\n", r == test_array[i].h + test_array[i].pos ? "PASSED" : "FAILED");
     59        BBUNIT_ASSERT_EQ(r, test_array[i].h + test_array[i].pos);
    6660        i++;
    6761    }
    6862
    69     return 0;
     63    BBUNIT_ENDTEST;
    7064}
    71 #endif
     65
     66#endif /* ENABLE_UNIT_TEST */
  • branches/3.3/mindi-busybox/libbb/time.c

    r3232 r3621  
    2424                    &ptm->tm_hour,
    2525                    &ptm->tm_min,
    26                     &end) >= 2) {
     26                    &end) >= 2
     27        ) {
    2728            /* no adjustments needed */
    2829        } else
     
    3132                    &ptm->tm_mon, &ptm->tm_mday,
    3233                    &ptm->tm_hour, &ptm->tm_min,
    33                     &end) >= 4) {
     34                    &end) >= 4
     35        ) {
    3436            /* Adjust month from 1-12 to 0-11 */
    3537            ptm->tm_mon -= 1;
     
    3941                    &ptm->tm_mon, &ptm->tm_mday,
    4042                    &ptm->tm_hour, &ptm->tm_min,
    41                     &end) >= 5) {
    42             ptm->tm_year -= 1900; /* Adjust years */
    43             ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */
    44         } else
     43                    &end) >= 5
    4544        /* yyyy-mm-dd HH:MM */
    46         if (sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year,
     45         || sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year,
    4746                    &ptm->tm_mon, &ptm->tm_mday,
    4847                    &ptm->tm_hour, &ptm->tm_min,
    49                     &end) >= 5) {
     48                    &end) >= 5
     49        ) {
    5050            ptm->tm_year -= 1900; /* Adjust years */
    5151            ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */
     
    5959        } else
    6060#endif
    61 //TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes)
    6261        {
    6362            bb_error_msg_and_die(bb_msg_invalid_date, date_str);
     
    6968            /* else end != NUL and we error out */
    7069        }
    71     } else if (date_str[0] == '@') {
     70    } else
     71    if (strchr(date_str, '-')
     72        /* Why strchr('-') check?
     73         * sscanf below will trash ptm->tm_year, this breaks
     74         * if parse_str is "10101010" (iow, "MMddhhmm" form)
     75         * because we destroy year. Do these sscanf
     76         * only if we saw a dash in parse_str.
     77         */
     78        /* yyyy-mm-dd HH */
     79     && (sscanf(date_str, "%u-%u-%u %u%c", &ptm->tm_year,
     80                &ptm->tm_mon, &ptm->tm_mday,
     81                &ptm->tm_hour,
     82                &end) >= 4
     83        /* yyyy-mm-dd */
     84         || sscanf(date_str, "%u-%u-%u%c", &ptm->tm_year,
     85                &ptm->tm_mon, &ptm->tm_mday,
     86                &end) >= 3
     87        )
     88    ) {
     89        ptm->tm_year -= 1900; /* Adjust years */
     90        ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */
     91    } else
     92    if (date_str[0] == '@') {
    7293        time_t t = bb_strtol(date_str + 1, NULL, 10);
    7394        if (!errno) {
     
    166187            bb_error_msg_and_die(bb_msg_invalid_date, date_str);
    167188        }
     189        ptm->tm_sec = 0; /* assume zero if [.SS] is not given */
    168190        if (end == '.') {
    169191            /* xxx.SS */
     
    188210}
    189211
     212static char* strftime_fmt(char *buf, unsigned len, time_t *tp, const char *fmt)
     213{
     214    time_t t;
     215    if (!tp) {
     216        tp = &t;
     217        time(tp);
     218    }
     219    /* Returns pointer to NUL */
     220    return buf + strftime(buf, len, fmt, localtime(tp));
     221}
     222
     223char* FAST_FUNC strftime_HHMMSS(char *buf, unsigned len, time_t *tp)
     224{
     225    return strftime_fmt(buf, len, tp, "%H:%M:%S");
     226}
     227
     228char* FAST_FUNC strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp)
     229{
     230    return strftime_fmt(buf, len, tp, "%Y-%m-%d %H:%M:%S");
     231}
     232
    190233#if ENABLE_MONOTONIC_SYSCALL
    191234
  • branches/3.3/mindi-busybox/libbb/u_signal_names.c

    r3232 r3621  
    2020 * HPPA: SIGSTKFLT == 36. */
    2121
    22 static const char signals[][7] = {
     22static const char signals[][7] ALIGN1 = {
    2323    // SUSv3 says kill must support these, and specifies the numerical values,
    2424    // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
  • branches/3.3/mindi-busybox/libbb/udp_io.c

    r3232 r3621  
    1717{
    1818#ifdef IP_PKTINFO
    19     setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int));
     19    setsockopt_1(fd, IPPROTO_IP, IP_PKTINFO);
    2020#endif
    2121#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
    22     setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int));
     22    setsockopt_1(fd, IPPROTO_IPV6, IPV6_PKTINFO);
    2323#endif
    2424}
  • branches/3.3/mindi-busybox/libbb/unicode.c

    r3232 r3621  
    2929    size_t width;
    3030
     31    /* We pass "" instead of "C" because some libc's have
     32     * non-ASCII default locale for setlocale("") call
     33     * (this allows users of such libc to have Unicoded
     34     * system without having to mess with env).
     35     *
     36     * We set LC_CTYPE because (a) we may be called with $LC_CTYPE
     37     * value in LANG, not with $LC_ALL, (b) internationalized
     38     * LC_NUMERIC and LC_TIME are more PITA than benefit
     39     * (for one, some utilities have hard time with comma
     40     * used as a fractional separator).
     41     */
    3142//TODO: avoid repeated calls by caching last string?
    32     setlocale(LC_ALL, (LANG && LANG[0]) ? LANG : "C");
     43    setlocale(LC_CTYPE, LANG ? LANG : "");
    3344
    3445    /* In unicode, this is a one character string */
    35 // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
    36     width = mbstowcs(NULL, unicode_0x394, INT_MAX);
     46    width = unicode_strlen(unicode_0x394);
    3747    unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF);
    3848}
     
    4050void FAST_FUNC init_unicode(void)
    4151{
    42     if (unicode_status == UNICODE_UNKNOWN)
    43         reinit_unicode(getenv("LANG"));
     52    /* Some people set only $LC_CTYPE, not $LC_ALL, because they want
     53     * only Unicode to be activated on their system, not the whole
     54     * shebang of wrong decimal points, strange date formats and so on.
     55     */
     56    if (unicode_status == UNICODE_UNKNOWN) {
     57        char *s = getenv("LC_ALL");
     58        if (!s) s = getenv("LC_CTYPE");
     59        if (!s) s = getenv("LANG");
     60        reinit_unicode(s);
     61    }
    4462}
    4563
     
    5977void FAST_FUNC init_unicode(void)
    6078{
    61     if (unicode_status == UNICODE_UNKNOWN)
    62         reinit_unicode(getenv("LANG"));
     79    if (unicode_status == UNICODE_UNKNOWN) {
     80        char *s = getenv("LC_ALL");
     81        if (!s) s = getenv("LC_CTYPE");
     82        if (!s) s = getenv("LANG");
     83        reinit_unicode(s);
     84    }
    6385}
    6486# endif
     
    964986/* The rest is mostly same for libc and for "homegrown" support */
    965987
    966 #if 0 // UNUSED
    967988size_t FAST_FUNC unicode_strlen(const char *string)
    968989{
     
    972993    return width;
    973994}
    974 #endif
    975995
    976996size_t FAST_FUNC unicode_strwidth(const char *string)
  • branches/3.3/mindi-busybox/libbb/update_passwd.c

    r2725 r3621  
    6363    or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd
    6464
     65 8) delete a user from all groups: update_passwd(FILE, NULL, NULL, MEMBER)
     66
    6567 This function does not validate the arguments fed to it
    6668 so the calling program should take care of that.
     
    8385    char *sfx_char;
    8486    char *name_colon;
    85     unsigned user_len;
    8687    int old_fd;
    8788    int new_fd;
     
    100101        return ret;
    101102
    102     check_selinux_update_passwd(name);
     103    if (name)
     104        check_selinux_update_passwd(name);
    103105
    104106    /* New passwd file, "/etc/passwd+" for now */
    105107    fnamesfx = xasprintf("%s+", filename);
    106108    sfx_char = &fnamesfx[strlen(fnamesfx)-1];
    107     name_colon = xasprintf("%s:", name);
    108     user_len = strlen(name_colon);
     109    name_colon = xasprintf("%s:", name ? name : "");
    109110
    110111    if (shadow)
     
    168169        if (!line) /* EOF/error */
    169170            break;
    170         if (strncmp(name_colon, line, user_len) != 0) {
     171
     172        if (!name && member) {
     173            /* Delete member from all groups */
     174            /* line is "GROUP:PASSWD:[member1[,member2]...]" */
     175            unsigned member_len = strlen(member);
     176            char *list = strrchr(line, ':');
     177            while (list) {
     178                list++;
     179 next_list_element:
     180                if (is_prefixed_with(list, member)) {
     181                    char c;
     182                    changed_lines++;
     183                    c = list[member_len];
     184                    if (c == '\0') {
     185                        if (list[-1] == ',')
     186                            list--;
     187                        *list = '\0';
     188                        break;
     189                    }
     190                    if (c == ',') {
     191                        overlapping_strcpy(list, list + member_len + 1);
     192                        goto next_list_element;
     193                    }
     194                    changed_lines--;
     195                }
     196                list = strchr(list, ',');
     197            }
    171198            fprintf(new_fp, "%s\n", line);
    172199            goto next;
    173200        }
    174201
     202        cp = is_prefixed_with(line, name_colon);
     203        if (!cp) {
     204            fprintf(new_fp, "%s\n", line);
     205            goto next;
     206        }
     207
    175208        /* We have a match with "name:"... */
    176         cp = line + user_len; /* move past name: */
     209        /* cp points past "name:" */
    177210
    178211#if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP
  • branches/3.3/mindi-busybox/libbb/utmp.c

    r3232 r3621  
    1717void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname)
    1818{
    19     struct utmp utent;
     19    struct utmpx utent;
    2020    char *id;
    2121    unsigned width;
     
    4646    strncpy(id, tty_name, width);
    4747
    48     touch(_PATH_UTMP);
    49     //utmpname(_PATH_UTMP);
    50     setutent();
     48    touch(_PATH_UTMPX);
     49    //utmpxname(_PATH_UTMPX);
     50    setutxent();
    5151    /* Append new one (hopefully, unless we collide on ut_id) */
    52     pututline(&utent);
    53     endutent();
     52    pututxline(&utent);
     53    endutxent();
    5454
    5555#if ENABLE_FEATURE_WTMP
    5656    /* "man utmp" says wtmp file should *not* be created automagically */
    5757    /*touch(bb_path_wtmp_file);*/
    58     updwtmp(bb_path_wtmp_file, &utent);
     58    updwtmpx(bb_path_wtmp_file, &utent);
    5959#endif
    6060}
     
    6565void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname)
    6666{
    67     struct utmp utent;
    68     struct utmp *utp;
     67    struct utmpx utent;
     68    struct utmpx *utp;
    6969
    70     touch(_PATH_UTMP);
    71     //utmpname(_PATH_UTMP);
    72     setutent();
     70    touch(_PATH_UTMPX);
     71    //utmpxname(_PATH_UTMPX);
     72    setutxent();
    7373
    7474    /* Did init/getty/telnetd/sshd/... create an entry for us?
    7575     * It should be (new_type-1), but we'd also reuse
    7676     * any other potentially stale xxx_PROCESS entry */
    77     while ((utp = getutent()) != NULL) {
     77    while ((utp = getutxent()) != NULL) {
    7878        if (utp->ut_pid == pid
    7979        // && ut->ut_line[0]
     
    8989                memset(utp->ut_host, 0, sizeof(utp->ut_host));
    9090            }
    91             /* NB: pututline (see later) searches for matching utent
    92              * using getutid(utent) - we must not change ut_id
     91            /* NB: pututxline (see later) searches for matching utxent
     92             * using getutxid(utent) - we must not change ut_id
    9393             * if we want *exactly this* record to be overwritten!
    9494             */
     
    9696        }
    9797    }
    98     //endutent(); - no need, pututline can deal with (and actually likes)
     98    //endutxent(); - no need, pututxline can deal with (and actually likes)
    9999    //the situation when utmp file is positioned on found record
    100100
     
    103103            write_new_utmp(pid, new_type, tty_name, username, hostname);
    104104        else
    105             endutent();
     105            endutxent();
    106106        return;
    107107    }
    108108
    109     /* Make a copy. We can't use *utp, pututline's internal getutid
     109    /* Make a copy. We can't use *utp, pututxline's internal getutxid
    110110     * will overwrite it before it is used! */
    111111    utent = *utp;
     
    121121
    122122    /* Update, or append new one */
    123     //setutent();
    124     pututline(&utent);
    125     endutent();
     123    //setutxent();
     124    pututxline(&utent);
     125    endutxent();
    126126
    127127#if ENABLE_FEATURE_WTMP
    128128    /* "man utmp" says wtmp file should *not* be created automagically */
    129129    /*touch(bb_path_wtmp_file);*/
    130     updwtmp(bb_path_wtmp_file, &utent);
     130    updwtmpx(bb_path_wtmp_file, &utent);
    131131#endif
    132132}
     133
     134/* man utmp:
     135 * When init(8) finds that a process has exited, it locates its utmp entry
     136 * by ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host
     137 * and ut_time with null bytes.
     138 * [same applies to other processes which maintain utmp entries, like telnetd]
     139 *
     140 * We do not bother actually clearing fields:
     141 * it might be interesting to know who was logged in and from where
     142 */
     143void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid)
     144{
     145    update_utmp(pid, DEAD_PROCESS, NULL, NULL, NULL);
     146}
  • branches/3.3/mindi-busybox/libbb/verror_msg.c

    r2725 r3621  
    1212#endif
    1313
     14#if ENABLE_FEATURE_SYSLOG
     15smallint syslog_level = LOG_ERR;
     16#endif
    1417smallint logmode = LOGMODE_STDIO;
    1518const char *msg_eol = "\n";
     
    1821{
    1922    char *msg, *msg1;
     23    char stack_msg[80];
    2024    int applet_len, strerr_len, msgeol_len, used;
    2125
     
    2529    if (!s) /* nomsg[_and_die] uses NULL fmt */
    2630        s = ""; /* some libc don't like printf(NULL) */
     31
     32    applet_len = strlen(applet_name) + 2; /* "applet: " */
     33    strerr_len = strerr ? strlen(strerr) : 0;
     34    msgeol_len = strlen(msg_eol);
     35
     36    /* This costs ~90 bytes of code, but avoids costly
     37     * malloc()[in vasprintf]+realloc()+memmove()+free() in 99% of cases.
     38     * ~40% speedup.
     39     */
     40    if ((int)sizeof(stack_msg) - applet_len > 0) {
     41        va_list p2;
     42
     43        /* It is not portable to use va_list twice, need to va_copy it */
     44        va_copy(p2, p);
     45        used = vsnprintf(stack_msg + applet_len, (int)sizeof(stack_msg) - applet_len, s, p2);
     46        va_end(p2);
     47        msg = stack_msg;
     48        used += applet_len;
     49        if (used < (int)sizeof(stack_msg) - 3 - msgeol_len - strerr_len)
     50            goto add_pfx_and_sfx;
     51    }
    2752
    2853    used = vasprintf(&msg, s, p);
     
    3560     * children can produce log messages simultaneously. */
    3661
    37     applet_len = strlen(applet_name) + 2; /* "applet: " */
    38     strerr_len = strerr ? strlen(strerr) : 0;
    39     msgeol_len = strlen(msg_eol);
    4062    /* can't use xrealloc: it calls error_msg on failure,
    4163     * that may result in a recursion */
     
    5072        memmove(msg + applet_len, msg, used);
    5173        used += applet_len;
     74 add_pfx_and_sfx:
    5275        strcpy(msg, applet_name);
    5376        msg[applet_len - 2] = ':';
     
    7194#if ENABLE_FEATURE_SYSLOG
    7295    if (logmode & LOGMODE_SYSLOG) {
    73         syslog(LOG_ERR, "%s", msg + applet_len);
     96        syslog(syslog_level, "%s", msg + applet_len);
    7497    }
    7598#endif
    76     free(msg);
     99    if (msg != stack_msg)
     100        free(msg);
    77101}
    78102
  • branches/3.3/mindi-busybox/libbb/vfork_daemon_rexec.c

    r3232 r3621  
    7070
    7171#if ENABLE_FEATURE_PREFER_APPLETS
     72static jmp_buf die_jmp;
     73static void jump(void)
     74{
     75    /* Special case. We arrive here if NOFORK applet
     76     * calls xfunc, which then decides to die.
     77     * We don't die, but jump instead back to caller.
     78     * NOFORK applets still cannot carelessly call xfuncs:
     79     * p = xmalloc(10);
     80     * q = xmalloc(10); // BUG! if this dies, we leak p!
     81     */
     82    /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0).
     83     * This works because exitcodes are bytes,
     84     * run_nofork_applet() ensures that by "& 0xff" */
     85    longjmp(die_jmp, xfunc_error_retval | 0x100);
     86}
     87
    7288struct nofork_save_area {
    7389    jmp_buf die_jmp;
     90    void (*die_func)(void);
    7491    const char *applet_name;
    7592    uint32_t option_mask32;
    76     int die_sleep;
    7793    uint8_t xfunc_error_retval;
    7894};
     
    8096{
    8197    memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
     98    save->die_func = die_func;
    8299    save->applet_name = applet_name;
     100    save->option_mask32 = option_mask32;
    83101    save->xfunc_error_retval = xfunc_error_retval;
    84     save->option_mask32 = option_mask32;
    85     save->die_sleep = die_sleep;
    86102}
    87103static void restore_nofork_data(struct nofork_save_area *save)
    88104{
    89105    memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
     106    die_func = save->die_func;
    90107    applet_name = save->applet_name;
     108    option_mask32 = save->option_mask32;
    91109    xfunc_error_retval = save->xfunc_error_retval;
    92     option_mask32 = save->option_mask32;
    93     die_sleep = save->die_sleep;
    94110}
    95111
     
    100116
    101117    save_nofork_data(&old);
    102 
    103     applet_name = APPLET_NAME(applet_no);
    104118
    105119    xfunc_error_retval = EXIT_FAILURE;
     
    134148        argc++;
    135149
    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 
     150    /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */
     151    die_func = jump;
    141152    rc = setjmp(die_jmp);
    142153    if (!rc) {
     
    145156        char *tmp_argv[argc+1];
    146157        memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
     158        applet_name = tmp_argv[0];
    147159        /* Finally we can call NOFORK applet's main() */
    148160        rc = applet_main[applet_no](argc, tmp_argv);
    149     } else { /* xfunc died in NOFORK applet */
    150         /* in case they meant to return 0... */
    151         if (rc == -2222)
    152             rc = 0;
     161    } else {
     162        /* xfunc died in NOFORK applet */
    153163    }
    154164
  • branches/3.3/mindi-busybox/libbb/xatonum.c

    r2725 r3621  
    6969    return xatou_range(numstr, 0, 0xffff);
    7070}
     71
     72const struct suffix_mult bkm_suffixes[] = {
     73    { "b", 512 },
     74    { "k", 1024 },
     75    { "m", 1024*1024 },
     76    { "", 0 }
     77};
     78
     79const struct suffix_mult cwbkMG_suffixes[] = {
     80    { "c", 1 },
     81    { "w", 2 },
     82    { "b", 512 },
     83    { "kB", 1000 },
     84    { "kD", 1000 },
     85    { "k", 1024 },
     86    { "KB", 1000 }, /* compat with coreutils dd */
     87    { "KD", 1000 }, /* compat with coreutils dd */
     88    { "K", 1024 },  /* compat with coreutils dd */
     89    { "MB", 1000000 },
     90    { "MD", 1000000 },
     91    { "M", 1024*1024 },
     92    { "GB", 1000000000 },
     93    { "GD", 1000000000 },
     94    { "G", 1024*1024*1024 },
     95    /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */
     96    /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */
     97    { "", 0 }
     98};
  • branches/3.3/mindi-busybox/libbb/xconnect.c

    r3232 r3621  
    1515#include "libbb.h"
    1616
     17int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval)
     18{
     19    return setsockopt(fd, level, optname, &optval, sizeof(int));
     20}
     21int FAST_FUNC setsockopt_1(int fd, int level, int optname)
     22{
     23    return setsockopt_int(fd, level, optname, 1);
     24}
     25int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval)
     26{
     27    return setsockopt_int(fd, SOL_SOCKET, optname, optval);
     28}
     29int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname)
     30{
     31    return setsockopt_SOL_SOCKET_int(fd, optname, 1);
     32}
     33
    1734void FAST_FUNC setsockopt_reuseaddr(int fd)
    1835{
    19     setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1));
     36    setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR);
    2037}
    2138int FAST_FUNC setsockopt_broadcast(int fd)
    2239{
    23     return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1));
     40    return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST);
     41}
     42int FAST_FUNC setsockopt_keepalive(int fd)
     43{
     44    return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE);
    2445}
    2546
     
    172193    struct addrinfo hint;
    173194
    174     if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) {
     195    if (ENABLE_FEATURE_UNIX_LOCAL && is_prefixed_with(host, "local:")) {
    175196        struct sockaddr_un *sun;
    176197
  • branches/3.3/mindi-busybox/libbb/xfunc_die.c

    r2725 r3621  
    88 */
    99
    10 /* Keeping it separate allows to NOT suck in stdio for VERY small applets.
     10/* Keeping it separate allows to NOT pull in stdio for VERY small applets.
    1111 * Try building busybox with only "true" enabled... */
    1212
    1313#include "libbb.h"
    1414
    15 int die_sleep;
    16 #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
    17 jmp_buf die_jmp;
    18 #endif
     15void (*die_func)(void);
    1916
    2017void FAST_FUNC xfunc_die(void)
    2118{
    22     if (die_sleep) {
    23         if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
    24          && die_sleep < 0
    25         ) {
    26             /* Special case. We arrive here if NOFORK applet
    27              * calls xfunc, which then decides to die.
    28              * We don't die, but jump instead back to caller.
    29              * NOFORK applets still cannot carelessly call xfuncs:
    30              * p = xmalloc(10);
    31              * q = xmalloc(10); // BUG! if this dies, we leak p!
    32              */
    33             /* -2222 means "zero" (longjmp can't pass 0)
    34              * run_nofork_applet() catches -2222. */
    35             longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
    36         }
    37         sleep(die_sleep);
    38     }
     19    if (die_func)
     20        die_func();
    3921    exit(xfunc_error_retval);
    4022}
  • branches/3.3/mindi-busybox/libbb/xfuncs.c

    r3232 r3621  
    2626
    2727/* Turn on nonblocking I/O on a fd */
    28 void FAST_FUNC ndelay_on(int fd)
     28int FAST_FUNC ndelay_on(int fd)
    2929{
    3030    int flags = fcntl(fd, F_GETFL);
    3131    if (flags & O_NONBLOCK)
    32         return;
     32        return flags;
    3333    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    34 }
    35 
    36 void FAST_FUNC ndelay_off(int fd)
     34    return flags;
     35}
     36
     37int FAST_FUNC ndelay_off(int fd)
    3738{
    3839    int flags = fcntl(fd, F_GETFL);
    3940    if (!(flags & O_NONBLOCK))
    40         return;
     41        return flags;
    4142    fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
     43    return flags;
    4244}
    4345
     
    206208
    207209        // If we can't, it's smaller.
    208 
    209210        } else {
    210211            if (bottom == top) {
     
    270271    return err;
    271272}
     273int FAST_FUNC get_terminal_width(int fd)
     274{
     275    unsigned width;
     276    get_terminal_width_height(fd, &width, NULL);
     277    return width;
     278}
    272279
    273280int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
     
    309316    return 0;
    310317}
     318
     319// Useful when we do know that pid is valid, and we just want to wait
     320// for it to exit. Not existing pid is fatal. waitpid() status is not returned.
     321int FAST_FUNC wait_for_exitstatus(pid_t pid)
     322{
     323    int exit_status, n;
     324
     325    n = safe_waitpid(pid, &exit_status, 0);
     326    if (n < 0)
     327        bb_perror_msg_and_die("waitpid");
     328    return exit_status;
     329}
  • branches/3.3/mindi-busybox/libbb/xfuncs_printf.c

    r3232 r3621  
    113113}
    114114
     115void* FAST_FUNC xmemdup(const void *s, int n)
     116{
     117    return memcpy(xmalloc(n), s, n);
     118}
     119
    115120// Die if we can't open a file and return a FILE* to it.
    116121// Notice we haven't got xfread(), This is for use with fscanf() and friends.
     
    139144{
    140145    return xopen3(pathname, flags, 0666);
     146}
     147
     148// Warn if we can't open a file and return a fd.
     149int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode)
     150{
     151    int ret;
     152
     153    ret = open(pathname, flags, mode);
     154    if (ret < 0) {
     155        bb_perror_msg("can't open '%s'", pathname);
     156    }
     157    return ret;
     158}
     159
     160// Warn if we can't open a file and return a fd.
     161int FAST_FUNC open_or_warn(const char *pathname, int flags)
     162{
     163    return open3_or_warn(pathname, flags, 0666);
    141164}
    142165
     
    150173}
    151174
    152 // Warn if we can't open a file and return a fd.
    153 int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode)
    154 {
    155     int ret;
    156 
    157     ret = open(pathname, flags, mode);
    158     if (ret < 0) {
    159         bb_perror_msg("can't open '%s'", pathname);
    160     }
    161     return ret;
    162 }
    163 
    164 // Warn if we can't open a file and return a fd.
    165 int FAST_FUNC open_or_warn(const char *pathname, int flags)
    166 {
    167     return open3_or_warn(pathname, flags, 0666);
     175int FAST_FUNC xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g)
     176{
     177    int fd;
     178    uid_t old_euid = geteuid();
     179    gid_t old_egid = getegid();
     180
     181    xsetegid(g);
     182    xseteuid(u);
     183
     184    fd = xopen(pathname, flags);
     185
     186    xseteuid(old_euid);
     187    xsetegid(old_egid);
     188
     189    return fd;
    168190}
    169191
     
    352374}
    353375
     376void FAST_FUNC xsetegid(gid_t egid)
     377{
     378    if (setegid(egid)) bb_perror_msg_and_die("setegid");
     379}
     380
     381void FAST_FUNC xseteuid(uid_t euid)
     382{
     383    if (seteuid(euid)) bb_perror_msg_and_die("seteuid");
     384}
     385
    354386// Die if we can't chdir to a new path.
    355387void FAST_FUNC xchdir(const char *path)
     
    357389    if (chdir(path))
    358390        bb_perror_msg_and_die("can't change directory to '%s'", path);
     391}
     392
     393void FAST_FUNC xfchdir(int fd)
     394{
     395    if (fchdir(fd))
     396        bb_perror_msg_and_die("fchdir");
    359397}
    360398
     
    542580char* FAST_FUNC xmalloc_ttyname(int fd)
    543581{
    544     char *buf = xzalloc(128);
    545     int r = ttyname_r(fd, buf, 127);
    546     if (r) {
    547         free(buf);
    548         buf = NULL;
    549     }
    550     return buf;
     582    char buf[128];
     583    int r = ttyname_r(fd, buf, sizeof(buf) - 1);
     584    if (r)
     585        return NULL;
     586    return xstrdup(buf);
    551587}
    552588
     
    624660}
    625661#endif
     662
     663void FAST_FUNC xvfork_parent_waits_and_exits(void)
     664{
     665    pid_t pid;
     666
     667    fflush_all();
     668    pid = xvfork();
     669    if (pid > 0) {
     670        /* Parent */
     671        int exit_status = wait_for_exitstatus(pid);
     672        if (WIFSIGNALED(exit_status))
     673            kill_myself_with_sig(WTERMSIG(exit_status));
     674        _exit(WEXITSTATUS(exit_status));
     675    }
     676    /* Child continues */
     677}
  • branches/3.3/mindi-busybox/libbb/xreadlink.c

    r2725 r3621  
    22/*
    33 * xreadlink.c - safe implementation of readlink.
    4  * Returns a NULL on failure...
     4 * Returns a NULL on failure.
    55 *
    66 * Licensed under GPLv2, see file LICENSE in this source tree.
     
    88
    99#include "libbb.h"
     10
     11/* Some systems (eg Hurd) do not have MAXSYMLINKS definition,
     12 * set it to some reasonable value if it isn't defined */
     13#ifndef MAXSYMLINKS
     14# define MAXSYMLINKS 20
     15#endif
    1016
    1117/*
     
    103109char* FAST_FUNC xmalloc_realpath(const char *path)
    104110{
    105 #if defined(__GLIBC__) && !defined(__UCLIBC__)
     111/* NB: uclibc also defines __GLIBC__
     112 * Therefore the test "if glibc, or uclibc >= 0.9.31" looks a bit weird:
     113 */
     114#if defined(__GLIBC__) && \
     115    (!defined(__UCLIBC__) || UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 31))
    106116    /* glibc provides a non-standard extension */
    107117    /* new: POSIX.1-2008 specifies this behavior as well */
Note: See TracChangeset for help on using the changeset viewer.