Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/libbb


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/libbb
Files:
20 added
27 deleted
81 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/libbb/Config.in

    r821 r1765  
    66menu "Busybox Library Tuning"
    77
    8 config CONFIG_MD5_SIZE_VS_SPEED
     8config PASSWORD_MINLEN
     9    int "Minimum password length"
     10    default 6
     11    range 5 32
     12    help
     13      Minimum allowable password length.
     14
     15config MD5_SIZE_VS_SPEED
    916    int " MD5: Trade Bytes for Speed"
    1017    default 2
     
    2027      3 (smallest)        5.1                4912
    2128
     29config FEATURE_FAST_TOP
     30    bool "Faster /proc scanning code (+100 bytes)"
     31    default n
     32    help
     33      This option makes top (and ps) ~20% faster (or 20% less CPU hungry),
     34      but code size is slightly bigger.
     35
     36config FEATURE_ETC_NETWORKS
     37    bool "Support for /etc/networks"
     38    default n
     39    help
     40      Enable support for network names in /etc/networks. This is
     41      a rarely used feature which allows you to use names
     42      instead of IP/mask pairs in route command.
     43
     44config FEATURE_EDITING
     45    bool "Command line editing"
     46    default n
     47    help
     48      Enable line editing (mainly for shell command line).
     49
     50config FEATURE_EDITING_MAX_LEN
     51    int "Maximum length of input"
     52    range 128 8192
     53    default 1024
     54    depends on FEATURE_EDITING
     55    help
     56      Line editing code uses on-stack buffers for storage.
     57      You may want to decrease this parameter if your target machine
     58      benefits from smaller stack usage.
     59
     60config FEATURE_EDITING_FANCY_KEYS
     61    bool "Additional editing keys"
     62    default n
     63    depends on FEATURE_EDITING
     64    help
     65      Enable additonal editing keys (Ctrl-E, Ctrl-U etc).
     66      Arrow keys, Home/End/Delete and Ctrl-W work even without this option.
     67
     68config FEATURE_EDITING_VI
     69    bool "vi-style line editing commands"
     70    default n
     71    depends on FEATURE_EDITING
     72    help
     73      Enable vi-style line editing.  In shells, this mode can be
     74      turned on and off with "set -o vi" and "set +o vi".
     75
     76config FEATURE_EDITING_HISTORY
     77    int "History size"
     78    range 0 99999
     79    default 15
     80    depends on FEATURE_EDITING
     81    help
     82      Specify command history size.
     83
     84config FEATURE_EDITING_SAVEHISTORY
     85    bool "History saving"
     86    default n
     87    depends on ASH && FEATURE_EDITING
     88    help
     89      Enable history saving in ash shell.
     90
     91config FEATURE_TAB_COMPLETION
     92    bool "Tab completion"
     93    default n
     94    depends on FEATURE_EDITING
     95    help
     96      Enable tab completion.
     97
     98config FEATURE_USERNAME_COMPLETION
     99    bool "Username completion"
     100    default n
     101    depends on FEATURE_TAB_COMPLETION
     102    help
     103      Enable username completion.
     104
     105config FEATURE_EDITING_FANCY_PROMPT
     106    bool "Fancy shell prompts"
     107    default n
     108    depends on FEATURE_EDITING
     109    help
     110      Setting this option allows for prompts to use things like \w and
     111      \$ and escape codes.
     112
     113config MONOTONIC_SYSCALL
     114    bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
     115    default y
     116    help
     117      Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring
     118      time intervals (time, ping, traceroute etc need this).
     119      Probably requires Linux 2.6+. If not selected, gettimeofday
     120      will be used instead (which gives wrong results if date/time
     121      is reset).
     122
     123config IOCTL_HEX2STR_ERROR
     124    bool "Use ioctl names rather than hex values in error messages"
     125    default y
     126    help
     127      Use ioctl names rather than hex values in error messages
     128      (e.g. VT_DISALLOCATE rather than 0x5608). If disabled this
     129      saves about 1400 bytes.
    22130endmenu
  • branches/2.2.5/mindi-busybox/libbb/ask_confirmation.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    2512 */
    2613
    27 #include <stdio.h>
    28 #include <ctype.h>
    2914#include "libbb.h"
    3015
  • branches/2.2.5/mindi-busybox/libbb/bb_askpass.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <string.h>
    13 #include <unistd.h>
    14 #include <fcntl.h>
    15 #include <signal.h>
    1611#include <termios.h>
    17 #include <sys/ioctl.h>
    1812
    1913#include "libbb.h"
    20 #define PWD_BUFFER_SIZE 256
    21 
    2214
    2315/* do nothing signal handler */
     
    2820char *bb_askpass(int timeout, const char * prompt)
    2921{
     22    /* Was static char[BIGNUM] */
     23    enum { sizeof_passwd = 128 };
     24    static char *passwd;
     25
    3026    char *ret;
    31     int i, size;
     27    int i;
    3228    struct sigaction sa;
    3329    struct termios old, new;
    34     static char passwd[PWD_BUFFER_SIZE];
     30
     31    if (!passwd)
     32        passwd = xmalloc(sizeof_passwd);
     33    memset(passwd, 0, sizeof_passwd);
    3534
    3635    tcgetattr(STDIN_FILENO, &old);
    3736    tcflush(STDIN_FILENO, TCIFLUSH);
    38 
    39     size = sizeof(passwd);
    40     ret = passwd;
    41     memset(passwd, 0, size);
    4237
    4338    fputs(prompt, stdout);
     
    5651    }
    5752
    58     if (read(STDIN_FILENO, passwd, size-1) <= 0) {
    59         ret = NULL;
    60     } else {
    61         for(i = 0; i < size && passwd[i]; i++) {
    62             if (passwd[i]== '\r' || passwd[i] == '\n') {
    63                 passwd[i]= 0;
    64                 break;
    65             }
    66         }
     53    ret = NULL;
     54    /* On timeout, read will hopefully be interrupted by SIGALRM,
     55     * and we return NULL */
     56    if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) {
     57        ret = passwd;
     58        i = 0;
     59        /* Last byte is guaranteed to be 0
     60           (read did not overwrite it) */
     61        do {
     62            if (passwd[i] == '\r' || passwd[i] == '\n')
     63                passwd[i] = '\0';
     64        } while (passwd[i++]);
    6765    }
    6866
     
    7270
    7371    tcsetattr(STDIN_FILENO, TCSANOW, &old);
    74     fputs("\n", stdout);
     72    putchar('\n');
    7573    fflush(stdout);
    7674    return ret;
    7775}
    78 
  • branches/2.2.5/mindi-busybox/libbb/bb_do_delay.c

    r821 r1765  
    88 */
    99
    10 #include <time.h>
    11 #include <unistd.h>
    1210#include "libbb.h"
    1311
  • branches/2.2.5/mindi-busybox/libbb/bb_pwd.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    88 */
    99
     10#include "libbb.h"
    1011
    11 #ifdef L_bb_getgrgid
    12   /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
    13   * flexible :
    14   *
    15   * if bufsize is > 0 char *group cannot be set to NULL.
    16   *                   On success groupname is written on static allocated buffer
    17   *                   group (and a pointer to it is returned).
    18   *                   On failure gid as string is written to static allocated
    19   *                   buffer group and NULL is returned.
    20   * if bufsize is = 0 char *group can be set to NULL.
    21   *                   On success groupname is returned.
    22   *                   On failure NULL is returned.
    23   * if bufsize is < 0 char *group can be set to NULL.
    24   *                   On success groupname is returned.
    25   *                   On failure an error message is printed and
    26   *                   the program exits.
    27   */
     12#define assert(x) ((void)0)
    2813
    29 #include "libbb.h"
    30 #include "grp_.h"
     14/* internal function for bb_getpwuid and bb_getgrgid */
     15/* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
     16 * flexible:
     17 *
     18 * bufsize > 0:      If idname is not NULL it is copied to buffer,
     19 *                   and buffer is returned. Else id as string is written
     20 *                   to buffer, and NULL is returned.
     21 *
     22 * bufsize == 0:     idname is returned.
     23 *
     24 * bufsize < 0:      If idname is not NULL it is returned.
     25 *                   Else an error message is printed and the program exits.
     26 */
     27static char* bb_getug(char *buffer, int bufsize, char *idname, long id, char prefix)
     28{
     29    if (bufsize > 0) {
     30        assert(buffer != NULL);
     31        if (idname) {
     32            return safe_strncpy(buffer, idname, bufsize);
     33        }
     34        snprintf(buffer, bufsize, "%ld", id);
     35    } else if (bufsize < 0 && !idname) {
     36        bb_error_msg_and_die("unknown %cid %ld", prefix, id);
     37    }
     38    return idname;
     39}
    3140
     41/* bb_getpwuid, bb_getgrgid:
     42 * bb_getXXXid(buf, bufsz, id) - copy user/group name or id
     43 *               as a string to buf, return user/group name or NULL
     44 * bb_getXXXid(NULL, 0, id) - return user/group name or NULL
     45 * bb_getXXXid(NULL, -1, id) - return user/group name or exit
     46 */
     47/* gets a username given a uid */
     48char* bb_getpwuid(char *name, int bufsize, long uid)
     49{
     50    struct passwd *myuser = getpwuid(uid);
     51
     52    return bb_getug(name, bufsize,
     53            (myuser ? myuser->pw_name : (char*)myuser),
     54            uid, 'u');
     55}
    3256/* gets a groupname given a gid */
    33 char * bb_getgrgid(char *group, long gid, int bufsize)
     57char* bb_getgrgid(char *group, int bufsize, long gid)
    3458{
    3559    struct group *mygroup = getgrgid(gid);
    3660
    37     return  bb_getug(group, (mygroup) ?
    38             mygroup->gr_name : (char *)mygroup, gid, bufsize, 'g');
     61    return bb_getug(group, bufsize,
     62            (mygroup ? mygroup->gr_name : (char*)mygroup),
     63            gid, 'g');
    3964}
    40 #endif /* L_bb_getgrgid */
    41 
    42 #ifdef L_bb_xgetgrnam
    43 #include <stdio.h>
    44 #include <string.h>
    45 #include "libbb.h"
    46 #include "pwd_.h"
    47 #include "grp_.h"
    48 
    4965
    5066/* returns a gid given a group name */
    51 long bb_xgetgrnam(const char *name)
     67long xgroup2gid(const char *name)
    5268{
    5369    struct group *mygroup;
    5470
    55     mygroup  = getgrnam(name);
    56     if (mygroup==NULL)
     71    mygroup = getgrnam(name);
     72    if (mygroup == NULL)
    5773        bb_error_msg_and_die("unknown group name: %s", name);
    5874
    59     return (mygroup->gr_gid);
     75    return mygroup->gr_gid;
    6076}
    61 #endif /* L_bb_xgetgrnam */
    62 
    63 #ifdef L_bb_xgetpwnam
    64 #include <stdio.h>
    65 #include <string.h>
    66 #include "libbb.h"
    67 #include "pwd_.h"
    68 #include "grp_.h"
    69 
    7077
    7178/* returns a uid given a username */
    72 long bb_xgetpwnam(const char *name)
     79long xuname2uid(const char *name)
    7380{
    7481    struct passwd *myuser;
    7582
    76     myuser  = getpwnam(name);
    77     if (myuser==NULL)
     83    myuser = getpwnam(name);
     84    if (myuser == NULL)
    7885        bb_error_msg_and_die("unknown user name: %s", name);
    7986
    8087    return myuser->pw_uid;
    8188}
    82 #endif /* L_bb_xgetpwnam */
    83 
    84 #ifdef L_bb_getpwuid
    85  /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
    86   * flexible :
    87   *
    88   * if bufsize is > 0 char *name can not be set to NULL.
    89   *                   On success username is written on the static allocated
    90   *                   buffer name (and a pointer to it is returned).
    91   *                   On failure uid as string is written to the static
    92   *                   allocated buffer name and NULL is returned.
    93   * if bufsize is = 0 char *name can be set to NULL.
    94   *                   On success username is returned.
    95   *                   On failure NULL is returned.
    96   * if bufsize is < 0 char *name can be set to NULL
    97   *                   On success username is returned.
    98   *                   On failure an error message is printed and
    99   *                   the program exits.
    100   */
    101 
    102 #include "libbb.h"
    103 #include "pwd_.h"
    104 
    105 /* gets a username given a uid */
    106 char * bb_getpwuid(char *name, long uid, int bufsize)
    107 {
    108     struct passwd *myuser = getpwuid(uid);
    109 
    110     return  bb_getug(name, (myuser) ?
    111             myuser->pw_name : (char *)myuser , uid, bufsize, 'u');
    112 }
    113 #endif /* L_bb_getpwuid */
    114 
    115 #ifdef L_bb_getug
    116  /*
    117   * if bufsize is > 0 char *buffer can not be set to NULL.
    118   *                   If idname is not NULL it is written on the static
    119   *                   allocated buffer (and a pointer to it is returned).
    120   *                   if idname is NULL, id as string is written to the static
    121   *                   allocated buffer and NULL is returned.
    122   * if bufsize is = 0 char *buffer can be set to NULL.
    123   *                   If idname exists a pointer to it is returned,
    124   *                   else NULL is returned.
    125   * if bufsize is < 0 char *buffer can be set to NULL.
    126   *                   If idname exists a pointer to it is returned,
    127   *                   else an error message is printed and the program exits.
    128   */
    129 
    130 #include <stdio.h>
    131 #include <assert.h>
    132 #include "libbb.h"
    133 
    134 
    135 /* internal function for bb_getpwuid and bb_getgrgid */
    136 char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix)
    137 {
    138     if(bufsize > 0 ) {
    139         assert(buffer!=NULL);
    140         if(idname) {
    141             return safe_strncpy(buffer, idname, bufsize);
    142         }
    143         snprintf(buffer, bufsize, "%ld", id);
    144     } else if(bufsize < 0 && !idname) {
    145         bb_error_msg_and_die("unknown %cid %ld", prefix, id);
    146     }
    147     return idname;
    148 }
    149 #endif /* L_bb_getug */
    150 
    151 
    152 #ifdef L_get_ug_id
    153 /* indirect dispatcher for pwd helpers.  */
    154 #include <stdlib.h>
    155 #include "libbb.h"
    15689
    15790unsigned long get_ug_id(const char *s,
    158         long (*__bb_getxxnam)(const char *))
     91        long (*xname2id)(const char *))
    15992{
    16093    unsigned long r;
    161     char *p;
    16294
    163     r = strtoul(s, &p, 10);
    164     if (*p || (s == p)) {
    165         r = __bb_getxxnam(s);
    166     }
    167 
     95    r = bb_strtoul(s, NULL, 10);
     96    if (errno)
     97        return xname2id(s);
    16898    return r;
    16999}
    170 #endif /* L_get_ug_id */
  • branches/2.2.5/mindi-busybox/libbb/change_identity.c

    r821 r1765  
    2929 */
    3030
    31 #include <stdio.h>
    32 #include <errno.h>
    33 #include <unistd.h>
    34 #include <string.h>
    35 #include <stdlib.h>
    36 #include <syslog.h>
    37 #include <ctype.h>
    38 
    3931#include "libbb.h"
    4032
    4133
    4234/* Become the user and group(s) specified by PW.  */
    43 const char *change_identity_e2str ( const struct passwd *pw )
     35const char *change_identity_e2str(const struct passwd *pw)
    4436{
    45     if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 )
     37    if (initgroups(pw->pw_name, pw->pw_gid) == -1)
    4638        return "cannot set groups";
    47     endgrent ( );
    48 
    49     if ( setgid ( pw-> pw_gid ))
    50         return "cannot set group id";
    51     if ( setuid ( pw->pw_uid ))
    52         return "cannot set user id";
     39    endgrent(); /* ?? */
     40    xsetgid(pw->pw_gid);
     41    xsetuid(pw->pw_uid);
    5342    return NULL;
    5443}
    5544
    56 void change_identity ( const struct passwd *pw )
     45void change_identity(const struct passwd *pw)
    5746{
    5847    const char *err_msg = change_identity_e2str(pw);
    5948
    60     if(err_msg)
    61         bb_perror_msg_and_die ( "%s", err_msg );
     49    if (err_msg)
     50        bb_perror_msg_and_die("%s", err_msg);
    6251}
  • branches/2.2.5/mindi-busybox/libbb/chomp.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <string.h>
    1311#include "libbb.h"
    14 
    1512
    1613void chomp(char *s)
     
    1815    char *lc = last_char_is(s, '\n');
    1916
    20     if(lc)
    21         *lc = 0;
     17    if (lc)
     18        *lc = '\0';
    2219}
  • branches/2.2.5/mindi-busybox/libbb/compare_string_array.c

    r821 r1765  
    1 /* vi:set ts=4:*/
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    44 */
    55
    6 #include <string.h>
    76#include "libbb.h"
    87
    9 /* returns the array number of the string */
    10 int compare_string_array(const char * const string_array[], const char *key)
     8/* returns the array index of the string */
     9/* (index of first match is returned, or -1) */
     10int index_in_str_array(const char *const string_array[], const char *key)
    1111{
    1212    int i;
     
    1717        }
    1818    }
    19     return -i;
     19    return -1;
    2020}
    2121
     22int index_in_strings(const char *strings, const char *key)
     23{
     24    int idx = 0;
     25
     26    while (strings[0]) {
     27        if (strcmp(strings, key) == 0) {
     28            return idx;
     29        }
     30        strings += strlen(strings) + 1; /* skip NUL */
     31        idx++;
     32    }
     33    return -1;
     34}
     35
     36/* returns the array index of the string, even if it matches only a beginning */
     37/* (index of first match is returned, or -1) */
     38#ifdef UNUSED
     39int index_in_substr_array(const char *const string_array[], const char *key)
     40{
     41    int i;
     42    int len = strlen(key);
     43    if (len) {
     44        for (i = 0; string_array[i] != 0; i++) {
     45            if (strncmp(string_array[i], key, len) == 0) {
     46                return i;
     47            }
     48        }
     49    }
     50    return -1;
     51}
     52#endif
     53
     54int index_in_substrings(const char *strings, const char *key)
     55{
     56    int len = strlen(key);
     57
     58    if (len) {
     59        int idx = 0;
     60        while (strings[0]) {
     61            if (strncmp(strings, key, len) == 0) {
     62                return idx;
     63            }
     64            strings += strlen(strings) + 1; /* skip NUL */
     65            idx++;
     66        }
     67    }
     68    return -1;
     69}
  • branches/2.2.5/mindi-busybox/libbb/concat_path_file.c

    r821 r1765  
    66 * If you wrote this, please acknowledge your work.
    77 *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful, but
    14  * WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    16  * General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    21  * USA
     8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    229 */
    2310
    2411/* concatenate path and file name to new allocation buffer,
    25  * not addition '/' if path name already have '/'
     12 * not adding '/' if path name already has '/'
    2613*/
    2714
    28 #include <string.h>
    2915#include "libbb.h"
    3016
     
    3824    while (*filename == '/')
    3925        filename++;
    40     return bb_xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename);
     26    return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename);
    4127}
  • branches/2.2.5/mindi-busybox/libbb/concat_subpath_file.c

    r821 r1765  
    55 * Copyright (C) (C) 2003  Vladimir Oleynik  <dzo@simtreas.ru>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful, but
    13  * WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    20  * USA
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    2411   This function make special for recursive actions with usage
    2512   concat_path_file(path, filename)
    26    and skiping "." and ".." directory entries
     13   and skipping "." and ".." directory entries
    2714*/
    2815
     
    3118char *concat_subpath_file(const char *path, const char *f)
    3219{
    33     if(f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2])))
     20    if (f && DOT_OR_DOTDOT(f))
    3421        return NULL;
    3522    return concat_path_file(path, f);
  • branches/2.2.5/mindi-busybox/libbb/copy_file.c

    r821 r1765  
    44 *
    55 * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
     6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
    67 *
    78 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     
    1011
    1112#include "libbb.h"
    12 #include <utime.h>
    13 #include <errno.h>
    14 
     13
     14// POSIX: if exists and -i, ask (w/o -i assume yes).
     15// Then open w/o EXCL (yes, not unlink!).
     16// If open still fails and -f, try unlink, then try open again.
     17// Result: a mess:
     18// If dest is a softlink, we overwrite softlink's destination!
     19// (or fail, if it points to dir/nonexistent location/etc).
     20// This is strange, but POSIX-correct.
     21// coreutils cp has --remove-destination to override this...
     22//
     23// NB: we have special code which still allows for "cp file /dev/node"
     24// to work POSIX-ly (the only realistic case where it makes sense)
     25
     26#define DO_POSIX_CP 0  /* 1 - POSIX behavior, 0 - safe behavior */
     27
     28// errno must be set to relevant value ("why we cannot create dest?")
     29// for POSIX mode to give reasonable error message
     30static int ask_and_unlink(const char *dest, int flags)
     31{
     32#if DO_POSIX_CP
     33    if (!(flags & (FILEUTILS_FORCE|FILEUTILS_INTERACTIVE))) {
     34        // Either it exists, or the *path* doesnt exist
     35        bb_perror_msg("cannot create '%s'", dest);
     36        return -1;
     37    }
     38#endif
     39    // If !DO_POSIX_CP, act as if -f is always in effect - we don't want
     40    // "cannot create" msg, we want unlink to be done (silently unless -i).
     41
     42    // TODO: maybe we should do it only if ctty is present?
     43    if (flags & FILEUTILS_INTERACTIVE) {
     44        // We would not do POSIX insanity. -i asks,
     45        // then _unlinks_ the offender. Presto.
     46        // (No "opening without O_EXCL", no "unlink only if -f")
     47        // Or else we will end up having 3 open()s!
     48        fprintf(stderr, "%s: overwrite '%s'? ", applet_name, dest);
     49        if (!bb_ask_confirmation())
     50            return 0; // not allowed to overwrite
     51    }
     52    if (unlink(dest) < 0) {
     53        bb_perror_msg("cannot remove '%s'", dest);
     54        return -1; // error
     55    }
     56    return 1; // ok (to try again)
     57}
     58
     59/* Return:
     60 * -1 error, copy not made
     61 *  0 copy is made or user answered "no" in interactive mode
     62 *    (failures to preserve mode/owner/times are not reported in exit code)
     63 */
    1564int copy_file(const char *source, const char *dest, int flags)
    1665{
     66    /* This is a recursive function, try to minimize stack usage */
     67    /* NB: each struct stat is ~100 bytes */
    1768    struct stat source_stat;
    1869    struct stat dest_stat;
    19     int dest_exists = 0;
    20     int status = 0;
    21 
    22     if ((!(flags & FILEUTILS_DEREFERENCE) &&
    23             lstat(source, &source_stat) < 0) ||
    24             ((flags & FILEUTILS_DEREFERENCE) &&
    25              stat(source, &source_stat) < 0)) {
    26         bb_perror_msg("%s", source);
     70    signed char retval = 0;
     71    signed char dest_exists = 0;
     72    signed char ovr;
     73
     74#define FLAGS_DEREF (flags & FILEUTILS_DEREFERENCE)
     75
     76    if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) {
     77        // This may be a dangling symlink.
     78        // Making [sym]links to dangling symlinks works, so...
     79        if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK))
     80            goto make_links;
     81        bb_perror_msg("cannot stat '%s'", source);
    2782        return -1;
    2883    }
     
    3085    if (lstat(dest, &dest_stat) < 0) {
    3186        if (errno != ENOENT) {
    32             bb_perror_msg("unable to stat `%s'", dest);
     87            bb_perror_msg("cannot stat '%s'", dest);
    3388            return -1;
    3489        }
    3590    } else {
    36         if (source_stat.st_dev == dest_stat.st_dev &&
    37             source_stat.st_ino == dest_stat.st_ino)
    38         {
    39             bb_error_msg("`%s' and `%s' are the same file", source, dest);
     91        if (source_stat.st_dev == dest_stat.st_dev
     92         && source_stat.st_ino == dest_stat.st_ino
     93        ) {
     94            bb_error_msg("'%s' and '%s' are the same file", source, dest);
    4095            return -1;
    4196        }
    4297        dest_exists = 1;
    4398    }
     99
     100#if ENABLE_SELINUX
     101    if ((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) && is_selinux_enabled() > 0) {
     102        security_context_t con;
     103        if (lgetfilecon(source, &con) >= 0) {
     104            if (setfscreatecon(con) < 0) {
     105                bb_perror_msg("cannot set setfscreatecon %s", con);
     106                freecon(con);
     107                return -1;
     108            }
     109        } else if (errno == ENOTSUP || errno == ENODATA) {
     110            setfscreatecon_or_die(NULL);
     111        } else {
     112            bb_perror_msg("cannot lgetfilecon %s", source);
     113            return -1;
     114        }
     115    }
     116#endif
    44117
    45118    if (S_ISDIR(source_stat.st_mode)) {
    46119        DIR *dp;
     120        const char *tp;
    47121        struct dirent *d;
    48122        mode_t saved_umask = 0;
    49123
    50124        if (!(flags & FILEUTILS_RECUR)) {
    51             bb_error_msg("%s: omitting directory", source);
    52             return -1;
    53         }
    54 
    55         /* Create DEST.  */
     125            bb_error_msg("omitting directory '%s'", source);
     126            return -1;
     127        }
     128
     129        /* Did we ever create source ourself before? */
     130        tp = is_in_ino_dev_hashtable(&source_stat);
     131        if (tp) {
     132            /* We did! it's a recursion! man the lifeboats... */
     133            bb_error_msg("recursion detected, omitting directory '%s'",
     134                    source);
     135            return -1;
     136        }
     137
     138        /* Create DEST */
    56139        if (dest_exists) {
    57140            if (!S_ISDIR(dest_stat.st_mode)) {
    58                 bb_error_msg("`%s' is not a directory", dest);
    59                 return -1;
    60             }
     141                bb_error_msg("target '%s' is not a directory", dest);
     142                return -1;
     143            }
     144            /* race here: user can substitute a symlink between
     145             * this check and actual creation of files inside dest */
    61146        } else {
    62147            mode_t mode;
     
    66151            if (!(flags & FILEUTILS_PRESERVE_STATUS))
    67152                mode = source_stat.st_mode & ~saved_umask;
     153            /* Allow owner to access new dir (at least for now) */
    68154            mode |= S_IRWXU;
    69 
    70155            if (mkdir(dest, mode) < 0) {
    71156                umask(saved_umask);
    72                 bb_perror_msg("cannot create directory `%s'", dest);
    73                 return -1;
    74             }
    75 
     157                bb_perror_msg("cannot create directory '%s'", dest);
     158                return -1;
     159            }
    76160            umask(saved_umask);
    77         }
    78 
    79         /* Recursively copy files in SOURCE.  */
    80         if ((dp = bb_opendir(source)) == NULL) {
    81             status = -1;
    82             goto preserve_status;
     161            /* need stat info for add_to_ino_dev_hashtable */
     162            if (lstat(dest, &dest_stat) < 0) {
     163                bb_perror_msg("cannot stat '%s'", dest);
     164                return -1;
     165            }
     166        }
     167        /* remember (dev,inode) of each created dir.
     168         * NULL: name is not remembered */
     169        add_to_ino_dev_hashtable(&dest_stat, NULL);
     170
     171        /* Recursively copy files in SOURCE */
     172        dp = opendir(source);
     173        if (dp == NULL) {
     174            retval = -1;
     175            goto preserve_mode_ugid_time;
    83176        }
    84177
     
    87180
    88181            new_source = concat_subpath_file(source, d->d_name);
    89             if(new_source == NULL)
     182            if (new_source == NULL)
    90183                continue;
    91184            new_dest = concat_path_file(dest, d->d_name);
    92185            if (copy_file(new_source, new_dest, flags) < 0)
    93                 status = -1;
     186                retval = -1;
    94187            free(new_source);
    95188            free(new_dest);
    96189        }
    97         /* closedir have only EBADF error, but "dp" not changes */
    98190        closedir(dp);
    99191
    100         if (!dest_exists &&
    101                 chmod(dest, source_stat.st_mode & ~saved_umask) < 0) {
    102             bb_perror_msg("unable to change permissions of `%s'", dest);
    103             status = -1;
    104         }
    105     } else if (S_ISREG(source_stat.st_mode) ||
    106            (S_ISLNK(source_stat.st_mode) && (flags & FILEUTILS_DEREFERENCE)))
    107     {
     192        if (!dest_exists
     193         && chmod(dest, source_stat.st_mode & ~saved_umask) < 0
     194        ) {
     195            bb_perror_msg("cannot preserve %s of '%s'", "permissions", dest);
     196            /* retval = -1; - WRONG! copy *WAS* made */
     197        }
     198        goto preserve_mode_ugid_time;
     199    }
     200
     201    if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) {
     202        int (*lf)(const char *oldpath, const char *newpath);
     203 make_links:
     204        // Hmm... maybe
     205        // if (DEREF && MAKE_SOFTLINK) source = realpath(source) ?
     206        // (but realpath returns NULL on dangling symlinks...)
     207        lf = (flags & FILEUTILS_MAKE_SOFTLINK) ? symlink : link;
     208        if (lf(source, dest) < 0) {
     209            ovr = ask_and_unlink(dest, flags);
     210            if (ovr <= 0)
     211                return ovr;
     212            if (lf(source, dest) < 0) {
     213                bb_perror_msg("cannot create link '%s'", dest);
     214                return -1;
     215            }
     216        }
     217        /* _Not_ jumping to preserve_mode_ugid_time:
     218         * hard/softlinks don't have those */
     219        return 0;
     220    }
     221
     222    if (S_ISREG(source_stat.st_mode)
     223     /* DEREF uses stat, which never returns S_ISLNK() == true. */
     224     /* || (FLAGS_DEREF && S_ISLNK(source_stat.st_mode)) */
     225    ) {
    108226        int src_fd;
    109227        int dst_fd;
    110         if (ENABLE_FEATURE_PRESERVE_HARDLINKS) {
    111             char *link_name;
    112 
    113             if (!(flags & FILEUTILS_DEREFERENCE) &&
    114                     is_in_ino_dev_hashtable(&source_stat, &link_name)) {
    115                 if (link(link_name, dest) < 0) {
    116                     bb_perror_msg("unable to link `%s'", dest);
     228
     229        if (ENABLE_FEATURE_PRESERVE_HARDLINKS && !FLAGS_DEREF) {
     230            const char *link_target;
     231            link_target = is_in_ino_dev_hashtable(&source_stat);
     232            if (link_target) {
     233                if (link(link_target, dest) < 0) {
     234                    ovr = ask_and_unlink(dest, flags);
     235                    if (ovr <= 0)
     236                        return ovr;
     237                    if (link(link_target, dest) < 0) {
     238                        bb_perror_msg("cannot create link '%s'", dest);
     239                        return -1;
     240                    }
     241                }
     242                return 0;
     243            }
     244            add_to_ino_dev_hashtable(&source_stat, dest);
     245        }
     246
     247        src_fd = open_or_warn(source, O_RDONLY);
     248        if (src_fd < 0)
     249            return -1;
     250
     251        /* POSIX way is a security problem versus symlink attacks,
     252         * we do it only for non-symlinks, and only for non-recursive,
     253         * non-interactive cp. NB: it is still racy
     254         * for "cp file /home/bad_user/file" case
     255         * (user can rm file and create a link to /etc/passwd) */
     256        if (DO_POSIX_CP
     257         || (dest_exists && !(flags & (FILEUTILS_RECUR|FILEUTILS_INTERACTIVE))
     258             && !S_ISLNK(dest_stat.st_mode))
     259        ) {
     260            dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, source_stat.st_mode);
     261        } else  /* safe way: */
     262            dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode);
     263        if (dst_fd == -1) {
     264            ovr = ask_and_unlink(dest, flags);
     265            if (ovr <= 0) {
     266                close(src_fd);
     267                return ovr;
     268            }
     269            /* It shouldn't exist. If it exists, do not open (symlink attack?) */
     270            dst_fd = open3_or_warn(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode);
     271            if (dst_fd < 0) {
     272                close(src_fd);
     273                return -1;
     274            }
     275        }
     276
     277#if ENABLE_SELINUX
     278        if (((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT)
     279            || (flags & FILEUTILS_SET_SECURITY_CONTEXT))
     280         && is_selinux_enabled() > 0
     281        ) {
     282            security_context_t con;
     283            if (getfscreatecon(&con) == -1) {
     284                bb_perror_msg("getfscreatecon");
     285                return -1;
     286            }
     287            if (con) {
     288                if (setfilecon(dest, con) == -1) {
     289                    bb_perror_msg("setfilecon:%s,%s", dest, con);
     290                    freecon(con);
    117291                    return -1;
    118292                }
    119 
    120                 return 0;
    121             }
    122             add_to_ino_dev_hashtable(&source_stat, dest);
    123         }
    124         src_fd = open(source, O_RDONLY);
    125         if (src_fd == -1) {
    126             bb_perror_msg("unable to open `%s'", source);
    127             return(-1);
    128         }
    129 
    130         if (dest_exists) {
    131             if (flags & FILEUTILS_INTERACTIVE) {
    132                 fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest);
    133                 if (!bb_ask_confirmation()) {
    134                     close (src_fd);
    135                     return 0;
    136                 }
    137             }
    138 
    139             dst_fd = open(dest, O_WRONLY|O_TRUNC);
    140             if (dst_fd == -1) {
    141                 if (!(flags & FILEUTILS_FORCE)) {
    142                     bb_perror_msg("unable to open `%s'", dest);
    143                     close(src_fd);
    144                     return -1;
    145                 }
    146 
    147                 if (unlink(dest) < 0) {
    148                     bb_perror_msg("unable to remove `%s'", dest);
    149                     close(src_fd);
    150                     return -1;
    151                 }
    152 
    153                 goto dest_removed;
    154             }
    155         } else {
    156 dest_removed:
    157             dst_fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode);
    158             if (dst_fd == -1) {
    159                 bb_perror_msg("unable to open `%s'", dest);
    160                 close(src_fd);
    161                 return(-1);
    162             }
    163         }
    164 
     293                freecon(con);
     294            }
     295        }
     296#endif
    165297        if (bb_copyfd_eof(src_fd, dst_fd) == -1)
    166             status = -1;
    167 
     298            retval = -1;
     299        /* Ok, writing side I can understand... */
    168300        if (close(dst_fd) < 0) {
    169             bb_perror_msg("unable to close `%s'", dest);
    170             status = -1;
    171         }
    172 
    173         if (close(src_fd) < 0) {
    174             bb_perror_msg("unable to close `%s'", source);
    175             status = -1;
    176         }
    177     } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
    178         S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) ||
    179         S_ISLNK(source_stat.st_mode)) {
    180 
    181         if (dest_exists) {
    182             if((flags & FILEUTILS_FORCE) == 0) {
    183                 fprintf(stderr, "`%s' exists\n", dest);
    184                 return -1;
    185             }
    186             if(unlink(dest) < 0) {
    187                 bb_perror_msg("unable to remove `%s'", dest);
    188                 return -1;
    189             }
    190         }
    191         if (S_ISFIFO(source_stat.st_mode)) {
    192             if (mkfifo(dest, source_stat.st_mode) < 0) {
    193                 bb_perror_msg("cannot create fifo `%s'", dest);
    194                 return -1;
    195             }
    196         } else if (S_ISLNK(source_stat.st_mode)) {
    197             char *lpath;
    198 
    199             lpath = xreadlink(source);
    200             if (symlink(lpath, dest) < 0) {
    201                 bb_perror_msg("cannot create symlink `%s'", dest);
    202                 return -1;
    203             }
     301            bb_perror_msg("cannot close '%s'", dest);
     302            retval = -1;
     303        }
     304        /* ...but read size is already checked by bb_copyfd_eof */
     305        close(src_fd);
     306        goto preserve_mode_ugid_time;
     307    }
     308
     309    /* Source is a symlink or a special file */
     310    /* We are lazy here, a bit lax with races... */
     311    if (dest_exists) {
     312        errno = EEXIST;
     313        ovr = ask_and_unlink(dest, flags);
     314        if (ovr <= 0)
     315            return ovr;
     316    }
     317    if (S_ISLNK(source_stat.st_mode)) {
     318        char *lpath = xmalloc_readlink_or_warn(source);
     319        if (lpath) {
     320            int r = symlink(lpath, dest);
    204321            free(lpath);
    205 
     322            if (r < 0) {
     323                bb_perror_msg("cannot create symlink '%s'", dest);
     324                return -1;
     325            }
    206326            if (flags & FILEUTILS_PRESERVE_STATUS)
    207327                if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
    208                     bb_perror_msg("unable to preserve ownership of `%s'", dest);
    209 
    210             return 0;
    211 
    212         } else {
    213             if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
    214                 bb_perror_msg("unable to create `%s'", dest);
    215                 return -1;
    216             }
     328                    bb_perror_msg("cannot preserve %s of '%s'", "ownership", dest);
     329        }
     330        /* _Not_ jumping to preserve_mode_ugid_time:
     331         * symlinks don't have those */
     332        return 0;
     333    }
     334    if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode)
     335     || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode)
     336    ) {
     337        if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
     338            bb_perror_msg("cannot create '%s'", dest);
     339            return -1;
    217340        }
    218341    } else {
    219         bb_error_msg("internal error: unrecognized file type");
     342        bb_error_msg("unrecognized file '%s' with mode %x", source, source_stat.st_mode);
    220343        return -1;
    221344    }
    222345
    223 preserve_status:
    224 
    225     if (flags & FILEUTILS_PRESERVE_STATUS) {
     346 preserve_mode_ugid_time:
     347
     348    if (flags & FILEUTILS_PRESERVE_STATUS
     349    /* Cannot happen: */
     350    /* && !(flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) */
     351    ) {
    226352        struct utimbuf times;
    227         char *msg="unable to preserve %s of `%s'";
    228353
    229354        times.actime = source_stat.st_atime;
    230355        times.modtime = source_stat.st_mtime;
     356        /* BTW, utimes sets usec-precision time - just FYI */
    231357        if (utime(dest, &times) < 0)
    232             bb_perror_msg(msg, "times", dest);
     358            bb_perror_msg("cannot preserve %s of '%s'", "times", dest);
    233359        if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) {
    234360            source_stat.st_mode &= ~(S_ISUID | S_ISGID);
    235             bb_perror_msg(msg, "ownership", dest);
     361            bb_perror_msg("cannot preserve %s of '%s'", "ownership", dest);
    236362        }
    237363        if (chmod(dest, source_stat.st_mode) < 0)
    238             bb_perror_msg(msg, "permissions", dest);
    239     }
    240 
    241     return status;
     364            bb_perror_msg("cannot preserve %s of '%s'", "permissions", dest);
     365    }
     366
     367    return retval;
    242368}
  • branches/2.2.5/mindi-busybox/libbb/copyfd.c

    r821 r1765  
    88 */
    99
    10 #include <errno.h>
    11 #include <stdlib.h>
    12 #include <string.h>
    13 #include <unistd.h>
    14 
    1510#include "libbb.h"
    16 
    1711
    1812#if BUFSIZ < 4096
     
    2115#endif
    2216
     17/* Used by NOFORK applets (e.g. cat) - must not use xmalloc */
    2318
    24 static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size)
     19static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
    2520{
    2621    int status = -1;
    27     size_t total = 0;
    28     RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
     22    off_t total = 0;
     23    char buffer[BUFSIZ];
    2924
    30     if (src_fd < 0) goto out;
    31     while (!size || total < size)
    32     {
    33         ssize_t wrote, xread;
     25    if (src_fd < 0)
     26        goto out;
    3427
    35         xread = safe_read(src_fd, buffer,
    36                 (!size || size - total > BUFSIZ) ? BUFSIZ : size - total);
     28    if (!size) {
     29        size = BUFSIZ;
     30        status = 1; /* copy until eof */
     31    }
    3732
    38         if (xread > 0) {
    39             /* A -1 dst_fd means we need to fake it... */
    40             wrote = (dst_fd < 0) ? xread : bb_full_write(dst_fd, buffer, xread);
    41             if (wrote < xread) {
     33    while (1) {
     34        ssize_t rd;
     35
     36        rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size);
     37
     38        if (!rd) { /* eof - all done */
     39            status = 0;
     40            break;
     41        }
     42        if (rd < 0) {
     43            bb_perror_msg(bb_msg_read_error);
     44            break;
     45        }
     46        /* dst_fd == -1 is a fake, else... */
     47        if (dst_fd >= 0) {
     48            ssize_t wr = full_write(dst_fd, buffer, rd);
     49            if (wr < rd) {
    4250                bb_perror_msg(bb_msg_write_error);
    4351                break;
    4452            }
    45             total += wrote;
    46             if (total == size) status = 0;
    47         } else if (xread < 0) {
    48             bb_perror_msg(bb_msg_read_error);
    49             break;
    50         } else if (xread == 0) {
    51             /* All done. */
    52             status = 0;
    53             break;
     53        }
     54        total += rd;
     55        if (status < 0) { /* if we aren't copying till EOF... */
     56            size -= rd;
     57            if (!size) {
     58                /* 'size' bytes copied - all done */
     59                status = 0;
     60                break;
     61            }
    5462        }
    5563    }
    56 
    57 out:
    58     RELEASE_CONFIG_BUFFER(buffer);
    59 
    60     return status ? status : (ssize_t)total;
     64 out:
     65    return status ? -1 : total;
    6166}
    6267
    6368
    64 int bb_copyfd_size(int fd1, int fd2, const off_t size)
     69#if 0
     70void complain_copyfd_and_die(off_t sz)
     71{
     72    if (sz != -1)
     73        bb_error_msg_and_die("short read");
     74    /* if sz == -1, bb_copyfd_XX already complained */
     75    xfunc_die();
     76}
     77#endif
     78
     79off_t bb_copyfd_size(int fd1, int fd2, off_t size)
    6580{
    6681    if (size) {
    67         return(bb_full_fd_action(fd1, fd2, size));
     82        return bb_full_fd_action(fd1, fd2, size);
    6883    }
    69     return(0);
     84    return 0;
    7085}
    7186
    72 int bb_copyfd_eof(int fd1, int fd2)
     87void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
    7388{
    74     return(bb_full_fd_action(fd1, fd2, 0));
     89    off_t sz = bb_copyfd_size(fd1, fd2, size);
     90    if (sz == size)
     91        return;
     92    if (sz != -1)
     93        bb_error_msg_and_die("short read");
     94    /* if sz == -1, bb_copyfd_XX already complained */
     95    xfunc_die();
    7596}
     97
     98off_t bb_copyfd_eof(int fd1, int fd2)
     99{
     100    return bb_full_fd_action(fd1, fd2, 0);
     101}
  • branches/2.2.5/mindi-busybox/libbb/correct_password.c

    r821 r1765  
    2929 */
    3030
    31 #include <stdio.h>
    32 #include <errno.h>
    33 #include <unistd.h>
    34 #include <string.h>
    35 #include <stdlib.h>
    36 #include <syslog.h>
    37 #include <ctype.h>
    38 #include <crypt.h>
    39 
    4031#include "libbb.h"
    4132
     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" */
    4238
     39int correct_password(const struct passwd *pw)
     40{
     41    char *unencrypted, *encrypted;
     42    const char *correct;
    4343
    44 /* Ask the user for a password.
    45    Return 1 if the user gives the correct password for entry PW,
    46    0 if not.  Return 1 without asking for a password if run by UID 0
    47    or if PW has an empty password.  */
     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;
     51#if ENABLE_FEATURE_SHADOWPASSWDS
     52    if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) {
     53        /* Using _r function to avoid pulling in static buffers */
     54        struct spwd spw;
     55        struct spwd *result;
     56        char buffer[256];
     57        correct = (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) ? "aa" : spw.sp_pwdp;
     58    }
     59#endif
    4860
    49 int correct_password ( const struct passwd *pw )
    50 {
    51     char *unencrypted, *encrypted, *correct;
    52 
    53 #ifdef CONFIG_FEATURE_SHADOWPASSWDS
    54     if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
    55         struct spwd *sp = getspnam ( pw-> pw_name );
    56 
    57         if ( !sp )
    58             bb_error_msg_and_die ( "\nno valid shadow password" );
    59 
    60         correct = sp-> sp_pwdp;
    61     }
    62     else
    63 #endif
    64         correct = pw-> pw_passwd;
    65 
    66     if ( correct == 0 || correct[0] == '\0' )
     61    if (!correct[0]) /* empty password field? */
    6762        return 1;
    6863
    69     unencrypted = bb_askpass ( 0, "Password: " );
    70     if ( !unencrypted )
    71     {
     64 fake_it:
     65    unencrypted = bb_askpass(0, "Password: ");
     66    if (!unencrypted) {
    7267        return 0;
    7368    }
    74     encrypted = crypt ( unencrypted, correct );
    75     memset ( unencrypted, 0, strlen ( unencrypted ));
    76     return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0;
     69    encrypted = crypt(unencrypted, correct);
     70    memset(unencrypted, 0, strlen(unencrypted));
     71    return strcmp(encrypted, correct) == 0;
    7772}
  • branches/2.2.5/mindi-busybox/libbb/crc32.c

    r821 r1765  
    77 *
    88 * The following function creates a CRC32 table depending on whether
    9  * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is 
     9 * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is
    1010 * required. Admittedly, there are other CRC32 polynomials floating
    1111 * around, but Busybox doesn't use them.
     
    1515 */
    1616
    17 #include <stdio.h>
    18 #include <stdlib.h>
    1917#include "libbb.h"
    2018
    21 uint32_t *bb_crc32_filltable (int endian) {
    22    
    23     uint32_t *crc_table = xmalloc(256 * sizeof(uint32_t));
     19uint32_t *crc32_filltable(uint32_t *crc_table, int endian)
     20{
    2421    uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320;
    2522    uint32_t c;
    2623    int i, j;
    27    
     24
     25    if (!crc_table)
     26        crc_table = xmalloc(256 * sizeof(uint32_t));
     27
    2828    for (i = 0; i < 256; i++) {
    2929        c = endian ? (i << 24) : i;
  • branches/2.2.5/mindi-busybox/libbb/create_icmp6_socket.c

    r821 r1765  
    88 */
    99
    10 #include <sys/types.h>
    11 #include <netdb.h>
    12 #include <sys/socket.h>
    13 #include <errno.h>
    14 #include <unistd.h>
     10//#include <sys/types.h>
     11//#include <netdb.h>
     12//#include <sys/socket.h>
    1513#include "libbb.h"
    1614
    17 #ifdef CONFIG_FEATURE_IPV6
     15#if ENABLE_FEATURE_IPV6
    1816int create_icmp6_socket(void)
    1917{
     
    2422    /* if getprotobyname failed, just silently force
    2523     * proto->p_proto to have the correct value for "ipv6-icmp" */
    26     if ((sock = socket(AF_INET6, SOCK_RAW,
    27             (proto ? proto->p_proto : IPPROTO_ICMPV6))) < 0) {
     24    sock = socket(AF_INET6, SOCK_RAW,
     25            (proto ? proto->p_proto : IPPROTO_ICMPV6));
     26    if (sock < 0) {
    2827        if (errno == EPERM)
    2928            bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
    30         else
    31             bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
     29        bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
    3230    }
    3331
    3432    /* drop root privs if running setuid */
    35     setuid(getuid());
     33    xsetuid(getuid());
    3634
    3735    return sock;
  • branches/2.2.5/mindi-busybox/libbb/create_icmp_socket.c

    r821 r1765  
    88 */
    99
    10 #include <sys/types.h>
    11 #include <netdb.h>
    12 #include <sys/socket.h>
    13 #include <errno.h>
    14 #include <unistd.h>
     10//#include <sys/types.h>
     11//#include <netdb.h>
     12//#include <sys/socket.h>
    1513#include "libbb.h"
    1614
     
    2321    /* if getprotobyname failed, just silently force
    2422     * proto->p_proto to have the correct value for "icmp" */
    25     if ((sock = socket(AF_INET, SOCK_RAW,
    26             (proto ? proto->p_proto : 1))) < 0) {        /* 1 == ICMP */
     23    sock = socket(AF_INET, SOCK_RAW,
     24            (proto ? proto->p_proto : 1)); /* 1 == ICMP */
     25    if (sock < 0) {
    2726        if (errno == EPERM)
    2827            bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
    29         else
    30             bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
     28        bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
    3129    }
    3230
    3331    /* drop root privs if running setuid */
    34     setuid(getuid());
     32    xsetuid(getuid());
    3533
    3634    return sock;
  • branches/2.2.5/mindi-busybox/libbb/default_error_retval.c

    r821 r1765  
    33 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    44 *
    5  * This program is free software; you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License as published by
    7  * the Free Software Foundation; either version 2 of the License, or
    8  * (at your option) any later version.
    9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    13  * General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program; if not, write to the Free Software
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    18  *
     5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    196 */
    207
     
    2714 */
    2815
    29 #include <stdlib.h>
    3016#include "libbb.h"
    3117
    32 int bb_default_error_retval = EXIT_FAILURE;
     18int xfunc_error_retval = EXIT_FAILURE;
  • branches/2.2.5/mindi-busybox/libbb/device_open.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <fcntl.h>
    1210#include "libbb.h"
    13 
    1411
    1512/* try to open up the specified device */
     
    2118
    2219    /* Retry up to 5 times */
     20    /* TODO: explain why it can't be considered insane */
    2321    for (f = 0; f < 5; f++)
    2422        if ((fd = open(device, m, 0600)) >= 0)
  • branches/2.2.5/mindi-busybox/libbb/dump.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Support code for the hexdump and od applets,
     
    1213
    1314#include "libbb.h"
    14 #include <string.h>
    15 #include <unistd.h>
    16 #include <ctype.h>      /* for isdigit() */
    1715#include "dump.h"
    1816
     
    2927int bb_dump_length = -1;        /* max bytes to read */
    3028
    31 static const char index_str[] = ".#-+ 0123456789";
    32 
    33 static const char size_conv_str[] =
     29static const char index_str[] ALIGN1 = ".#-+ 0123456789";
     30
     31static const char size_conv_str[] ALIGN1 =
    3432"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";
    3533
    36 static const char lcc[] = "diouxX";
     34static const char lcc[] ALIGN1 = "diouxX";
    3735
    3836int bb_dump_size(FS * fs)
    3937{
    40     register FU *fu;
    41     register int bcnt, cur_size;
    42     register char *fmt;
     38    FU *fu;
     39    int bcnt, cur_size;
     40    char *fmt;
    4341    const char *p;
    4442    int prec;
     
    7775        cur_size += bcnt * fu->reps;
    7876    }
    79     return (cur_size);
     77    return cur_size;
    8078}
    8179
     
    156154                /* Unlike the original, output the remainder of the format string. */
    157155                if (!*byte_count_str) {
    158                     bb_error_msg_and_die("bad byte count for conversion character %s.", p1);
     156                    bb_error_msg_and_die("bad byte count for conversion character %s", p1);
    159157                }
    160158                pr->bcnt = *byte_count_str;
     
    189187                    pr->bcnt = prec;
    190188                } else {    /* NOTOKAY */
    191                     bb_error_msg_and_die("%%s requires a precision or a byte count.");
     189                    bb_error_msg_and_die("%%s requires a precision or a byte count");
    192190                }
    193191            } else if (*p1 == '_') {
     
    223221            } else {
    224222            DO_BAD_CONV_CHAR:
    225                 bb_error_msg_and_die("bad conversion character %%%s.\n", p1);
     223                bb_error_msg_and_die("bad conversion character %%%s", p1);
    226224            }
    227225
     
    232230            savech = *p2;
    233231            p1[1] = '\0';
    234             pr->fmt = bb_xstrdup(fmtp);
     232            pr->fmt = xstrdup(fmtp);
    235233            *p2 = savech;
    236234            pr->cchar = pr->fmt + (p1 - fmtp);
     
    256254            /* only one conversion character if byte count */
    257255            if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
    258                 bb_error_msg_and_die("byte count with multiple conversion characters.\n");
     256                bb_error_msg_and_die("byte count with multiple conversion characters");
    259257            }
    260258        }
     
    294292}
    295293
    296 static void do_skip(char *fname, int statok)
     294static void do_skip(const char *fname, int statok)
    297295{
    298296    struct stat sbuf;
     
    320318static int next(char **argv)
    321319{
    322     static int done;
     320    static smallint done;
     321
    323322    int statok;
    324323
    325324    if (argv) {
    326325        _argv = argv;
    327         return (1);
     326        return 1;
    328327    }
    329328    for (;;) {
     
    335334                continue;
    336335            }
    337             statok = done = 1;
     336            done = statok = 1;
    338337        } else {
    339             if (done++)
    340                 return (0);
     338            if (done)
     339                return 0;
     340            done = 1;
    341341            statok = 0;
    342342        }
     
    346346            ++_argv;
    347347        if (!bb_dump_skip)
    348             return (1);
     348            return 1;
    349349    }
    350350    /* NOTREACHED */
     
    353353static unsigned char *get(void)
    354354{
    355     static int ateof = 1;
    356     static unsigned char *curp=NULL, *savp; /*DBU:[dave@cray.com]initialize curp */
    357     register int n;
     355    static smallint ateof = 1;
     356    static unsigned char *curp = NULL, *savp; /*DBU:[dave@cray.com]initialize curp */
     357
     358    int n;
    358359    int need, nread;
    359360    unsigned char *tmpp;
     
    361362    if (!curp) {
    362363        address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/
    363         curp = (unsigned char *) xmalloc(bb_dump_blocksize);
    364         savp = (unsigned char *) xmalloc(bb_dump_blocksize);
     364        curp = xmalloc(bb_dump_blocksize);
     365        savp = xmalloc(bb_dump_blocksize);
    365366    } else {
    366367        tmpp = curp;
     
    377378        if (!bb_dump_length || (ateof && !next((char **) NULL))) {
    378379            if (need == bb_dump_blocksize) {
    379                 return ((unsigned char *) NULL);
     380                return NULL;
    380381            }
    381382            if (bb_dump_vflag != ALL && !memcmp(curp, savp, nread)) {
    382383                if (bb_dump_vflag != DUP) {
    383                     printf("*\n");
    384                 }
    385                 return ((unsigned char *) NULL);
     384                    puts("*");
     385                }
     386                return NULL;
    386387            }
    387388            memset((char *) curp + nread, 0, need);
    388389            eaddress = address + nread;
    389             return (curp);
     390            return curp;
    390391        }
    391392        n = fread((char *) curp + nread, sizeof(unsigned char),
     
    402403            bb_dump_length -= n;
    403404        }
    404         if (!(need -= n)) {
     405        need -= n;
     406        if (!need) {
    405407            if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
    406408                || memcmp(curp, savp, bb_dump_blocksize)) {
     
    408410                    bb_dump_vflag = WAIT;
    409411                }
    410                 return (curp);
     412                return curp;
    411413            }
    412414            if (bb_dump_vflag == WAIT) {
    413                 printf("*\n");
     415                puts("*");
    414416            }
    415417            bb_dump_vflag = DUP;
     
    439441}
    440442
    441 static const char conv_str[] =
     443static const char conv_str[] ALIGN1 =
    442444    "\0\\0\0"
    443445    "\007\\a\0"             /* \a */
     
    448450    "\t\\t\0"
    449451    "\v\\v\0"
    450     "\0";
     452    ;
    451453
    452454
     
    478480static void conv_u(PR * pr, unsigned char * p)
    479481{
    480     static const char list[] =
     482    static const char list[] ALIGN1 =
    481483        "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
    482484        "bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_"
     
    503505{
    504506/*  extern FU *endfu; */
    505     register FS *fs;
    506     register FU *fu;
    507     register PR *pr;
    508     register int cnt;
    509     register unsigned char *bp;
     507    FS *fs;
     508    FU *fu;
     509    PR *pr;
     510    int cnt;
     511    unsigned char *bp;
    510512
    511513    off_t saveaddress;
     
    651653int bb_dump_dump(char **argv)
    652654{
    653     register FS *tfs;
     655    FS *tfs;
    654656
    655657    /* figure out the data block bb_dump_size */
     
    668670    display();
    669671
    670     return (exitval);
     672    return exitval;
    671673}
    672674
     
    727729        /* byte count */
    728730        if (isdigit(*p)) {
    729             for (savep = p; isdigit(*p); ++p);
     731// TODO: use bb_strtou
     732            savep = p;
     733            do p++; while (isdigit(*p));
    730734            if (!isspace(*p)) {
    731735                bb_error_msg_and_die("bad format {%s}", fmt);
  • branches/2.2.5/mindi-busybox/libbb/error_msg.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    1410#include "libbb.h"
    1511
     
    1915
    2016    va_start(p, s);
    21     bb_verror_msg(s, p);
     17    bb_verror_msg(s, p, NULL);
    2218    va_end(p);
    23     putc('\n', stderr);
    2419}
  • branches/2.2.5/mindi-busybox/libbb/error_msg_and_die.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    1410#include "libbb.h"
     11
     12int die_sleep;
     13#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
     14jmp_buf die_jmp;
     15#endif
     16
     17void xfunc_die(void)
     18{
     19    if (die_sleep) {
     20        if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
     21         && die_sleep < 0
     22        ) {
     23            /* Special case. We arrive here if NOFORK applet
     24             * calls xfunc, which then decides to die.
     25             * We don't die, but jump instead back to caller.
     26             * NOFORK applets still cannot carelessly call xfuncs:
     27             * p = xmalloc(10);
     28             * q = xmalloc(10); // BUG! if this dies, we leak p!
     29             */
     30            /* -2222 means "zero" (longjmp can't pass 0)
     31             * run_nofork_applet() catches -2222. */
     32            longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
     33        }
     34        sleep(die_sleep);
     35    }
     36    exit(xfunc_error_retval);
     37}
    1538
    1639void bb_error_msg_and_die(const char *s, ...)
     
    1942
    2043    va_start(p, s);
    21     bb_verror_msg(s, p);
     44    bb_verror_msg(s, p, NULL);
    2245    va_end(p);
    23     putc('\n', stderr);
    24     exit(bb_default_error_retval);
     46    xfunc_die();
    2547}
  • branches/2.2.5/mindi-busybox/libbb/fclose_nonstdin.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    2613 */
    2714
    28 #include <stdio.h>
    29 #include <libbb.h>
     15#include "libbb.h"
    3016
    31 int bb_fclose_nonstdin(FILE *f)
     17int fclose_if_not_stdin(FILE *f)
    3218{
    3319    if (f != stdin) {
  • branches/2.2.5/mindi-busybox/libbb/fflush_stdout_and_exit.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    2512 */
    2613
    27 #include <stdio.h>
    28 #include <stdlib.h>
    29 #include <libbb.h>
     14#include "libbb.h"
    3015
    31 void bb_fflush_stdout_and_exit(int retval)
     16void fflush_stdout_and_exit(int retval)
    3217{
    33     if (fflush(stdout)) {
    34         retval = bb_default_error_retval;
     18    if (fflush(stdout))
     19        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();
    3526    }
     27
    3628    exit(retval);
    3729}
  • branches/2.2.5/mindi-busybox/libbb/fgets_str.c

    r821 r1765  
    66 * If you wrote this, please acknowledge your work.
    77 *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    16  * General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    219 */
    22 
    23 
    24 #include <stdio.h>
    25 #include <stdlib.h>
    26 #include <string.h>
    2710
    2811#include "libbb.h"
     
    3114 * Return NULL on EOF.  */
    3215
    33 char *fgets_str(FILE *file, const char *terminating_string)
     16char *xmalloc_fgets_str(FILE *file, const char *terminating_string)
    3417{
    3518    char *linebuf = NULL;
     
    4932        /* grow the line buffer as necessary */
    5033        while (idx > linebufsz - 2) {
    51             linebuf = xrealloc(linebuf, linebufsz += 1000);
     34            linebufsz += 200;
     35            linebuf = xrealloc(linebuf, linebufsz);
    5236        }
    5337
     
    5741        /* Check for terminating string */
    5842        end_string_offset = idx - term_length;
    59         if ((end_string_offset > 0) && (memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0)) {
     43        if (end_string_offset > 0
     44         && memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0
     45        ) {
    6046            idx -= term_length;
    6147            break;
    6248        }
    6349    }
     50    linebuf = xrealloc(linebuf, idx + 1);
    6451    linebuf[idx] = '\0';
    65     return(linebuf);
     52    return linebuf;
    6653}
    67 
  • branches/2.2.5/mindi-busybox/libbb/find_mount_point.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <string.h>
    1210#include "libbb.h"
     11#include <mntent.h>
    1312
    14 
    15 #include <mntent.h>
    1613/*
    1714 * Given a block device, find the mount table entry if that block device
     
    3734
    3835
    39     if ((mountTable = setmntent(table ? table : bb_path_mtab_file, "r")) == 0)
     36    mountTable = setmntent(table ? table : bb_path_mtab_file, "r");
     37    if (!mountTable)
    4038        return 0;
    4139
    4240    while ((mountEntry = getmntent(mountTable)) != 0) {
    43 
    44             if(strcmp(name, mountEntry->mnt_dir) == 0
    45             || strcmp(name, mountEntry->mnt_fsname) == 0)   /* String match. */
     41        if (strcmp(name, mountEntry->mnt_dir) == 0
     42         || strcmp(name, mountEntry->mnt_fsname) == 0
     43        ) { /* String match. */
    4644            break;
     45        }
    4746        if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)  /* Match the device. */
    4847            break;
  • branches/2.2.5/mindi-busybox/libbb/find_pid_by_name.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    88 */
    99
    10 #include <stdio.h>
    11 #include <ctype.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    1410#include "libbb.h"
     11
     12/*
     13In Linux we have three ways to determine "process name":
     141. /proc/PID/stat has "...(name)...", among other things. It's so-called "comm" field.
     152. /proc/PID/cmdline's first NUL-terminated string. It's argv[0] from exec syscall.
     163. /proc/PID/exe symlink. Points to the running executable file.
     17
     18kernel threads:
     19 comm: thread name
     20 cmdline: empty
     21 exe: <readlink fails>
     22
     23executable
     24 comm: first 15 chars of base name
     25 (if executable is a symlink, then first 15 chars of symlink name are used)
     26 cmdline: argv[0] from exec syscall
     27 exe: points to executable (resolves symlink, unlike comm)
     28
     29script (an executable with #!/path/to/interpreter):
     30 comm: first 15 chars of script's base name (symlinks are not resolved)
     31 cmdline: /path/to/interpreter (symlinks are not resolved)
     32 (script name is in argv[1], args are pushed into argv[2] etc)
     33 exe: points to interpreter's executable (symlinks are resolved)
     34
     35If FEATURE_PREFER_APPLETS=y (and more so if FEATURE_SH_STANDALONE=y),
     36some commands started from busybox shell, xargs or find are started by
     37execXXX("/proc/self/exe", applet_name, params....)
     38and therefore comm field contains "exe".
     39*/
    1540
    1641/* find_pid_by_name()
     
    2449 *  It is the caller's duty to free the returned pidlist.
    2550 */
    26 long* find_pid_by_name( const char* pidName)
     51pid_t* find_pid_by_name(const char* procName)
    2752{
    28     long* pidList;
    29     int i=0;
    30     procps_status_t * p;
     53    pid_t* pidList;
     54    int i = 0;
     55    procps_status_t* p = NULL;
    3156
    32     pidList = xmalloc(sizeof(long));
    33     while ((p = procps_scan(0)) != 0)
    34     {
    35         if (strncmp(p->short_cmd, pidName, COMM_LEN-1) == 0) {
    36             pidList=xrealloc( pidList, sizeof(long) * (i+2));
    37             pidList[i++]=p->pid;
     57    pidList = xmalloc(sizeof(*pidList));
     58    while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGV0))) {
     59        if (
     60        /* we require comm to match and to not be truncated */
     61        /* in Linux, if comm is 15 chars, it may be a truncated
     62         * name, so we don't allow that to match */
     63            (!p->comm[sizeof(p->comm)-2] && strcmp(p->comm, procName) == 0)
     64        /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
     65         || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
     66        /* TOOD: we can also try exe, do we want that? */
     67        ) {
     68            pidList = xrealloc(pidList, sizeof(*pidList) * (i+2));
     69            pidList[i++] = p->pid;
    3870        }
    3971    }
    4072
    41     pidList[i] = i==0 ? -1 : 0;
     73    pidList[i] = 0;
    4274    return pidList;
    4375}
    4476
    45 long *pidlist_reverse(long *pidList)
     77pid_t *pidlist_reverse(pid_t *pidList)
    4678{
    47     int i=0;
    48     while (pidList[i] > 0 && ++i);
    49     if ( i-- > 0) {
    50         long k;
     79    int i = 0;
     80    while (pidList[i])
     81        i++;
     82    if (--i >= 0) {
     83        pid_t k;
    5184        int j;
    5285        for (j = 0; i > j; i--, j++) {
  • branches/2.2.5/mindi-busybox/libbb/find_root_device.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    208 */
    219
    22 #include <limits.h>
    23 #include <stdio.h>
    24 #include <string.h>
    25 #include <dirent.h>
    26 #include <stdlib.h>
    2710#include "libbb.h"
    2811
    29 char *find_block_device(char *path)
     12/* Find block device /dev/XXX which contains specified file
     13 * We handle /dev/dir/dir/dir too, at a cost of ~80 more bytes code */
     14
     15/* Do not reallocate all this stuff on each recursion */
     16enum { DEVNAME_MAX = 256 };
     17struct arena {
     18    struct stat st;
     19    dev_t dev;
     20    /* Was PATH_MAX, but we recurse _/dev_. We can assume
     21     * people are not crazy enough to have mega-deep tree there */
     22    char devpath[DEVNAME_MAX];
     23};
     24
     25static char *find_block_device_in_dir(struct arena *ap)
    3026{
    3127    DIR *dir;
    3228    struct dirent *entry;
    33     struct stat st;
    34     dev_t dev;
    35     char *retpath=NULL;
     29    char *retpath = NULL;
     30    int len, rem;
    3631
    37     if(stat(path, &st) || !(dir = opendir("/dev"))) return NULL;
    38     dev = (st.st_mode & S_IFMT) == S_IFBLK ? st.st_rdev : st.st_dev;
    39     while((entry = readdir(dir)) != NULL) {
    40         char devpath[PATH_MAX];
    41         sprintf(devpath,"/dev/%s", entry->d_name);
    42         if(!stat(devpath, &st) && S_ISBLK(st.st_mode) && st.st_rdev == dev) {
    43             retpath = bb_xstrdup(devpath);
     32    dir = opendir(ap->devpath);
     33    if (!dir)
     34        return NULL;
     35
     36    len = strlen(ap->devpath);
     37    rem = DEVNAME_MAX-2 - len;
     38    if (rem <= 0)
     39        return NULL;
     40    ap->devpath[len++] = '/';
     41
     42    while ((entry = readdir(dir)) != NULL) {
     43        safe_strncpy(ap->devpath + len, entry->d_name, rem);
     44        /* lstat: do not follow links */
     45        if (lstat(ap->devpath, &ap->st) != 0)
     46            continue;
     47        if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) {
     48            retpath = xstrdup(ap->devpath);
    4449            break;
     50        }
     51        if (S_ISDIR(ap->st.st_mode)) {
     52            /* Do not recurse for '.' and '..' */
     53            if (DOT_OR_DOTDOT(entry->d_name))
     54                continue;
     55            retpath = find_block_device_in_dir(ap);
     56            if (retpath)
     57                break;
    4558        }
    4659    }
     
    4962    return retpath;
    5063}
     64
     65char *find_block_device(const char *path)
     66{
     67    struct arena a;
     68
     69    if (stat(path, &a.st) != 0)
     70        return NULL;
     71    a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev;
     72    strcpy(a.devpath, "/dev");
     73    return find_block_device_in_dir(&a);
     74}
  • branches/2.2.5/mindi-busybox/libbb/full_write.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <unistd.h>
    1210#include "libbb.h"
    1311
     
    1715 * Returns the amount written, or -1 on an error.
    1816 */
    19 ssize_t bb_full_write(int fd, const void *buf, size_t len)
     17ssize_t full_write(int fd, const void *buf, size_t len)
    2018{
    2119    ssize_t cc;
     
    2422    total = 0;
    2523
    26     while (len > 0) {
     24    while (len) {
    2725        cc = safe_write(fd, buf, len);
    2826
    2927        if (cc < 0)
    30             return cc;      /* write() returns -1 on failure. */
     28            return cc;  /* write() returns -1 on failure. */
    3129
    3230        total += cc;
  • branches/2.2.5/mindi-busybox/libbb/get_console.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <errno.h>
    13 #include <fcntl.h>
    14 #include <unistd.h>
    15 #include <sys/ioctl.h>
     11//#include <sys/ioctl.h>
    1612#include "libbb.h"
    17 
    1813
    1914
     
    4843int get_console_fd(void)
    4944{
     45    static const char *const console_names[] = {
     46        DEV_CONSOLE, CURRENT_VC, CURRENT_TTY
     47    };
     48
    5049    int fd;
    51 
    52     static const char * const choise_console_names[] = {
    53         CONSOLE_DEV, CURRENT_VC, CURRENT_TTY
    54     };
    5550
    5651    for (fd = 2; fd >= 0; fd--) {
    5752        int fd4name;
    58         int choise_fd;
     53        int choice_fd;
    5954        char arg;
    6055
    61         fd4name = open_a_console(choise_console_names[fd]);
    62     chk_std:
    63         choise_fd = fd4name >= 0 ? fd4name : fd;
     56        fd4name = open_a_console(console_names[fd]);
     57 chk_std:
     58        choice_fd = (fd4name >= 0 ? fd4name : fd);
    6459
    6560        arg = 0;
    66         if (ioctl(choise_fd, KDGKBTYPE, &arg) == 0)
    67             return choise_fd;
    68         if(fd4name >= 0) {
     61        if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0)
     62            return choice_fd;
     63        if (fd4name >= 0) {
    6964            close(fd4name);
    7065            fd4name = -1;
     
    7368    }
    7469
    75     bb_error_msg("Couldn't get a file descriptor referring to the console");
     70    bb_error_msg("cannot get file descriptor referring to console");
    7671    return fd;                      /* total failure */
    7772}
  • branches/2.2.5/mindi-busybox/libbb/get_last_path_component.c

    r821 r1765  
    2727        last = first;
    2828    }
    29     last[1] = 0;
     29    last[1] = '\0';
    3030
    3131    return first;
  • branches/2.2.5/mindi-busybox/libbb/get_line_from_file.c

    r821 r1765  
    1010 */
    1111
    12 #include <stdio.h>
    13 #include <stdlib.h>
    1412#include "libbb.h"
    1513
    16 /* get_line_from_file() - This function reads an entire line from a text file,
    17  * up to a newline or NUL byte.  It returns a malloc'ed char * which must be
    18  * stored and free'ed  by the caller.  If end is null '\n' isn't considered
    19  * and of line.  If end isn't null, length of the chunk read is stored in it. */
     14/* This function reads an entire line from a text file, up to a newline
     15 * or NUL byte, inclusive.  It returns a malloc'ed char * which must be
     16 * stored and free'ed by the caller.  If end is NULL '\n' isn't considered
     17 * end of line.  If end isn't NULL, length of the chunk read is stored in it.
     18 * Return NULL if EOF/error */
    2019
    21 char *bb_get_chunk_from_file(FILE * file, int *end)
     20char *bb_get_chunk_from_file(FILE *file, int *end)
    2221{
    2322    int ch;
     
    2827    while ((ch = getc(file)) != EOF) {
    2928        /* grow the line buffer as necessary */
    30         if (idx > linebufsz - 2) {
    31             linebuf = xrealloc(linebuf, linebufsz += 80);
     29        if (idx >= linebufsz) {
     30            linebufsz += 80;
     31            linebuf = xrealloc(linebuf, linebufsz);
    3232        }
    3333        linebuf[idx++] = (char) ch;
     
    3838        *end = idx;
    3939    if (linebuf) {
    40         if (ferror(file)) {
    41             free(linebuf);
    42             return NULL;
    43         }
    44         linebuf[idx] = 0;
     40        // huh, does fgets discard prior data on error like this?
     41        // I don't think so....
     42        //if (ferror(file)) {
     43        //  free(linebuf);
     44        //  return NULL;
     45        //}
     46        linebuf = xrealloc(linebuf, idx+1);
     47        linebuf[idx] = '\0';
    4548    }
    4649    return linebuf;
    4750}
    4851
    49 /* Get line, including trailing /n if any */
    50 char *bb_get_line_from_file(FILE * file)
     52/* Get line, including trailing \n if any */
     53char *xmalloc_fgets(FILE *file)
    5154{
    5255    int i;
     
    5558}
    5659
    57 /* Get line.  Remove trailing /n */
    58 char *bb_get_chomped_line_from_file(FILE * file)
     60/* Get line.  Remove trailing \n */
     61char *xmalloc_getline(FILE *file)
    5962{
    6063    int i;
     
    6265
    6366    if (i && c[--i] == '\n')
    64         c[i] = 0;
     67        c[i] = '\0';
    6568
    6669    return c;
  • branches/2.2.5/mindi-busybox/libbb/herror_msg.c

    r821 r1765  
    88 */
    99
    10 #include <stdarg.h>
    11 #include <stdlib.h>
    12 
    1310#include "libbb.h"
    1411
     
    1815
    1916    va_start(p, s);
    20     bb_vherror_msg(s, p);
     17    bb_verror_msg(s, p, hstrerror(h_errno));
    2118    va_end(p);
    2219}
  • branches/2.2.5/mindi-busybox/libbb/herror_msg_and_die.c

    r821 r1765  
    88 */
    99
    10 #include <stdarg.h>
    11 #include <stdlib.h>
    12 
    1310#include "libbb.h"
    1411
     
    1815
    1916    va_start(p, s);
    20     bb_vherror_msg(s, p);
     17    bb_verror_msg(s, p, hstrerror(h_errno));
    2118    va_end(p);
    22     exit(bb_default_error_retval);
     19    xfunc_die();
    2320}
  • branches/2.2.5/mindi-busybox/libbb/human_readable.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * June 30, 2001                 Manuel Novoa III
     
    2627 */
    2728
    28 #include <stdio.h>
    2929#include "libbb.h"
    3030
     
    3232    unsigned long block_size, unsigned long display_unit)
    3333{
    34     /* The code will adjust for additional (appended) units. */
    35     static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' };
    36     static const char fmt[] = "%llu";
    37     static const char fmt_tenths[] = "%llu.%d%c";
     34    /* The code will adjust for additional (appended) units */
     35    static const char zero_and_units[] ALIGN1 = { '0', 0, 'k', 'M', 'G', 'T' };
     36    static const char fmt[] ALIGN1 = "%llu";
     37    static const char fmt_tenths[] ALIGN1 = "%llu.%d%c";
    3838
    39     static char str[21];        /* Sufficient for 64 bit unsigned integers. */
     39    static char str[21] ALIGN1;  /* Sufficient for 64 bit unsigned integers */
    4040
    4141    unsigned long long val;
     
    5454
    5555    if (display_unit) {
    56         val += display_unit/2;  /* Deal with rounding. */
     56        val += display_unit/2;  /* Deal with rounding */
    5757        val /= display_unit;    /* Don't combine with the line above!!! */
    5858    } else {
    5959        ++u;
    60         while ((val >= KILOBYTE)
    61                && (u < zero_and_units + sizeof(zero_and_units) - 1)) {
     60        while ((val >= 1024)
     61         && (u < zero_and_units + sizeof(zero_and_units) - 1)
     62        ) {
    6263            f = fmt_tenths;
    6364            ++u;
    64             frac = ((((int)(val % KILOBYTE)) * 10) + (KILOBYTE/2)) / KILOBYTE;
    65             val /= KILOBYTE;
     65            frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024;
     66            val /= 1024;
    6667        }
    6768        if (frac >= 10) {       /* We need to round up here. */
     
    7172#if 0
    7273        /* Sample code to omit decimal point and tenths digit. */
    73         if ( /* no_tenths */ 1 ) {
    74             if ( frac >= 5 ) {
     74        if (/* no_tenths */ 1) {
     75            if (frac >= 5) {
    7576                ++val;
    7677            }
    77             f = "%llu%*c" /* fmt_no_tenths */ ;
     78            f = "%llu%*c" /* fmt_no_tenths */;
    7879            frac = 1;
    7980        }
  • branches/2.2.5/mindi-busybox/libbb/inet_common.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * stolen from net-tools-1.59 and stripped down for busybox by
     
    56 * Heavily modified by Manuel Novoa III       Mar 12, 2001
    67 *
    7  * Version:     $Id: inet_common.c,v 1.8 2004/03/10 07:42:38 mjn3 Exp $
    88 *
    99 */
     
    1111#include "libbb.h"
    1212#include "inet_common.h"
    13 #include <stdio.h>
    14 #include <errno.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include <unistd.h>
    18 
    19 #ifdef DEBUG
    20 # include <resolv.h>
    21 #endif
    22 
    23 
    24 const char bb_INET_default[] = "default";
    2513
    2614int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
    2715{
    2816    struct hostent *hp;
     17#if ENABLE_FEATURE_ETC_NETWORKS
    2918    struct netent *np;
     19#endif
    3020
    3121    /* Grmpf. -FvK */
     
    3424
    3525    /* Default is special, meaning 0.0.0.0. */
    36     if (!strcmp(name, bb_INET_default)) {
     26    if (!strcmp(name, bb_str_default)) {
    3727        s_in->sin_addr.s_addr = INADDR_ANY;
    38         return (1);
     28        return 1;
    3929    }
    4030    /* Look to see if it's a dotted quad. */
     
    4535#ifdef DEBUG
    4636    if (hostfirst) {
    47         bb_error_msg("gethostbyname (%s)", name);
    48     }
    49 #endif
    50     if (hostfirst && (hp = gethostbyname(name)) != (struct hostent *) NULL) {
    51         memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],
    52                sizeof(struct in_addr));
    53         return 0;
    54     }
     37        bb_error_msg("gethostbyname(%s)", name);
     38    }
     39#endif
     40    if (hostfirst) {
     41        hp = gethostbyname(name);
     42        if (hp != NULL) {
     43            memcpy(&s_in->sin_addr, hp->h_addr_list[0],
     44                sizeof(struct in_addr));
     45            return 0;
     46        }
     47    }
     48#if ENABLE_FEATURE_ETC_NETWORKS
    5549    /* Try the NETWORKS database to see if this is a known network. */
    5650#ifdef DEBUG
    57     bb_error_msg("getnetbyname (%s)", name);
    58 #endif
    59     if ((np = getnetbyname(name)) != (struct netent *) NULL) {
     51    bb_error_msg("getnetbyname(%s)", name);
     52#endif
     53    np = getnetbyname(name);
     54    if (np != NULL) {
    6055        s_in->sin_addr.s_addr = htonl(np->n_net);
    6156        return 1;
    6257    }
     58#endif
    6359    if (hostfirst) {
    6460        /* Don't try again */
     
    7167
    7268#ifdef DEBUG
    73     bb_error_msg("gethostbyname (%s)", name);
    74 #endif
    75     if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
     69    bb_error_msg("gethostbyname(%s)", name);
     70#endif
     71    hp = gethostbyname(name);
     72    if (hp == NULL) {
    7673        return -1;
    7774    }
    78     memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0],
    79            sizeof(struct in_addr));
    80 
     75    memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
    8176    return 0;
    8277}
    8378
    84 /* cache */
    85 struct addr {
    86     struct sockaddr_in addr;
    87     char *name;
    88     int host;
    89     struct addr *next;
    90 };
    91 
    92 static struct addr *INET_nn = NULL; /* addr-to-name cache           */
    9379
    9480/* numeric: & 0x8000: default instead of *,
     
    9682 *          & 0x0fff: don't resolve
    9783 */
    98 int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
    99                   int numeric, unsigned int netmask)
    100 {
    101     struct hostent *ent;
    102     struct netent *np;
     84char *INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t netmask)
     85{
     86    /* addr-to-name cache */
     87    struct addr {
     88        struct addr *next;
     89        struct sockaddr_in addr;
     90        int host;
     91        char name[1];
     92    };
     93    static struct addr *cache = NULL;
     94
    10395    struct addr *pn;
    104     unsigned long ad, host_ad;
     96    char *name;
     97    uint32_t ad, host_ad;
    10598    int host = 0;
    10699
     
    108101    if (s_in->sin_family != AF_INET) {
    109102#ifdef DEBUG
    110         bb_error_msg("rresolve: unsupport address family %d !",
     103        bb_error_msg("rresolve: unsupported address family %d!",
    111104                  s_in->sin_family);
    112105#endif
    113106        errno = EAFNOSUPPORT;
    114         return (-1);
    115     }
    116     ad = (unsigned long) s_in->sin_addr.s_addr;
    117 #ifdef DEBUG
    118     bb_error_msg("rresolve: %08lx, mask %08x, num %08x", ad, netmask, numeric);
     107        return NULL;
     108    }
     109    ad = s_in->sin_addr.s_addr;
     110#ifdef DEBUG
     111    bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric);
    119112#endif
    120113    if (ad == INADDR_ANY) {
    121114        if ((numeric & 0x0FFF) == 0) {
    122115            if (numeric & 0x8000)
    123                 safe_strncpy(name, bb_INET_default, len);
    124             else
    125                 safe_strncpy(name, "*", len);
    126             return (0);
     116                return xstrdup(bb_str_default);
     117            return xstrdup("*");
    127118        }
    128119    }
    129     if (numeric & 0x0FFF) {
    130         safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);
    131         return (0);
    132     }
     120    if (numeric & 0x0FFF)
     121        return xstrdup(inet_ntoa(s_in->sin_addr));
    133122
    134123    if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
    135124        host = 1;
    136 #if 0
    137     INET_nn = NULL;
    138 #endif
    139     pn = INET_nn;
    140     while (pn != NULL) {
     125    pn = cache;
     126    while (pn) {
    141127        if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
    142             safe_strncpy(name, pn->name, len);
    143 #ifdef DEBUG
    144             bb_error_msg("rresolve: found %s %08lx in cache",
    145                       (host ? "host" : "net"), ad);
    146 #endif
    147             return (0);
     128#ifdef DEBUG
     129            bb_error_msg("rresolve: found %s %08x in cache",
     130                      (host ? "host" : "net"), (unsigned)ad);
     131#endif
     132            return xstrdup(pn->name);
    148133        }
    149134        pn = pn->next;
     
    151136
    152137    host_ad = ntohl(ad);
    153     np = NULL;
    154     ent = NULL;
     138    name = NULL;
    155139    if (host) {
    156 #ifdef DEBUG
    157         bb_error_msg("gethostbyaddr (%08lx)", ad);
     140        struct hostent *ent;
     141#ifdef DEBUG
     142        bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad);
    158143#endif
    159144        ent = gethostbyaddr((char *) &ad, 4, AF_INET);
    160         if (ent != NULL) {
    161             safe_strncpy(name, ent->h_name, len);
    162         }
    163     } else {
    164 #ifdef DEBUG
    165         bb_error_msg("getnetbyaddr (%08lx)", host_ad);
     145        if (ent)
     146            name = xstrdup(ent->h_name);
     147    } else if (ENABLE_FEATURE_ETC_NETWORKS) {
     148        struct netent *np;
     149#ifdef DEBUG
     150        bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad);
    166151#endif
    167152        np = getnetbyaddr(host_ad, AF_INET);
    168         if (np != NULL) {
    169             safe_strncpy(name, np->n_name, len);
    170         }
    171     }
    172     if ((ent == NULL) && (np == NULL)) {
    173         safe_strncpy(name, inet_ntoa(s_in->sin_addr), len);
    174     }
    175     pn = (struct addr *) xmalloc(sizeof(struct addr));
     153        if (np)
     154            name = xstrdup(np->n_name);
     155    }
     156    if (!name)
     157        name = xstrdup(inet_ntoa(s_in->sin_addr));
     158    pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */
     159    pn->next = cache;
    176160    pn->addr = *s_in;
    177     pn->next = INET_nn;
    178161    pn->host = host;
    179     pn->name = bb_xstrdup(name);
    180     INET_nn = pn;
    181 
    182     return (0);
    183 }
    184 
    185 #ifdef CONFIG_FEATURE_IPV6
     162    strcpy(pn->name, name);
     163    cache = pn;
     164    return name;
     165}
     166
     167#if ENABLE_FEATURE_IPV6
    186168
    187169int INET6_resolve(const char *name, struct sockaddr_in6 *sin6)
     
    192174    memset(&req, '\0', sizeof req);
    193175    req.ai_family = AF_INET6;
    194     if ((s = getaddrinfo(name, NULL, &req, &ai))) {
     176    s = getaddrinfo(name, NULL, &req, &ai);
     177    if (s) {
    195178        bb_error_msg("getaddrinfo: %s: %d", name, s);
    196179        return -1;
    197180    }
    198181    memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
    199 
    200182    freeaddrinfo(ai);
    201 
    202     return (0);
     183    return 0;
    203184}
    204185
     
    210191
    211192
    212 int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6,
    213                    int numeric)
    214 {
     193char *INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
     194{
     195    char name[128];
    215196    int s;
    216197
     
    218199    if (sin6->sin6_family != AF_INET6) {
    219200#ifdef DEBUG
    220         bb_error_msg(_("rresolve: unsupport address family %d !\n"),
     201        bb_error_msg("rresolve: unsupport address family %d!",
    221202                  sin6->sin6_family);
    222203#endif
    223204        errno = EAFNOSUPPORT;
    224         return (-1);
     205        return NULL;
    225206    }
    226207    if (numeric & 0x7FFF) {
    227         inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);
    228         return (0);
     208        inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name));
     209        return xstrdup(name);
    229210    }
    230211    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
    231         if (numeric & 0x8000) {
    232             strcpy(name, "default");
    233         } else {
    234             strcpy(name, "*");
    235         }
    236         return (0);
    237     }
    238 
    239     s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), name, len, NULL, 0, 0);
     212        if (numeric & 0x8000)
     213            return xstrdup(bb_str_default);
     214        return xstrdup("*");
     215    }
     216
     217    s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
     218                name, sizeof(name), NULL, 0, 0);
    240219    if (s) {
    241220        bb_error_msg("getnameinfo failed");
    242         return -1;
    243     }
    244     return (0);
     221        return NULL;
     222    }
     223    return xstrdup(name);
    245224}
    246225
  • branches/2.2.5/mindi-busybox/libbb/inode_hash.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <stdlib.h>
    13 #include <string.h>
    1411#include "libbb.h"
     12
     13typedef struct ino_dev_hash_bucket_struct {
     14    struct ino_dev_hash_bucket_struct *next;
     15    ino_t ino;
     16    dev_t dev;
     17    char name[1];
     18} ino_dev_hashtable_bucket_t;
    1519
    1620#define HASH_SIZE   311     /* Should be prime */
    1721#define hash_inode(i)   ((i) % HASH_SIZE)
    1822
    19 typedef struct ino_dev_hash_bucket_struct {
    20   struct ino_dev_hash_bucket_struct *next;
    21   ino_t ino;
    22   dev_t dev;
    23   char name[1];
    24 } ino_dev_hashtable_bucket_t;
    25 
    26 static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
     23/* array of [HASH_SIZE] elements */
     24static ino_dev_hashtable_bucket_t **ino_dev_hashtable;
    2725
    2826/*
    29  * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
    30  * `ino_dev_hashtable', else return 0
    31  *
    32  * If NAME is a non-NULL pointer to a character pointer, and there is
    33  * a match, then set *NAME to the value of the name slot in that
    34  * bucket.
     27 * Return name if statbuf->st_ino && statbuf->st_dev are recorded in
     28 * ino_dev_hashtable, else return NULL
    3529 */
    36 int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
     30char *is_in_ino_dev_hashtable(const struct stat *statbuf)
    3731{
    3832    ino_dev_hashtable_bucket_t *bucket;
    3933
     34    if (!ino_dev_hashtable)
     35        return NULL;
     36
    4037    bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
    4138    while (bucket != NULL) {
    42       if ((bucket->ino == statbuf->st_ino) &&
    43           (bucket->dev == statbuf->st_dev))
    44       {
    45         if (name) *name = bucket->name;
    46         return 1;
    47       }
    48       bucket = bucket->next;
     39        if ((bucket->ino == statbuf->st_ino)
     40         && (bucket->dev == statbuf->st_dev)
     41        ) {
     42            return bucket->name;
     43        }
     44        bucket = bucket->next;
    4945    }
    50     return 0;
     46    return NULL;
    5147}
    5248
     
    5551{
    5652    int i;
    57     size_t s;
    5853    ino_dev_hashtable_bucket_t *bucket;
    5954
    6055    i = hash_inode(statbuf->st_ino);
    61     s = name ? strlen(name) : 0;
    62     bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s);
     56    if (!name)
     57        name = "";
     58    bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name));
    6359    bucket->ino = statbuf->st_ino;
    6460    bucket->dev = statbuf->st_dev;
    65     if (name)
    66         strcpy(bucket->name, name);
    67     else
    68         bucket->name[0] = '\0';
     61    strcpy(bucket->name, name);
     62
     63    if (!ino_dev_hashtable)
     64        ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable));
     65
    6966    bucket->next = ino_dev_hashtable[i];
    7067    ino_dev_hashtable[i] = bucket;
    7168}
    7269
    73 #ifdef CONFIG_FEATURE_CLEAN_UP
     70#if ENABLE_FEATURE_CLEAN_UP
    7471/* Clear statbuf hash table */
    7572void reset_ino_dev_hashtable(void)
     
    7875    ino_dev_hashtable_bucket_t *bucket;
    7976
    80     for (i = 0; i < HASH_SIZE; i++) {
     77    for (i = 0; ino_dev_hashtable && i < HASH_SIZE; i++) {
    8178        while (ino_dev_hashtable[i] != NULL) {
    8279            bucket = ino_dev_hashtable[i]->next;
     
    8582        }
    8683    }
     84    free(ino_dev_hashtable);
     85    ino_dev_hashtable = NULL;
    8786}
     87#else
     88void reset_ino_dev_hashtable(void);
    8889#endif
  • branches/2.2.5/mindi-busybox/libbb/kernel_version.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <string.h>
    12 #include <stdlib.h>
    1310#include <sys/utsname.h>        /* for uname(2) */
    1411
     
    2825    if (uname(&name) == -1) {
    2926        bb_perror_msg("cannot get system information");
    30         return (0);
     27        return 0;
    3128    }
    3229
    3330    s = name.release;
    3431    r = 0;
    35     for (i=0 ; i<3 ; i++) {
     32    for (i = 0; i < 3; i++) {
    3633        r = r * 256 + atoi(strtok(s, "."));
    3734        s = NULL;
  • branches/2.2.5/mindi-busybox/libbb/last_char_is.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * busybox library eXtended function
     
    45 * Copyright (C) 2001 Larry Doolittle, <ldoolitt@recycle.lbl.gov>
    56 *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
    10  *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    14  * General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License
    17  * along with this program; if not, write to the Free Software
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    19  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    208 */
    219
    22 #include <string.h>
    2310#include "libbb.h"
    2411
    25 /* Find out if the last character of a string matches the one given Don't
    26  * underrun the buffer if the string length is 0.  Also avoids a possible
    27  * space-hogging inline of strlen() per usage.
     12/* Find out if the last character of a string matches the one given.
     13 * Don't underrun the buffer if the string length is 0.
    2814 */
    29 char * last_char_is(const char *s, int c)
     15char* last_char_is(const char *s, int c)
    3016{
    31     char *sret = (char *)s;
    32     if (sret) {
    33         sret = strrchr(sret, c);
    34         if(sret != NULL && *(sret+1) != 0)
    35             sret = NULL;
     17    if (s && *s) {
     18        size_t sz = strlen(s) - 1;
     19        s += sz;
     20        if ( (unsigned char)*s == c)
     21            return (char*)s;
    3622    }
    37     return sret;
     23    return NULL;
    3824}
  • branches/2.2.5/mindi-busybox/libbb/llist.c

    r821 r1765  
    88 * Copyright (C) 2006 Rob Landley <rob@landley.net>
    99 *
    10  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     10 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    1111 */
    12 #include <stdlib.h>
     12
    1313#include "libbb.h"
    1414
    15 #ifdef L_llist_add_to
    1615/* Add data to the start of the linked list.  */
    1716void llist_add_to(llist_t **old_head, void *data)
    1817{
    1918    llist_t *new_head = xmalloc(sizeof(llist_t));
     19
    2020    new_head->data = data;
    2121    new_head->link = *old_head;
    2222    *old_head = new_head;
    2323}
    24 #endif
    2524
    26 #ifdef L_llist_add_to_end
    2725/* Add data to the end of the linked list.  */
    2826void llist_add_to_end(llist_t **list_head, void *data)
    2927{
    3028    llist_t *new_item = xmalloc(sizeof(llist_t));
     29
    3130    new_item->data = data;
    3231    new_item->link = NULL;
    3332
    34     if (!*list_head) *list_head = new_item;
     33    if (!*list_head)
     34        *list_head = new_item;
    3535    else {
    3636        llist_t *tail = *list_head;
    37         while (tail->link) tail = tail->link;
     37
     38        while (tail->link)
     39            tail = tail->link;
    3840        tail->link = new_item;
    3941    }
    4042}
    41 #endif
    4243
    43 #ifdef L_llist_pop
    4444/* Remove first element from the list and return it */
    4545void *llist_pop(llist_t **head)
    4646{
    47     void *data;
     47    void *data, *next;
    4848
    49     if(!*head) data = *head;
    50     else {
    51         void *next = (*head)->link;
    52         data = (*head)->data;
    53         free(*head);
    54         *head = next;
    55     }
     49    if (!*head)
     50        return NULL;
     51
     52    data = (*head)->data;
     53    next = (*head)->link;
     54    free(*head);
     55    *head = next;
    5656
    5757    return data;
    5858}
    59 #endif
    6059
    61 #ifdef L_llist_free
     60/* Unlink arbitrary given element from the list */
     61void llist_unlink(llist_t **head, llist_t *elm)
     62{
     63    llist_t *crt;
     64
     65    if (!(elm && *head))
     66        return;
     67
     68    if (elm == *head) {
     69        *head = (*head)->link;
     70        return;
     71    }
     72
     73    for (crt = *head; crt; crt = crt->link) {
     74        if (crt->link == elm) {
     75            crt->link = elm->link;
     76            return;
     77        }
     78    }
     79}
     80
    6281/* Recursively free all elements in the linked list.  If freeit != NULL
    6382 * call it on each datum in the list */
    64 void llist_free(llist_t *elm, void (*freeit)(void *data))
     83void llist_free(llist_t *elm, void (*freeit) (void *data))
    6584{
    6685    while (elm) {
    6786        void *data = llist_pop(&elm);
    68         if (freeit) freeit(data);
     87
     88        if (freeit)
     89            freeit(data);
    6990    }
    7091}
     92
     93#ifdef UNUSED
     94/* Reverse list order. */
     95llist_t *llist_rev(llist_t *list)
     96{
     97    llist_t *rev = NULL;
     98
     99    while (list) {
     100        llist_t *next = list->link;
     101
     102        list->link = rev;
     103        rev = list;
     104        list = next;
     105    }
     106    return rev;
     107}
    71108#endif
  • branches/2.2.5/mindi-busybox/libbb/login.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * issue.c: issue printing code
     
    45 * Copyright (C) 2003 Bastian Blank <waldi@tuxbox.org>
    56 *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
     7 * Optimize and correcting OCRNL by Vladimir Oleynik <dzo@simtreas.ru>
    108 *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License
    17  * along with this program; if not, write to the Free Software
    18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    19  *
    20  * Optimize and correcting OCRNL by Vladimir Oleynik <dzo@simtreas.ru>
     9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    2110 */
    2211
    2312#include <sys/param.h>  /* MAXHOSTNAMELEN */
    24 #include <stdio.h>
    25 #include <unistd.h>
     13#include <sys/utsname.h>
    2614#include "libbb.h"
    27 
    28 #include <sys/utsname.h>
    29 #include <time.h>
    3015
    3116#define LOGIN " login: "
    3217
    33 static const char fmtstr_d[] = "%A, %d %B %Y";
    34 static const char fmtstr_t[] = "%H:%M:%S";
     18static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y";
     19static const char fmtstr_t[] ALIGN1 = "%H:%M:%S";
    3520
    3621void print_login_issue(const char *issue_file, const char *tty)
     
    4833    puts("\r"); /* start a new line */
    4934
    50     if ((fd = fopen(issue_file, "r"))) {
    51         while ((c = fgetc(fd)) != EOF) {
    52             outbuf = buf;
    53             buf[0] = c;
    54             if(c == '\n') {
    55                 buf[1] = '\r';
    56                 buf[2] = 0;
    57             } else {
    58                 buf[1] = 0;
     35    fd = fopen(issue_file, "r");
     36    if (!fd)
     37        return;
     38    while ((c = fgetc(fd)) != EOF) {
     39        outbuf = buf;
     40        buf[0] = c;
     41        buf[1] = '\0';
     42        if (c == '\n') {
     43            buf[1] = '\r';
     44            buf[2] = '\0';
     45        }
     46        if (c == '\\' || c == '%') {
     47            c = fgetc(fd);
     48            switch (c) {
     49            case 's':
     50                outbuf = uts.sysname;
     51                break;
     52            case 'n':
     53                outbuf = uts.nodename;
     54                break;
     55            case 'r':
     56                outbuf = uts.release;
     57                break;
     58            case 'v':
     59                outbuf = uts.version;
     60                break;
     61            case 'm':
     62                outbuf = uts.machine;
     63                break;
     64            case 'D':
     65            case 'o':
     66                c = getdomainname(buf, sizeof(buf) - 1);
     67                buf[c >= 0 ? c : 0] = '\0';
     68                break;
     69            case 'd':
     70                strftime(buf, sizeof(buf), fmtstr_d, localtime(&t));
     71                break;
     72            case 't':
     73                strftime(buf, sizeof(buf), fmtstr_t, localtime(&t));
     74                break;
     75            case 'h':
     76                gethostname(buf, sizeof(buf) - 1);
     77                buf[sizeof(buf) - 1] = '\0';
     78                break;
     79            case 'l':
     80                outbuf = tty;
     81                break;
     82            default:
     83                buf[0] = c;
    5984            }
    60             if (c == '\\' || c == '%') {
    61                 c = fgetc(fd);
    62                 switch (c) {
    63                     case 's':
    64                         outbuf = uts.sysname;
    65                         break;
    66 
    67                     case 'n':
    68                         outbuf = uts.nodename;
    69                         break;
    70 
    71                     case 'r':
    72                         outbuf = uts.release;
    73                         break;
    74 
    75                     case 'v':
    76                         outbuf = uts.version;
    77                         break;
    78 
    79                     case 'm':
    80                         outbuf = uts.machine;
    81                         break;
    82 
    83                     case 'D':
    84                     case 'o':
    85                         c = getdomainname(buf, sizeof(buf) - 1);
    86                         buf[c >= 0 ? c : 0] = '\0';
    87                         break;
    88 
    89                     case 'd':
    90                         strftime(buf, sizeof(buf), fmtstr_d, localtime(&t));
    91                         break;
    92 
    93                     case 't':
    94                         strftime(buf, sizeof(buf), fmtstr_t, localtime(&t));
    95                         break;
    96 
    97                     case 'h':
    98                         gethostname(buf, sizeof(buf) - 1);
    99                         buf[sizeof(buf) - 1] = '\0';
    100                         break;
    101 
    102                     case 'l':
    103                         outbuf = tty;
    104                         break;
    105 
    106                     default:
    107                         buf[0] = c;
    108                 }
    109             }
    110             fputs(outbuf, stdout);
    11185        }
    112 
    113         fclose(fd);
    114 
    115         fflush(stdout);
     86        fputs(outbuf, stdout);
    11687    }
     88    fclose(fd);
     89    fflush(stdout);
    11790}
    11891
     
    12194    char buf[MAXHOSTNAMELEN+1];
    12295
    123     if(gethostname(buf, MAXHOSTNAMELEN) == 0)
     96    if (gethostname(buf, MAXHOSTNAMELEN) == 0)
    12497        fputs(buf, stdout);
    12598
     
    127100    fflush(stdout);
    128101}
    129 
  • branches/2.2.5/mindi-busybox/libbb/loop.c

    r821 r1765  
    44 *
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
     6 * Copyright (C) 2005 by Rob Landley <rob@landley.net>
    67 *
    78 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    89 */
    910
    10 
    11 #include <features.h>
    12 #include <stdio.h>
    13 #include <errno.h>
    14 #include <fcntl.h>
    15 #include <string.h>
    16 #include <unistd.h>
    17 #include <sys/ioctl.h>
    1811#include "libbb.h"
    1912
     
    5649    int fd;
    5750    bb_loop_info loopinfo;
    58     char *dev=0;
     51    char *dev = 0;
    5952
    60     if ((fd = open(device, O_RDONLY)) < 0) return 0;
     53    fd = open(device, O_RDONLY);
     54    if (fd < 0) return 0;
    6155    if (!ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo))
    62         dev=bb_xasprintf("%ld %s", (long) loopinfo.lo_offset,
     56        dev = xasprintf("%ld %s", (long) loopinfo.lo_offset,
    6357                (char *)loopinfo.lo_file_name);
    6458    close(fd);
     
    7266    int fd, rc;
    7367
    74     if ((fd = open(device, O_RDONLY)) < 0) return 1;
    75     rc=ioctl(fd, LOOP_CLR_FD, 0);
     68    fd = open(device, O_RDONLY);
     69    if (fd < 0) return 1;
     70    rc = ioctl(fd, LOOP_CLR_FD, 0);
    7671    close(fd);
    7772
     
    8580   file/offset if it finds one.
    8681 */
    87 int set_loop(char **device, const char *file, int offset)
     82int set_loop(char **device, const char *file, unsigned long long offset)
    8883{
    89     char dev[20], *try;
     84    char dev[LOOP_NAMESIZE];
     85    char *try;
    9086    bb_loop_info loopinfo;
    9187    struct stat statbuf;
    92     int i, dfd, ffd, mode, rc=-1;
    93    
     88    int i, dfd, ffd, mode, rc = -1;
     89
    9490    /* Open the file.  Barf if this doesn't work.  */
    95     if((ffd = open(file, mode=O_RDWR))<0 && (ffd = open(file,mode=O_RDONLY))<0)
    96         return -errno;
     91    mode = O_RDWR;
     92    ffd = open(file, mode);
     93    if (ffd < 0) {
     94        mode = O_RDONLY;
     95        ffd = open(file, mode);
     96        if (ffd < 0)
     97            return -errno;
     98    }
    9799
    98100    /* Find a loop device.  */
    99     try=*device ? : dev;
    100     for(i=0;rc;i++) {
     101    try = *device ? : dev;
     102    for (i = 0; rc; i++) {
    101103        sprintf(dev, LOOP_FORMAT, i);
    102104
    103105        /* Ran out of block devices, return failure.  */
    104         if(stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) {
    105             rc=-ENOENT;
     106        if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) {
     107            rc = -ENOENT;
    106108            break;
    107109        }
    108110        /* Open the sucker and check its loopiness.  */
    109         if((dfd=open(try, mode))<0 && errno==EROFS)
    110             dfd=open(try, mode = O_RDONLY);
    111         if(dfd<0) goto try_again;
     111        dfd = open(try, mode);
     112        if (dfd < 0 && errno == EROFS) {
     113            mode = O_RDONLY;
     114            dfd = open(try, mode);
     115        }
     116        if (dfd < 0)
     117            goto try_again;
    112118
    113         rc=ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);
     119        rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);
    114120
    115         /* If device free, claim it.  */
    116         if(rc && errno==ENXIO) {
     121        /* If device is free, claim it.  */
     122        if (rc && errno == ENXIO) {
    117123            memset(&loopinfo, 0, sizeof(loopinfo));
    118124            safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
    119125            loopinfo.lo_offset = offset;
    120126            /* Associate free loop device with file.  */
    121             if(!ioctl(dfd, LOOP_SET_FD, ffd)) {
    122                 if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) rc=0;
    123                 else ioctl(dfd, LOOP_CLR_FD, 0);
     127            if (!ioctl(dfd, LOOP_SET_FD, ffd)) {
     128                if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo))
     129                    rc = 0;
     130                else
     131                    ioctl(dfd, LOOP_CLR_FD, 0);
    124132            }
    125133
     
    129137           without using losetup manually is problematic.)
    130138         */
    131         } else if(strcmp(file,(char *)loopinfo.lo_file_name)
    132                     || offset!=loopinfo.lo_offset) rc=-1;
     139        } else if (strcmp(file, (char *)loopinfo.lo_file_name) != 0
     140        || offset != loopinfo.lo_offset) {
     141            rc = -1;
     142        }
    133143        close(dfd);
    134 try_again:
    135         if(*device) break;
     144 try_again:
     145        if (*device) break;
    136146    }
    137147    close(ffd);
    138     if(!rc) {
    139         if(!*device) *device=strdup(dev);
    140         return mode==O_RDONLY ? 1 : 0;
    141     } else return rc;
     148    if (!rc) {
     149        if (!*device)
     150            *device = xstrdup(dev);
     151        return (mode == O_RDONLY); /* 1:ro, 0:rw */
     152    }
     153    return rc;
    142154}
  • branches/2.2.5/mindi-busybox/libbb/make_directory.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    3623 */
    3724
    38 #include <errno.h>
    39 #include <unistd.h>
    40 #include <sys/stat.h>
    4125#include "libbb.h"
     26
     27/* This function is used from NOFORK applets. It must not allocate anything */
    4228
    4329int bb_make_directory (char *path, long mode, int flags)
     
    11399    } while (1);
    114100
    115     bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);
     101    bb_perror_msg("cannot %s directory '%s'", fail_msg, path);
    116102    return -1;
    117103}
  • branches/2.2.5/mindi-busybox/libbb/md5.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 *  md5.c - Compute MD5 checksum of strings according to the
     
    1213 *  Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    1314 */
    14 #include <fcntl.h>
    15 #include <limits.h>
    16 #include <stdio.h>
    17 #include <stdint.h>
    18 #include <stdlib.h>
    19 #include <string.h>
    20 #include <unistd.h>
    2115
    2216#include "libbb.h"
    2317
    24 # if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3
     18#if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3
    2519# define MD5_SIZE_VS_SPEED 2
    26 # else
     20#else
    2721# define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED
    28 # endif
     22#endif
    2923
    3024/* Initialize structure containing state of computation.
     
    8276    };
    8377
    84     static const char P_array[] = {
     78    static const char P_array[] ALIGN1 = {
    8579#  if MD5_SIZE_VS_SPEED > 1
    8680        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,   /* 1 */
     
    9286
    9387#  if MD5_SIZE_VS_SPEED > 1
    94     static const char S_array[] = {
     88    static const char S_array[] ALIGN1 = {
    9589        7, 12, 17, 22,
    9690        5, 9, 14, 20,
     
    439433    if (buf != ctx->buffer) md5_hash_block(ctx->buffer, ctx);
    440434    md5_hash_block(buf, ctx);
    441    
     435
    442436    /* Put result from CTX in first 16 bytes following RESBUF.  The result is
    443437     * always in little endian byte order, so that a byte-wise output yields
  • branches/2.2.5/mindi-busybox/libbb/messages.c

    r821 r1765  
    44 *
    55 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  *
    76 */
    87
    98#include "libbb.h"
    109
    11 #ifdef L_full_version
    1210#ifndef BB_EXTRA_VERSION
    13 #define LIBBB_BANNER "BusyBox's library v" BB_VER " (" BB_BT ")"
     11#define BANNER "BusyBox v" BB_VER " (" BB_BT ")"
    1412#else
    15 #define LIBBB_BANNER "BusyBox's library v" BB_VER " (" BB_EXTRA_VERSION ")"
     13#define BANNER "BusyBox v" BB_VER " (" BB_EXTRA_VERSION ")"
    1614#endif
    17     const char * const libbb_msg_full_version = LIBBB_BANNER;
    18 #endif
    19 #ifdef L_memory_exhausted
    20     const char * const bb_msg_memory_exhausted = "memory exhausted";
    21 #endif
    22 #ifdef L_invalid_date
    23     const char * const bb_msg_invalid_date = "invalid date `%s'";
    24 #endif
    25 #ifdef L_io_error
    26     const char * const bb_msg_io_error = "%s: input/output error -- %m";
    27 #endif
    28 #ifdef L_write_error
    29     const char * const bb_msg_write_error = "Write Error";
    30 #endif
    31 #ifdef L_read_error
    32     const char * const bb_msg_read_error = "Read Error";
    33 #endif
    34 #ifdef L_name_longer_than_foo
    35     const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported.";
    36 #endif
    37 #ifdef L_unknown
    38     const char * const bb_msg_unknown = "(unknown)";
    39 #endif
    40 #ifdef L_can_not_create_raw_socket
    41     const char * const bb_msg_can_not_create_raw_socket = "can't create raw socket";
    42 #endif
    43 #ifdef L_perm_denied_are_you_root
    44     const char * const bb_msg_perm_denied_are_you_root = "permission denied. (are you root?)";
    45 #endif
    46 #ifdef L_msg_requires_arg
    47     const char * const bb_msg_requires_arg = "%s requires an argument";
    48 #endif
    49 #ifdef L_msg_invalid_arg
    50     const char * const bb_msg_invalid_arg = "invalid argument `%s' to `%s'";
    51 #endif
    52 #ifdef L_msg_standard_input
    53     const char * const bb_msg_standard_input = "standard input";
    54 #endif
    55 #ifdef L_msg_standard_output
    56     const char * const bb_msg_standard_output = "standard output";
    57 #endif
     15const char bb_banner[] ALIGN1 = BANNER;
    5816
    59 #ifdef L_passwd_file
    60 #define PASSWD_FILE        "/etc/passwd"
    61 const char * const bb_path_passwd_file = PASSWD_FILE;
    62 #endif
     17const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted";
     18const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'";
     19const char bb_msg_write_error[] ALIGN1 = "write error";
     20const char bb_msg_read_error[] ALIGN1 = "read error";
     21const char bb_msg_unknown[] ALIGN1 = "(unknown)";
     22const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket";
     23const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied. (are you root?)";
     24const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument";
     25const char bb_msg_invalid_arg[] ALIGN1 = "invalid argument '%s' to '%s'";
     26const char bb_msg_standard_input[] ALIGN1 = "standard input";
     27const char bb_msg_standard_output[] ALIGN1 = "standard output";
    6328
    64 #ifdef L_shadow_file
    65 #define SHADOW_FILE        "/etc/shadow"
    66 const char * const bb_path_shadow_file = SHADOW_FILE;
    67 #endif
     29const char bb_str_default[] ALIGN1 = "default";
     30const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
    6831
    69 #ifdef L_group_file
    70 #define GROUP_FILE         "/etc/group"
    71 const char * const bb_path_group_file = GROUP_FILE;
    72 #endif
     32const char bb_path_passwd_file[] ALIGN1 = "/etc/passwd";
     33const char bb_path_shadow_file[] ALIGN1 = "/etc/shadow";
     34const char bb_path_group_file[] ALIGN1 = "/etc/group";
     35const char bb_path_gshadow_file[] ALIGN1 = "/etc/gshadow";
     36const char bb_path_motd_file[] ALIGN1 = "/etc/motd";
     37const char bb_dev_null[] ALIGN1 = "/dev/null";
     38const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
     39const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
     40/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
     41 * but I want to save a few bytes here. Check libbb.h before changing! */
     42const char bb_PATH_root_path[] ALIGN1 = "PATH=/sbin:/usr/sbin:/bin:/usr/bin";
    7343
    74 #ifdef L_gshadow_file
    75 #define GSHADOW_FILE       "/etc/gshadow"
    76 const char * const bb_path_gshadow_file = GSHADOW_FILE;
    77 #endif
    7844
    79 #ifdef L_nologin_file
    80 #define NOLOGIN_FILE       "/etc/nologin"
    81 const char * const bb_path_nologin_file = NOLOGIN_FILE;
    82 #endif
     45const int const_int_0;
     46const int const_int_1 = 1;
    8347
    84 #ifdef L_securetty_file
    85 #define SECURETTY_FILE     "/etc/securetty"
    86 const char * const bb_path_securetty_file = SECURETTY_FILE;
    87 #endif
    88 
    89 #ifdef L_motd_file
    90 #define MOTD_FILE          "/etc/motd"
    91 const char * const bb_path_motd_file = MOTD_FILE;
    92 #endif
    93 
    94 #ifdef L_shell_file
    95 const char * const bb_default_login_shell = LIBBB_DEFAULT_LOGIN_SHELL;
    96 #endif
    97 
    98 #ifdef L_bb_dev_null
    99 const char * const bb_dev_null = "/dev/null";
    100 #endif
    101 
    102 #ifdef L_bb_path_wtmp_file
    10348#include <utmp.h>
    10449/* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */
    105 const char * const bb_path_wtmp_file =
     50const char bb_path_wtmp_file[] ALIGN1 =
    10651#if defined _PATH_WTMP
    10752_PATH_WTMP;
     
    11156# error unknown path to wtmp file
    11257#endif
    113 #endif
    11458
     59char bb_common_bufsiz1[COMMON_BUFSIZE];
    11560
    116 #ifdef L_bb_common_bufsiz1
    117 char bb_common_bufsiz1[BUFSIZ+1];
    118 #endif
     61struct globals;
     62/* Make it reside in R/W memory: */
     63struct globals *const ptr_to_globals __attribute__ ((section (".data")));
  • branches/2.2.5/mindi-busybox/libbb/mode_string.c

    r821 r1765  
    66 *
    77 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    8  *
    98 */
    109
     
    4948/* The previous version used "0pcCd?bB-?l?s???".  However, the '0', 'C',
    5049 * and 'B' types don't appear to be available on linux.  So I removed them. */
    51 static const char type_chars[16] = "?pc?d?b?-?l?s???";
     50static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???";
    5251/*                                  0123456789abcdef */
    53 static const char mode_chars[7] = "rwxSTst";
     52static const char mode_chars[7] ALIGN1 = "rwxSTst";
    5453
    55 const char *bb_mode_string(int mode)
     54const char *bb_mode_string(mode_t mode)
    5655{
    5756    static char buf[12];
     
    9392static const char mode_chars[7] = "rwxSTst";
    9493
    95 const char *bb_mode_string(int mode)
     94const char *bb_mode_string(mode_t mode)
    9695{
    9796    static char buf[12];
  • branches/2.2.5/mindi-busybox/libbb/mtab.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    208 */
    219
    22 #include <stdlib.h>
    23 #include <unistd.h>
    24 #include <errno.h>
    25 #include <string.h>
    26 #include <stdio.h>
    2710#include <mntent.h>
    2811#include "libbb.h"
    2912
    30 #define MTAB_MAX_ENTRIES 40
    31 
    32 #ifdef CONFIG_FEATURE_MTAB_SUPPORT
     13#if ENABLE_FEATURE_MTAB_SUPPORT
    3314void erase_mtab(const char *name)
    3415{
    35     struct mntent entries[MTAB_MAX_ENTRIES];
    36     int count = 0;
    37     FILE *mountTable = setmntent(bb_path_mtab_file, "r");
     16    struct mntent *entries = NULL;
     17    int i, count = 0;
     18    FILE *mountTable;
    3819    struct mntent *m;
    3920
    40     /* Check if reading the mtab file failed */
    41     if (mountTable == 0
    42             /* Bummer.  fall back on trying the /proc filesystem */
    43             && (mountTable = setmntent("/proc/mounts", "r")) == 0) {
     21    mountTable = setmntent(bb_path_mtab_file, "r");
     22    /* Bummer. Fall back on trying the /proc filesystem */
     23    if (!mountTable) mountTable = setmntent("/proc/mounts", "r");
     24    if (!mountTable) {
    4425        bb_perror_msg(bb_path_mtab_file);
    4526        return;
    4627    }
    4728
    48     while (((m = getmntent(mountTable)) != 0) && (count < MTAB_MAX_ENTRIES))
    49     {
    50         entries[count].mnt_fsname = strdup(m->mnt_fsname);
    51         entries[count].mnt_dir = strdup(m->mnt_dir);
    52         entries[count].mnt_type = strdup(m->mnt_type);
    53         entries[count].mnt_opts = strdup(m->mnt_opts);
    54         entries[count].mnt_freq = m->mnt_freq;
    55         entries[count].mnt_passno = m->mnt_passno;
    56         count++;
     29    while ((m = getmntent(mountTable)) != 0) {
     30        i = count++;
     31        entries = xrealloc(entries, count * sizeof(entries[0]));
     32        entries[i].mnt_fsname = xstrdup(m->mnt_fsname);
     33        entries[i].mnt_dir = xstrdup(m->mnt_dir);
     34        entries[i].mnt_type = xstrdup(m->mnt_type);
     35        entries[i].mnt_opts = xstrdup(m->mnt_opts);
     36        entries[i].mnt_freq = m->mnt_freq;
     37        entries[i].mnt_passno = m->mnt_passno;
    5738    }
    5839    endmntent(mountTable);
    59     if ((mountTable = setmntent(bb_path_mtab_file, "w"))) {
    60         int i;
    6140
     41    mountTable = setmntent(bb_path_mtab_file, "w");
     42    if (mountTable) {
    6243        for (i = 0; i < count; i++) {
    63             int result = (strcmp(entries[i].mnt_fsname, name) == 0
    64                           || strcmp(entries[i].mnt_dir, name) == 0);
    65 
    66             if (result)
    67                 continue;
    68             else
     44            if (strcmp(entries[i].mnt_fsname, name) != 0
     45             && strcmp(entries[i].mnt_dir, name) != 0)
    6946                addmntent(mountTable, &entries[i]);
    7047        }
  • branches/2.2.5/mindi-busybox/libbb/mtab_file.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    1110#include "libbb.h"
    12 
    1311
    1412/* Busybox mount uses either /proc/mounts or /etc/mtab to
    1513 * get the list of currently mounted filesystems */
    16 #if defined(CONFIG_FEATURE_MTAB_SUPPORT)
    17 const char bb_path_mtab_file[] = "/etc/mtab";
    18 #else
    19 const char bb_path_mtab_file[] = "/proc/mounts";
    20 #endif
     14const char bb_path_mtab_file[] ALIGN1 =
     15USE_FEATURE_MTAB_SUPPORT("/etc/mtab")SKIP_FEATURE_MTAB_SUPPORT("/proc/mounts");
  • branches/2.2.5/mindi-busybox/libbb/obscure.c

    r821 r1765  
    4040*/
    4141
    42 #include <ctype.h>
    43 #include <unistd.h>
    44 #include <string.h>
    45 #include <strings.h>
    46 
    4742#include "libbb.h"
    48 
    49 
    50 /* passwords should consist of 6 (to 8 characters) */
    51 #define MINLEN 6
    52 
    5343
    5444static int string_checker_helper(const char *p1, const char *p2) __attribute__ ((__pure__));
     
    7262    int ret = string_checker_helper(p1, p2);
    7363    /* Make our own copy */
    74     char *p = bb_xstrdup(p1);
     64    char *p = xstrdup(p1);
    7565    /* reverse string */
    7666    size = strlen(p);
     
    10191    int length;
    10292    int mixed = 0;
    103     /* Add 1 for each type of characters to the minlen of password */
    104     int size = MINLEN + 8;
     93    /* Add 2 for each type of characters to the minlen of password */
     94    int size = CONFIG_PASSWORD_MINLEN + 8;
    10595    const char *p;
    10696    char hostname[255];
    10797
    10898    /* size */
    109     if (!new_p || (length = strlen(new_p)) < MINLEN)
    110         return("too short");
     99    if (!new_p || (length = strlen(new_p)) < CONFIG_PASSWORD_MINLEN)
     100        return "too short";
    111101
    112102    /* no username as-is, as sub-string, reversed, capitalized, doubled */
     
    168158}
    169159
    170 int obscure(const char *old, const char *newval, const struct passwd *pwdp)
     160int obscure(const char *old, const char *newval, const struct passwd *pw)
    171161{
    172162    const char *msg;
    173163
    174     if ((msg = obscure_msg(old, newval, pwdp))) {
    175         printf("Bad password: %s.\n", msg);
    176         /* If user is root warn only */
    177         return (getuid())? 1 : 0;
     164    msg = obscure_msg(old, newval, pw);
     165    if (msg) {
     166        printf("Bad password: %s\n", msg);
     167        return 1;
    178168    }
    179169    return 0;
  • branches/2.2.5/mindi-busybox/libbb/parse_mode.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    2310/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
    2411
    25 #include <stdlib.h>
    26 #include <assert.h>
    27 #include <sys/stat.h>
    2812#include "libbb.h"
    2913
    30 #define FILEMODEBITS    (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
     14/* This function is used from NOFORK applets. It must not allocate anything */
     15
     16#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
    3117
    3218int bb_parse_mode(const char *s, mode_t *current_mode)
     
    3420    static const mode_t who_mask[] = {
    3521        S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
    36         S_ISUID | S_IRWXU,      /* u */
    37         S_ISGID | S_IRWXG,      /* g */
    38         S_IRWXO                 /* o */
     22        S_ISUID | S_IRWXU,           /* u */
     23        S_ISGID | S_IRWXG,           /* g */
     24        S_IRWXO                      /* o */
    3925    };
    40 
    4126    static const mode_t perm_mask[] = {
    4227        S_IRUSR | S_IRGRP | S_IROTH, /* r */
     
    4429        S_IXUSR | S_IXGRP | S_IXOTH, /* x */
    4530        S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */
    46         S_ISUID | S_ISGID,      /* s */
    47         S_ISVTX                 /* t */
     31        S_ISUID | S_ISGID,           /* s */
     32        S_ISVTX                      /* t */
    4833    };
    49 
    50     static const char who_chars[] = "augo";
    51     static const char perm_chars[] = "rwxXst";
     34    static const char who_chars[] ALIGN1 = "augo";
     35    static const char perm_chars[] ALIGN1 = "rwxXst";
    5236
    5337    const char *p;
    54 
    5538    mode_t wholist;
    5639    mode_t permlist;
    57     mode_t mask;
    5840    mode_t new_mode;
    5941    char op;
    60 
    61     assert(s);
    6242
    6343    if (((unsigned int)(*s - '0')) < 8) {
     
    6545        char *e;
    6646
    67         tmp = strtol(s, &e, 8);
     47        tmp = strtoul(s, &e, 8);
    6848        if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
    6949            return 0;
     
    7353    }
    7454
    75     mask = umask(0);
    76     umask(mask);
    77 
    7855    new_mode = *current_mode;
    7956
    80     /* Note: We allow empty clauses, and hence empty modes.
     57    /* Note: we allow empty clauses, and hence empty modes.
    8158     * We treat an empty mode as no change to perms. */
    8259
    8360    while (*s) {    /* Process clauses. */
    84 
    8561        if (*s == ',') {    /* We allow empty clauses. */
    8662            ++s;
     
    9066        /* Get a wholist. */
    9167        wholist = 0;
    92 
    93     WHO_LIST:
     68 WHO_LIST:
    9469        p = who_chars;
    9570        do {
     
    10984                }
    11085                /* Since op is '=', clear all bits corresponding to the
    111                  * wholist, of all file bits if wholist is empty. */
     86                 * wholist, or all file bits if wholist is empty. */
    11287                permlist = ~FILEMODEBITS;
    11388                if (wholist) {
     
    138113            /* It was not a permcopy, so get a permlist. */
    139114            permlist = 0;
    140 
    141         PERM_LIST:
     115 PERM_LIST:
    142116            p = perm_chars;
    143117            do {
    144118                if (*p == *s) {
    145119                    if ((*p != 'X')
    146                         || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
     120                     || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
    147121                    ) {
    148122                        permlist |= perm_mask[(int)(p-perm_chars)];
     
    154128                }
    155129            } while (*++p);
    156 
    157         GOT_ACTION:
     130 GOT_ACTION:
    158131            if (permlist) { /* The permlist was nonempty. */
    159                 mode_t tmp = ~mask;
    160                 if (wholist) {
    161                     tmp = wholist;
     132                mode_t tmp = wholist;
     133                if (!wholist) {
     134                    mode_t u_mask = umask(0);
     135                    umask(u_mask);
     136                    tmp = ~u_mask;
    162137                }
    163138                permlist &= tmp;
    164 
    165139                if (op == '-') {
    166140                    new_mode &= ~permlist;
     
    173147
    174148    *current_mode = new_mode;
    175 
    176149    return 1;
    177150}
  • branches/2.2.5/mindi-busybox/libbb/perror_msg.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    1410#include "libbb.h"
    1511
     
    1915
    2016    va_start(p, s);
    21     bb_vperror_msg(s, p);
     17    /* Guard against "<error message>: Success" */
     18    bb_verror_msg(s, p, errno ? strerror(errno) : NULL);
    2219    va_end(p);
    2320}
  • branches/2.2.5/mindi-busybox/libbb/perror_msg_and_die.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    1410#include "libbb.h"
    1511
     
    1915
    2016    va_start(p, s);
    21     bb_vperror_msg(s, p);
     17    /* Guard against "<error message>: Success" */
     18    bb_verror_msg(s, p, errno ? strerror(errno) : NULL);
    2219    va_end(p);
    23     exit(bb_default_error_retval);
     20    xfunc_die();
    2421}
  • branches/2.2.5/mindi-busybox/libbb/perror_nomsg.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    23 #include <stddef.h>
    24 #include <libbb.h>
     10/* gcc warns about a null format string, therefore we provide
     11 * modified definition without "attribute (format)"
     12 * instead of including libbb.h */
     13//#include "libbb.h"
     14extern void bb_perror_msg(const char *s, ...);
    2515
     16/* suppress gcc "no previous prototype" warning */
     17void bb_perror_nomsg(void);
    2618void bb_perror_nomsg(void)
    2719{
    28     /* Ignore the gcc warning about a null format string. */
    29     bb_perror_msg(NULL);
     20    bb_perror_msg(0);
    3021}
  • branches/2.2.5/mindi-busybox/libbb/perror_nomsg_and_die.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    23 #include <stddef.h>
    24 #include "libbb.h"
     10/* gcc warns about a null format string, therefore we provide
     11 * modified definition without "attribute (format)"
     12 * instead of including libbb.h */
     13//#include "libbb.h"
     14extern void bb_perror_msg_and_die(const char *s, ...);
    2515
     16/* suppress gcc "no previous prototype" warning */
     17void bb_perror_nomsg_and_die(void);
    2618void bb_perror_nomsg_and_die(void)
    2719{
    28     /* Ignore the gcc warning about a null format string. */
    29     bb_perror_msg_and_die(NULL);
     20    bb_perror_msg_and_die(0);
    3021}
  • branches/2.2.5/mindi-busybox/libbb/process_escape_sequence.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <limits.h>
    13 #include <ctype.h>
    1411#include "libbb.h"
    1512
     
    2219char bb_process_escape_sequence(const char **ptr)
    2320{
    24     static const char charmap[] = {
     21    static const char charmap[] ALIGN1 = {
    2522        'a',  'b',  'f',  'n',  'r',  't',  'v',  '\\', 0,
    2623        '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
     
    4744
    4845    do {
    49         d = (unsigned int)(*q - '0');
     46        d = (unsigned char)(*q) - '0';
    5047#ifdef WANT_HEX_ESCAPES
    5148        if (d >= 10) {
    52             d = ((unsigned int)(_tolower(*q) - 'a')) + 10;
     49            d = (unsigned char)(_tolower(*q)) - 'a' + 10;
    5350        }
    5451#endif
     
    8178            }
    8279        } while (*++p);
    83         n = *(p+(sizeof(charmap)/2));
     80        n = *(p + (sizeof(charmap)/2));
    8481    }
    8582
  • branches/2.2.5/mindi-busybox/libbb/procps.c

    r821 r1765  
    55 * Copyright 1998 by Albert Cahalan; all rights reserved.
    66 * Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru>
     7 * SELinux support: (c) 2007 by Yuichi Nakamura <ynakam@hitachisoft.jp>
    78 *
    89 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    910 */
    1011
    11 #include <dirent.h>
    12 #include <string.h>
    13 #include <stdlib.h>
    14 #include <sys/param.h>
    15 #include <unistd.h>
    16 #include <fcntl.h>
    17 
    1812#include "libbb.h"
    1913
    2014
     15typedef struct unsigned_to_name_map_t {
     16    unsigned id;
     17    char name[USERNAME_MAX_SIZE];
     18} unsigned_to_name_map_t;
     19
     20typedef struct cache_t {
     21    unsigned_to_name_map_t *cache;
     22    int size;
     23} cache_t;
     24
     25static cache_t username, groupname;
     26
     27static void clear_cache(cache_t *cp)
     28{
     29    free(cp->cache);
     30    cp->cache = NULL;
     31    cp->size = 0;
     32}
     33void clear_username_cache(void)
     34{
     35    clear_cache(&username);
     36    clear_cache(&groupname);
     37}
     38
     39#if 0 /* more generic, but we don't need that yet */
     40/* Returns -N-1 if not found. */
     41/* cp->cache[N] is allocated and must be filled in this case */
     42static int get_cached(cache_t *cp, unsigned id)
     43{
     44    int i;
     45    for (i = 0; i < cp->size; i++)
     46        if (cp->cache[i].id == id)
     47            return i;
     48    i = cp->size++;
     49    cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache));
     50    cp->cache[i++].id = id;
     51    return -i;
     52}
     53#endif
     54
     55typedef char* ug_func(char *name, int bufsize, long uid);
     56static char* get_cached(cache_t *cp, unsigned id, ug_func* fp)
     57{
     58    int i;
     59    for (i = 0; i < cp->size; i++)
     60        if (cp->cache[i].id == id)
     61            return cp->cache[i].name;
     62    i = cp->size++;
     63    cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache));
     64    cp->cache[i].id = id;
     65    /* Never fails. Generates numeric string if name isn't found */
     66    fp(cp->cache[i].name, sizeof(cp->cache[i].name), id);
     67    return cp->cache[i].name;
     68}
     69const char* get_cached_username(uid_t uid)
     70{
     71    return get_cached(&username, uid, bb_getpwuid);
     72}
     73const char* get_cached_groupname(gid_t gid)
     74{
     75    return get_cached(&groupname, gid, bb_getgrgid);
     76}
     77
     78
    2179#define PROCPS_BUFSIZE 1024
    2280
     
    2482{
    2583    int fd;
    26     ssize_t ret;
    27 
     84    /* open_read_close() would do two reads, checking for EOF.
     85     * When you have 10000 /proc/$NUM/stat to read, it isn't desirable */
     86    ssize_t ret = -1;
    2887    fd = open(filename, O_RDONLY);
    29     if(fd < 0)
    30         return -1;
    31     ret = read(fd, buf, PROCPS_BUFSIZE-1);
    32     ((char *)buf)[ret > 0 ? ret : 0] = 0;
    33     close(fd);
     88    if (fd >= 0) {
     89        ret = read(fd, buf, PROCPS_BUFSIZE-1);
     90        close(fd);
     91    }
     92    ((char *)buf)[ret > 0 ? ret : 0] = '\0';
    3493    return ret;
    3594}
    3695
    37 
    38 procps_status_t * procps_scan(int save_user_arg0)
    39 {
    40     static DIR *dir;
     96procps_status_t *alloc_procps_scan(int flags)
     97{
     98    procps_status_t* sp = xzalloc(sizeof(procps_status_t));
     99    sp->dir = xopendir("/proc");
     100    return sp;
     101}
     102
     103void free_procps_scan(procps_status_t* sp)
     104{
     105    closedir(sp->dir);
     106    free(sp->argv0);
     107    USE_SELINUX(free(sp->context);)
     108    free(sp);
     109}
     110
     111#if ENABLE_FEATURE_FAST_TOP
     112/* We cut a lot of corners here for speed */
     113static unsigned long fast_strtoul_10(char **endptr)
     114{
     115    char c;
     116    char *str = *endptr;
     117    unsigned long n = *str - '0';
     118
     119    while ((c = *++str) != ' ')
     120        n = n*10 + (c - '0');
     121
     122    *endptr = str + 1; /* We skip trailing space! */
     123    return n;
     124}
     125static char *skip_fields(char *str, int count)
     126{
     127    do {
     128        while (*str++ != ' ')
     129            continue;
     130        /* we found a space char, str points after it */
     131    } while (--count);
     132    return str;
     133}
     134#endif
     135
     136void BUG_comm_size(void);
     137procps_status_t *procps_scan(procps_status_t* sp, int flags)
     138{
    41139    struct dirent *entry;
    42     static procps_status_t ret_status;
    43     char *name;
     140    char buf[PROCPS_BUFSIZE];
     141    char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
     142    char *filename_tail;
     143    long tasknice;
     144    unsigned pid;
    44145    int n;
    45     char status[32];
    46     char *status_tail;
    47     char buf[PROCPS_BUFSIZE];
    48     procps_status_t curstatus;
    49     int pid;
    50     long tasknice;
    51146    struct stat sb;
    52147
    53     if (!dir) {
    54         dir = bb_xopendir("/proc");
     148    if (!sp)
     149        sp = alloc_procps_scan(flags);
     150
     151    for (;;) {
     152        entry = readdir(sp->dir);
     153        if (entry == NULL) {
     154            free_procps_scan(sp);
     155            return NULL;
     156        }
     157        pid = bb_strtou(entry->d_name, NULL, 10);
     158        if (errno)
     159            continue;
     160
     161        /* After this point we have to break, not continue
     162         * ("continue" would mean that current /proc/NNN
     163         * is not a valid process info) */
     164
     165        memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz));
     166
     167        sp->pid = pid;
     168        if (!(flags & ~PSSCAN_PID)) break;
     169
     170#if ENABLE_SELINUX
     171        if (flags & PSSCAN_CONTEXT) {
     172            if (getpidcon(sp->pid, &sp->context) < 0)
     173                sp->context = NULL;
     174        }
     175#endif
     176
     177        filename_tail = filename + sprintf(filename, "/proc/%d", pid);
     178
     179        if (flags & PSSCAN_UIDGID) {
     180            if (stat(filename, &sb))
     181                break;
     182            /* Need comment - is this effective or real UID/GID? */
     183            sp->uid = sb.st_uid;
     184            sp->gid = sb.st_gid;
     185        }
     186
     187        if (flags & PSSCAN_STAT) {
     188            char *cp, *comm1;
     189            int tty;
     190#if !ENABLE_FEATURE_FAST_TOP
     191            unsigned long vsz, rss;
     192#endif
     193
     194            /* see proc(5) for some details on this */
     195            strcpy(filename_tail, "/stat");
     196            n = read_to_buf(filename, buf);
     197            if (n < 0)
     198                break;
     199            cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
     200            /*if (!cp || cp[1] != ' ')
     201                break;*/
     202            cp[0] = '\0';
     203            if (sizeof(sp->comm) < 16)
     204                BUG_comm_size();
     205            comm1 = strchr(buf, '(');
     206            /*if (comm1)*/
     207                safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm));
     208
     209#if !ENABLE_FEATURE_FAST_TOP
     210            n = sscanf(cp+2,
     211                "%c %u "               /* state, ppid */
     212                "%u %u %d %*s "        /* pgid, sid, tty, tpgid */
     213                "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
     214                "%lu %lu "             /* utime, stime */
     215                "%*s %*s %*s "         /* cutime, cstime, priority */
     216                "%ld "                 /* nice */
     217                "%*s %*s %*s "         /* timeout, it_real_value, start_time */
     218                "%lu "                 /* vsize */
     219                "%lu "                 /* rss */
     220            /*  "%lu %lu %lu %lu %lu %lu " rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
     221            /*  "%u %u %u %u "         signal, blocked, sigignore, sigcatch */
     222            /*  "%lu %lu %lu"          wchan, nswap, cnswap */
     223                ,
     224                sp->state, &sp->ppid,
     225                &sp->pgid, &sp->sid, &tty,
     226                &sp->utime, &sp->stime,
     227                &tasknice,
     228                &vsz,
     229                &rss);
     230            if (n != 10)
     231                break;
     232            sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
     233            sp->rss = rss >> 10;
     234            sp->tty_major = (tty >> 8) & 0xfff;
     235            sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00);
     236#else
     237/* This costs ~100 bytes more but makes top faster by 20%
     238 * If you run 10000 processes, this may be important for you */
     239            sp->state[0] = cp[2];
     240            cp += 4;
     241            sp->ppid = fast_strtoul_10(&cp);
     242            sp->pgid = fast_strtoul_10(&cp);
     243            sp->sid = fast_strtoul_10(&cp);
     244            tty = fast_strtoul_10(&cp);
     245            sp->tty_major = (tty >> 8) & 0xfff;
     246            sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00);
     247            cp = skip_fields(cp, 6); /* tpgid, flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
     248            sp->utime = fast_strtoul_10(&cp);
     249            sp->stime = fast_strtoul_10(&cp);
     250            cp = skip_fields(cp, 3); /* cutime, cstime, priority */
     251            tasknice = fast_strtoul_10(&cp);
     252            cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */
     253            sp->vsz = fast_strtoul_10(&cp) >> 10; /* vsize is in bytes and we want kb */
     254            sp->rss = fast_strtoul_10(&cp) >> 10;
     255#endif
     256
     257            if (sp->vsz == 0 && sp->state[0] != 'Z')
     258                sp->state[1] = 'W';
     259            else
     260                sp->state[1] = ' ';
     261            if (tasknice < 0)
     262                sp->state[2] = '<';
     263            else if (tasknice) /* > 0 */
     264                sp->state[2] = 'N';
     265            else
     266                sp->state[2] = ' ';
     267
     268        }
     269
     270#if 0 /* PSSCAN_CMD is not used */
     271        if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
     272            if (sp->argv0) {
     273                free(sp->argv0);
     274                sp->argv0 = NULL;
     275            }
     276            if (sp->cmd) {
     277                free(sp->cmd);
     278                sp->cmd = NULL;
     279            }
     280            strcpy(filename_tail, "/cmdline");
     281            /* TODO: to get rid of size limits, read into malloc buf,
     282             * then realloc it down to real size. */
     283            n = read_to_buf(filename, buf);
     284            if (n <= 0)
     285                break;
     286            if (flags & PSSCAN_ARGV0)
     287                sp->argv0 = xstrdup(buf);
     288            if (flags & PSSCAN_CMD) {
     289                do {
     290                    n--;
     291                    if ((unsigned char)(buf[n]) < ' ')
     292                        buf[n] = ' ';
     293                } while (n);
     294                sp->cmd = xstrdup(buf);
     295            }
     296        }
     297#else
     298        if (flags & PSSCAN_ARGV0) {
     299            if (sp->argv0) {
     300                free(sp->argv0);
     301                sp->argv0 = NULL;
     302            }
     303            strcpy(filename_tail, "/cmdline");
     304            n = read_to_buf(filename, buf);
     305            if (n <= 0)
     306                break;
     307            if (flags & PSSCAN_ARGV0)
     308                sp->argv0 = xstrdup(buf);
     309        }
     310#endif
     311        break;
    55312    }
    56     for(;;) {
    57         if((entry = readdir(dir)) == NULL) {
    58             closedir(dir);
    59             dir = 0;
    60             return 0;
    61         }
    62         name = entry->d_name;
    63         if (!(*name >= '0' && *name <= '9'))
    64             continue;
    65 
    66         memset(&curstatus, 0, sizeof(procps_status_t));
    67         pid = atoi(name);
    68         curstatus.pid = pid;
    69 
    70         status_tail = status + sprintf(status, "/proc/%d", pid);
    71         if(stat(status, &sb))
    72             continue;
    73         bb_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user));
    74 
    75         /* see proc(5) for some details on this */
    76         strcpy(status_tail, "/stat");
    77         n = read_to_buf(status, buf);
    78         if(n < 0)
    79             continue;
    80         name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
    81         if(name == 0 || name[1] != ' ')
    82             continue;
    83         *name = 0;
    84         sscanf(buf, "%*s (%15c", curstatus.short_cmd);
    85         n = sscanf(name+2,
    86         "%c %d "
    87         "%*s %*s %*s %*s "     /* pgrp, session, tty, tpgid */
    88         "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
    89 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    90         "%lu %lu "             /* utime, stime */
    91 #else
    92         "%*s %*s "             /* utime, stime */
    93 #endif
    94         "%*s %*s %*s "         /* cutime, cstime, priority */
    95         "%ld "                 /* nice */
    96         "%*s %*s %*s "         /* timeout, it_real_value, start_time */
    97         "%*s "                 /* vsize */
    98         "%ld",                 /* rss */
    99         curstatus.state, &curstatus.ppid,
    100 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    101         &curstatus.utime, &curstatus.stime,
    102 #endif
    103         &tasknice,
    104         &curstatus.rss);
    105 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    106         if(n != 6)
    107 #else
    108         if(n != 4)
    109 #endif
    110             continue;
    111 
    112         if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
    113             curstatus.state[1] = 'W';
    114         else
    115             curstatus.state[1] = ' ';
    116         if (tasknice < 0)
    117             curstatus.state[2] = '<';
    118         else if (tasknice > 0)
    119             curstatus.state[2] = 'N';
    120         else
    121             curstatus.state[2] = ' ';
    122 
    123 #ifdef PAGE_SHIFT
    124         curstatus.rss <<= (PAGE_SHIFT - 10);     /* 2**10 = 1kb */
    125 #else
    126         curstatus.rss *= (getpagesize() >> 10);     /* 2**10 = 1kb */
    127 #endif
    128 
    129         if(save_user_arg0) {
    130             strcpy(status_tail, "/cmdline");
    131             n = read_to_buf(status, buf);
    132             if(n > 0) {
    133                 if(buf[n-1]=='\n')
    134                     buf[--n] = 0;
    135                 name = buf;
    136                 while(n) {
    137                     if(((unsigned char)*name) < ' ')
    138                         *name = ' ';
    139                     name++;
    140                     n--;
    141                 }
    142                 *name = 0;
    143                 if(buf[0])
    144                     curstatus.cmd = strdup(buf);
    145                 /* if NULL it work true also */
    146             }
    147         }
    148         return memcpy(&ret_status, &curstatus, sizeof(procps_status_t));
     313    return sp;
     314}
     315
     316void read_cmdline(char *buf, int col, unsigned pid, const char *comm)
     317{
     318    ssize_t sz;
     319    char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
     320
     321    sprintf(filename, "/proc/%u/cmdline", pid);
     322    sz = open_read_close(filename, buf, col);
     323    if (sz > 0) {
     324        buf[sz] = '\0';
     325        while (--sz >= 0)
     326            if ((unsigned char)(buf[sz]) < ' ')
     327                buf[sz] = ' ';
     328    } else {
     329        snprintf(buf, col, "[%s]", comm);
    149330    }
    150331}
     332
     333/* from kernel:
     334    //             pid comm S ppid pgid sid tty_nr tty_pgrp flg
     335    sprintf(buffer,"%d (%s) %c %d  %d   %d  %d     %d       %lu %lu \
     336%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
     337%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
     338        task->pid,
     339        tcomm,
     340        state,
     341        ppid,
     342        pgid,
     343        sid,
     344        tty_nr,
     345        tty_pgrp,
     346        task->flags,
     347        min_flt,
     348        cmin_flt,
     349        maj_flt,
     350        cmaj_flt,
     351        cputime_to_clock_t(utime),
     352        cputime_to_clock_t(stime),
     353        cputime_to_clock_t(cutime),
     354        cputime_to_clock_t(cstime),
     355        priority,
     356        nice,
     357        num_threads,
     358        // 0,
     359        start_time,
     360        vsize,
     361        mm ? get_mm_rss(mm) : 0,
     362        rsslim,
     363        mm ? mm->start_code : 0,
     364        mm ? mm->end_code : 0,
     365        mm ? mm->start_stack : 0,
     366        esp,
     367        eip,
     368the rest is some obsolete cruft
     369*/
  • branches/2.2.5/mindi-busybox/libbb/pw_encrypt.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    2310#include "libbb.h"
    24 #include <string.h>
    2511#include <crypt.h>
    26 
    2712
    2813char *pw_encrypt(const char *clear, const char *salt)
    2914{
    30     static char cipher[128];
    31     char *cp;
     15    /* Was static char[BIGNUM]. Malloced thing works as well */
     16    static char *cipher;
    3217
    33 #ifdef CONFIG_FEATURE_SHA1_PASSWORDS
     18#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */
    3419    if (strncmp(salt, "$2$", 3) == 0) {
    3520        return sha1_crypt(clear);
    3621    }
    3722#endif
    38     cp = (char *) crypt(clear, salt);
    39     /* if crypt (a nonstandard crypt) returns a string too large,
    40        truncate it so we don't overrun buffers and hope there is
    41        enough security in what's left */
    42     safe_strncpy(cipher, cp, sizeof(cipher));
     23
     24    free(cipher);
     25    cipher = xstrdup(crypt(clear, salt));
    4326    return cipher;
    4427}
    45 
  • branches/2.2.5/mindi-busybox/libbb/recursive_action.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <string.h>
    12 #include <dirent.h>
    13 #include <sys/stat.h>
    14 #include <stdlib.h> /* free() */
    1510#include "libbb.h"
    1611
    1712#undef DEBUG_RECURS_ACTION
    18 
    1913
    2014/*
     
    2822 * is so stinking huge.
    2923 */
     24
     25static int true_action(const char *fileName, struct stat *statbuf,
     26                        void* userData, int depth)
     27{
     28    return TRUE;
     29}
     30
     31/* fileAction return value of 0 on any file in directory will make
     32 * recursive_action() return 0, but it doesn't stop directory traversal
     33 * (fileAction/dirAction will be called on each file).
     34 *
     35 * if !depthFirst, dirAction return value of 0 (FALSE) or 2 (SKIP)
     36 * prevents recursion into that directory, instead
     37 * recursive_action() returns 0 (if FALSE) or 1 (if SKIP).
     38 *
     39 * followLinks=0/1 differs mainly in handling of links to dirs.
     40 * 0: lstat(statbuf). Calls fileAction on link name even if points to dir.
     41 * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
     42 */
     43
    3044int recursive_action(const char *fileName,
    31                     int recurse, int followLinks, int depthFirst,
    32                     int (*fileAction) (const char *fileName,
    33                                        struct stat * statbuf,
    34                                        void* userData),
    35                     int (*dirAction) (const char *fileName,
    36                                       struct stat * statbuf,
    37                                       void* userData),
    38                     void* userData)
     45        unsigned flags,
     46        int (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
     47        int (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
     48        void* userData,
     49        unsigned depth)
    3950{
     51    struct stat statbuf;
    4052    int status;
    41     struct stat statbuf;
     53    DIR *dir;
    4254    struct dirent *next;
    4355
    44     if (followLinks)
    45         status = stat(fileName, &statbuf);
    46     else
    47         status = lstat(fileName, &statbuf);
     56    if (!fileAction) fileAction = true_action;
     57    if (!dirAction) dirAction = true_action;
    4858
     59    status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */
     60    if (!depth) status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
     61    status = ((flags & status) ? stat : lstat)(fileName, &statbuf);
    4962    if (status < 0) {
    5063#ifdef DEBUG_RECURS_ACTION
    51         bb_error_msg("status=%d followLinks=%d TRUE=%d",
    52                 status, followLinks, TRUE);
     64        bb_error_msg("status=%d flags=%x", status, flags);
    5365#endif
    54         bb_perror_msg("%s", fileName);
    55         return FALSE;
     66        goto done_nak_warn;
    5667    }
    5768
    58     if (! followLinks && (S_ISLNK(statbuf.st_mode))) {
    59         if (fileAction == NULL)
    60             return TRUE;
    61         else
    62             return fileAction(fileName, &statbuf, userData);
     69    /* If S_ISLNK(m), then we know that !S_ISDIR(m).
     70     * Then we can skip checking first part: if it is true, then
     71     * (!dir) is also true! */
     72    if ( /* (!(flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */
     73     !S_ISDIR(statbuf.st_mode)
     74    ) {
     75        return fileAction(fileName, &statbuf, userData, depth);
    6376    }
    6477
    65     if (! recurse) {
    66         if (S_ISDIR(statbuf.st_mode)) {
    67             if (dirAction != NULL)
    68                 return (dirAction(fileName, &statbuf, userData));
    69             else
    70                 return TRUE;
    71         }
     78    /* It's a directory (or a link to one, and followLinks is set) */
     79
     80    if (!(flags & ACTION_RECURSE)) {
     81        return dirAction(fileName, &statbuf, userData, depth);
    7282    }
    7383
    74     if (S_ISDIR(statbuf.st_mode)) {
    75         DIR *dir;
     84    if (!(flags & ACTION_DEPTHFIRST)) {
     85        status = dirAction(fileName, &statbuf, userData, depth);
     86        if (!status)
     87            goto done_nak_warn;
     88        if (status == SKIP)
     89            return TRUE;
     90    }
    7691
    77         if (dirAction != NULL && ! depthFirst) {
    78             status = dirAction(fileName, &statbuf, userData);
    79             if (! status) {
    80                 bb_perror_msg("%s", fileName);
    81                 return FALSE;
    82             } else if (status == SKIP)
    83                 return TRUE;
    84         }
    85         dir = bb_opendir(fileName);
    86         if (!dir) {
    87             return FALSE;
    88         }
    89         status = TRUE;
    90         while ((next = readdir(dir)) != NULL) {
    91             char *nextFile;
     92    dir = opendir(fileName);
     93    if (!dir) {
     94        /* findutils-4.1.20 reports this */
     95        /* (i.e. it doesn't silently return with exit code 1) */
     96        /* To trigger: "find -exec rm -rf {} \;" */
     97        goto done_nak_warn;
     98    }
     99    status = TRUE;
     100    while ((next = readdir(dir)) != NULL) {
     101        char *nextFile;
    92102
    93             nextFile = concat_subpath_file(fileName, next->d_name);
    94             if(nextFile == NULL)
    95                 continue;
    96             if (! recursive_action(nextFile, TRUE, followLinks, depthFirst,
    97                         fileAction, dirAction, userData)) {
    98                 status = FALSE;
    99             }
    100             free(nextFile);
    101         }
    102         closedir(dir);
    103         if (dirAction != NULL && depthFirst) {
    104             if (! dirAction(fileName, &statbuf, userData)) {
    105                 bb_perror_msg("%s", fileName);
    106                 return FALSE;
    107             }
    108         }
    109         if (! status)
    110             return FALSE;
    111     } else {
    112         if (fileAction == NULL)
    113             return TRUE;
    114         else
    115             return fileAction(fileName, &statbuf, userData);
     103        nextFile = concat_subpath_file(fileName, next->d_name);
     104        if (nextFile == NULL)
     105            continue;
     106        /* now descend into it (NB: ACTION_RECURSE is set in flags) */
     107        if (!recursive_action(nextFile, flags, fileAction, dirAction, userData, depth+1))
     108            status = FALSE;
     109        free(nextFile);
    116110    }
     111    closedir(dir);
     112
     113    if (flags & ACTION_DEPTHFIRST) {
     114        if (!dirAction(fileName, &statbuf, userData, depth))
     115            goto done_nak_warn;
     116    }
     117
     118    if (!status)
     119        return FALSE;
    117120    return TRUE;
     121
     122 done_nak_warn:
     123    bb_perror_msg("%s", fileName);
     124    return FALSE;
    118125}
  • branches/2.2.5/mindi-busybox/libbb/remove_file.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <time.h>
    12 #include <utime.h>
    13 #include <dirent.h>
    14 #include <errno.h>
    15 #include <unistd.h>
    16 #include <stdlib.h>
    17 #include <string.h>
    18 #include <getopt.h>
    1910#include "libbb.h"
     11
     12/* Used from NOFORK applets. Must not allocate anything */
    2013
    2114int remove_file(const char *path, int flags)
    2215{
    2316    struct stat path_stat;
    24     int path_exists = 1;
    2517
    2618    if (lstat(path, &path_stat) < 0) {
    2719        if (errno != ENOENT) {
    28             bb_perror_msg("unable to stat `%s'", path);
     20            bb_perror_msg("cannot stat '%s'", path);
    2921            return -1;
    3022        }
    31 
    32         path_exists = 0;
    33     }
    34 
    35     if (!path_exists) {
    3623        if (!(flags & FILEUTILS_FORCE)) {
    37             bb_perror_msg("cannot remove `%s'", path);
     24            bb_perror_msg("cannot remove '%s'", path);
    3825            return -1;
    3926        }
     
    5138        }
    5239
    53         if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
    54                     isatty(0)) ||
    55                 (flags & FILEUTILS_INTERACTIVE)) {
    56             fprintf(stderr, "%s: descend into directory `%s'? ", bb_applet_name,
     40        if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 && isatty(0))
     41         || (flags & FILEUTILS_INTERACTIVE)
     42        ) {
     43            fprintf(stderr, "%s: descend into directory '%s'? ", applet_name,
    5744                    path);
    5845            if (!bb_ask_confirmation())
     
    6047        }
    6148
    62         if ((dp = bb_opendir(path)) == NULL) {
     49        dp = opendir(path);
     50        if (dp == NULL) {
    6351            return -1;
    6452        }
     
    6856
    6957            new_path = concat_subpath_file(path, d->d_name);
    70             if(new_path == NULL)
     58            if (new_path == NULL)
    7159                continue;
    7260            if (remove_file(new_path, flags) < 0)
     
    7664
    7765        if (closedir(dp) < 0) {
    78             bb_perror_msg("unable to close `%s'", path);
     66            bb_perror_msg("cannot close '%s'", path);
    7967            return -1;
    8068        }
    8169
    8270        if (flags & FILEUTILS_INTERACTIVE) {
    83             fprintf(stderr, "%s: remove directory `%s'? ", bb_applet_name, path);
     71            fprintf(stderr, "%s: remove directory '%s'? ", applet_name, path);
    8472            if (!bb_ask_confirmation())
    8573                return status;
     
    8775
    8876        if (rmdir(path) < 0) {
    89             bb_perror_msg("unable to remove `%s'", path);
     77            bb_perror_msg("cannot remove '%s'", path);
    9078            return -1;
    9179        }
    9280
    9381        return status;
    94     } else {
    95         if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
    96                     !S_ISLNK(path_stat.st_mode) &&
    97                     isatty(0)) ||
    98                 (flags & FILEUTILS_INTERACTIVE)) {
    99             fprintf(stderr, "%s: remove `%s'? ", bb_applet_name, path);
    100             if (!bb_ask_confirmation())
    101                 return 0;
    102         }
     82    }
    10383
    104         if (unlink(path) < 0) {
    105             bb_perror_msg("unable to remove `%s'", path);
    106             return -1;
    107         }
     84    /* !ISDIR */
     85    if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0
     86            && !S_ISLNK(path_stat.st_mode) && isatty(0))
     87     || (flags & FILEUTILS_INTERACTIVE)
     88    ) {
     89        fprintf(stderr, "%s: remove '%s'? ", applet_name, path);
     90        if (!bb_ask_confirmation())
     91            return 0;
     92    }
    10893
    109         return 0;
     94    if (unlink(path) < 0) {
     95        bb_perror_msg("cannot remove '%s'", path);
     96        return -1;
    11097    }
     98
     99    return 0;
    111100}
  • branches/2.2.5/mindi-busybox/libbb/restricted_shell.c

    r821 r1765  
    2929 */
    3030
    31 #include <stdio.h>
    32 #include <errno.h>
    33 #include <unistd.h>
    34 #include <string.h>
    35 #include <stdlib.h>
    36 #include <syslog.h>
    37 #include <ctype.h>
    3831#include "libbb.h"
    39 
    40 
    4132
    4233/* Return 1 if SHELL is a restricted shell (one not returned by
    4334   getusershell), else 0, meaning it is a standard shell.  */
    44 
    45 int restricted_shell ( const char *shell )
     35int restricted_shell(const char *shell)
    4636{
    4737    char *line;
    4838
    49     setusershell ( );
    50     while (( line = getusershell ( ))) {
    51         if (( *line != '#' ) && ( strcmp ( line, shell ) == 0 ))
    52             break;
     39    setusershell();
     40    while ((line = getusershell())) {
     41        if (*line != '#' && strcmp(line, shell) == 0)
     42            return 0;
    5343    }
    54     endusershell ( );
    55     return line ? 0 : 1;
     44    endusershell();
     45    return 1;
    5646}
    57 
  • branches/2.2.5/mindi-busybox/libbb/run_shell.c

    r821 r1765  
    2929 */
    3030
    31 #include <stdio.h>
    32 #include <errno.h>
    33 #include <unistd.h>
    34 #include <string.h>
    35 #include <stdlib.h>
    36 #include <syslog.h>
    37 #include <ctype.h>
    3831#include "libbb.h"
    39 #ifdef CONFIG_SELINUX
     32#if ENABLE_SELINUX
    4033#include <selinux/selinux.h>  /* for setexeccon  */
    4134#endif
    4235
    43 #ifdef CONFIG_SELINUX
    44 static security_context_t current_sid=NULL;
     36#if ENABLE_SELINUX
     37static security_context_t current_sid;
    4538
    4639void
    4740renew_current_security_context(void)
    4841{
    49   if  (current_sid)
    50     freecon(current_sid);  /* Release old context  */
    51 
    52   getcon(&current_sid);  /* update */
    53 
    54   return;
     42    if (current_sid)
     43        freecon(current_sid);  /* Release old context  */
     44    getcon(&current_sid);  /* update */
    5545}
    5646void
    5747set_current_security_context(security_context_t sid)
    5848{
    59   if  (current_sid)
    60     freecon(current_sid);  /* Release old context  */
    61 
    62   current_sid=sid;
    63 
    64   return;
     49    if (current_sid)
     50        freecon(current_sid);  /* Release old context  */
     51    current_sid = sid;
    6552}
    6653
     
    7259   arguments.  */
    7360
    74 void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args)
     61void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args)
    7562{
    7663    const char **args;
     
    7865    int additional_args_cnt = 0;
    7966
    80     for ( args = additional_args; args && *args; args++ )
     67    for (args = additional_args; args && *args; args++)
    8168        additional_args_cnt++;
    8269
    83         args = (const char **) xmalloc (sizeof (char *) * ( 4  + additional_args_cnt ));
     70    args = xmalloc(sizeof(char*) * (4 + additional_args_cnt));
    8471
    85     args [0] = bb_get_last_path_component ( bb_xstrdup ( shell ));
     72    args[0] = bb_get_last_path_component(xstrdup(shell));
    8673
    87     if ( loginshell )
    88         args [0] = bb_xasprintf ("-%s", args [0]);
     74    if (loginshell)
     75        args[0] = xasprintf("-%s", args[0]);
    8976
    90     if ( command ) {
    91         args [argno++] = "-c";
    92         args [argno++] = command;
     77    if (command) {
     78        args[argno++] = "-c";
     79        args[argno++] = command;
    9380    }
    94     if ( additional_args ) {
    95         for ( ; *additional_args; ++additional_args )
    96             args [argno++] = *additional_args;
     81    if (additional_args) {
     82        for (; *additional_args; ++additional_args)
     83            args[argno++] = *additional_args;
    9784    }
    98     args [argno] = 0;
    99 #ifdef CONFIG_SELINUX
    100     if ( (current_sid) && (!setexeccon(current_sid)) ) {
    101         freecon(current_sid);
    102         execve(shell, (char **) args, environ);
     85    args[argno] = NULL;
     86#if ENABLE_SELINUX
     87    if (current_sid && !setexeccon(current_sid)) {
     88        freecon(current_sid);
     89        execve(shell, (char **) args, environ);
    10390    } else
    10491#endif
    105       execv ( shell, (char **) args );
    106     bb_perror_msg_and_die ( "cannot run %s", shell );
     92    execv(shell, (char **) args);
     93    bb_perror_msg_and_die("cannot run %s", shell);
    10794}
  • branches/2.2.5/mindi-busybox/libbb/safe_strncpy.c

    r821 r1765  
    88 */
    99
    10 #include <string.h>
    1110#include "libbb.h"
    12 
    13 
    1411
    1512/* Like strncpy but make sure the resulting string is always 0 terminated. */
    1613char * safe_strncpy(char *dst, const char *src, size_t size)
    1714{
    18     dst[size-1] = '\0';
    19     return strncpy(dst, src, size-1);
     15    if (!size) return dst;
     16    dst[--size] = '\0';
     17    return strncpy(dst, src, size);
    2018}
  • branches/2.2.5/mindi-busybox/libbb/safe_write.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <unistd.h>
    1310#include "libbb.h"
    14 
    15 
    1611
    1712ssize_t safe_write(int fd, const void *buf, size_t count)
  • branches/2.2.5/mindi-busybox/libbb/setup_environment.c

    r821 r1765  
    2929 */
    3030
    31 #include <stdio.h>
    32 #include <errno.h>
    33 #include <unistd.h>
    34 #include <string.h>
    35 #include <stdlib.h>
    36 #include <syslog.h>
    37 #include <ctype.h>
    3831#include "libbb.h"
    3932
    40 
    41 
    42 #define DEFAULT_LOGIN_PATH      "/bin:/usr/bin"
    43 #define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin"
    44 
    45 static void xsetenv ( const char *key, const char *value )
     33void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw)
    4634{
    47         if ( setenv ( key, value, 1 ))
    48                 bb_error_msg_and_die (bb_msg_memory_exhausted);
    49 }
    50 
    51 void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw )
    52 {
    53     if ( loginshell ) {
     35    if (loginshell) {
    5436        const char *term;
    5537
     
    6042         * Some systems default to HOME=/
    6143         */
    62         if ( chdir ( pw-> pw_dir )) {
    63             if ( chdir ( "/" )) {
    64                 syslog ( LOG_WARNING, "unable to cd to %s' for user %s'\n", pw-> pw_dir, pw-> pw_name );
    65                 bb_error_msg_and_die ( "cannot cd to home directory or /" );
    66             }
    67             fputs ( "warning: cannot change to home directory\n", stderr );
     44        if (chdir(pw->pw_dir)) {
     45            xchdir("/");
     46            fputs("warning: cannot change to home directory\n", stderr);
    6847        }
    6948
    7049        /* Leave TERM unchanged.  Set HOME, SHELL, USER, LOGNAME, PATH.
    7150           Unset all other environment variables.  */
    72         term = getenv ("TERM");
    73         clearenv ( );
    74         if ( term )
    75             xsetenv ( "TERM", term );
    76         xsetenv ( "HOME",    pw-> pw_dir );
    77         xsetenv ( "SHELL",   shell );
    78         xsetenv ( "USER",    pw-> pw_name );
    79         xsetenv ( "LOGNAME", pw-> pw_name );
    80         xsetenv ( "PATH",    ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ));
     51        term = getenv("TERM");
     52        clearenv();
     53        if (term)
     54            xsetenv("TERM", term);
     55        xsetenv("HOME",    pw->pw_dir);
     56        xsetenv("SHELL",   shell);
     57        xsetenv("USER",    pw->pw_name);
     58        xsetenv("LOGNAME", pw->pw_name);
     59        xsetenv("PATH",   (pw->pw_uid ? bb_default_path : bb_default_root_path));
    8160    }
    82     else if ( changeenv ) {
     61    else if (changeenv) {
    8362        /* Set HOME, SHELL, and if not becoming a super-user,
    8463           USER and LOGNAME.  */
    85         xsetenv ( "HOME",  pw-> pw_dir );
    86         xsetenv ( "SHELL", shell );
    87         if  ( pw-> pw_uid ) {
    88             xsetenv ( "USER",    pw-> pw_name );
    89             xsetenv ( "LOGNAME", pw-> pw_name );
     64        xsetenv("HOME",  pw->pw_dir);
     65        xsetenv("SHELL", shell);
     66        if (pw->pw_uid) {
     67            xsetenv("USER",    pw->pw_name);
     68            xsetenv("LOGNAME", pw->pw_name);
    9069        }
    9170    }
    9271}
    93 
  • branches/2.2.5/mindi-busybox/libbb/sha1.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 *  Based on shasum from http://www.netsw.org/crypto/hash/
     
    67 *  Copyright (C) 2003 Glenn L. McGrath
    78 *  Copyright (C) 2003 Erik Andersen
    8  * 
    9  *  LICENSE TERMS
    109 *
    11  *  The free distribution and use of this software in both source and binary
    12  *  form is allowed (with or without changes) provided that:
     10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1311 *
    14  *    1. distributions of this source code include the above copyright
    15  *       notice, this list of conditions and the following disclaimer;
    16  *
    17  *    2. distributions in binary form include the above copyright
    18  *       notice, this list of conditions and the following disclaimer
    19  *       in the documentation and/or other associated materials;
    20  *
    21  *    3. the copyright holder's name is not used to endorse products
    22  *       built using this software without specific written permission.
    23  *
    24  *  ALTERNATIVELY, provided that this notice is retained in full, this product
    25  *  may be distributed under the terms of the GNU General Public License (GPL),
    26  *  in which case the provisions of the GPL apply INSTEAD OF those given above.
    27  *
    28  *  DISCLAIMER
    29  *
    30  *  This software is provided 'as is' with no explicit or implied warranties
    31  *  in respect of its properties, including, but not limited to, correctness
    32  *  and/or fitness for purpose.
    3312 *  ---------------------------------------------------------------------------
    3413 *  Issue Date: 10/11/2002
     
    3817 */
    3918
    40 #include <fcntl.h>
    41 #include <limits.h>
    42 #include <stdio.h>
    43 #include <stdint.h>
    44 #include <stdlib.h>
    45 #include <string.h>
    46 #include <unistd.h>
    47 
    4819#include "libbb.h"
    4920
    50 # define SHA1_BLOCK_SIZE  64
    51 # define SHA1_DIGEST_SIZE 20
    52 # define SHA1_HASH_SIZE   SHA1_DIGEST_SIZE
    53 # define SHA2_GOOD        0
    54 # define SHA2_BAD         1
     21#define SHA1_BLOCK_SIZE  64
     22#define SHA1_DIGEST_SIZE 20
     23#define SHA1_HASH_SIZE   SHA1_DIGEST_SIZE
     24#define SHA2_GOOD        0
     25#define SHA2_BAD         1
    5526
    56 # define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
     27#define rotl32(x,n)      (((x) << n) | ((x) >> (32 - n)))
    5728
    58 # define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
     29#define SHA1_MASK        (SHA1_BLOCK_SIZE - 1)
    5930
    6031/* reverse byte order in 32-bit words   */
    61 #define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
    62 #define parity(x,y,z)   ((x) ^ (y) ^ (z))
    63 #define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) | (y))))
     32#define ch(x,y,z)        ((z) ^ ((x) & ((y) ^ (z))))
     33#define parity(x,y,z)    ((x) ^ (y) ^ (z))
     34#define maj(x,y,z)       (((x) & (y)) | ((z) & ((x) | (y))))
    6435
    6536/* A normal version as set out in the FIPS. This version uses   */
    6637/* partial loop unrolling and is optimised for the Pentium 4    */
    67 # define rnd(f,k)    \
    68     t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \
    69     e = d; d = c; c = rotl32(b, 30); b = t
    70 
     38#define rnd(f,k) \
     39    do { \
     40        t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \
     41        e = d; d = c; c = rotl32(b, 30); b = t; \
     42    } while (0)
    7143
    7244static void sha1_compile(sha1_ctx_t *ctx)
     
    182154
    183155    /* assemble the eight byte counter in the buffer in big-endian  */
    184     /* format                                  */
     156    /* format                                   */
    185157
    186158    ctx->wbuf[14] = htonl((ctx->count[1] << 3) | (ctx->count[0] >> 29));
     
    194166    for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
    195167        hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3));
    196    
     168
    197169    return resbuf;
    198170}
    199 
    200 
  • branches/2.2.5/mindi-busybox/libbb/simplify_path.c

    r821 r1765  
    55 * Copyright (C) 2001  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    23 #include <stdlib.h>
    2410#include "libbb.h"
    2511
     
    2915
    3016    if (path[0] == '/')
    31         start = bb_xstrdup(path);
     17        start = xstrdup(path);
    3218    else {
    33         s = xgetcwd(NULL);
     19        s = xrealloc_getcwd_or_warn(NULL);
    3420        start = concat_path_file(s, path);
    3521        free(s);
     
    4127            if (*s == '/') {    /* skip duplicate (or initial) slash */
    4228                continue;
    43             } else if (*s == '.') {
    44                 if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */
     29            }
     30            if (*s == '.') {
     31                if (s[1] == '/' || !s[1]) { /* remove extra '.' */
    4532                    continue;
    46                 } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) {
     33                }
     34                if ((s[1] == '.') && (s[2] == '/' || !s[2])) {
    4735                    ++s;
    4836                    if (p > start) {
    49                         while (*--p != '/');    /* omit previous dir */
     37                        while (*--p != '/') /* omit previous dir */
     38                            continue;
    5039                    }
    5140                    continue;
  • branches/2.2.5/mindi-busybox/libbb/skip_whitespace.c

    r821 r1765  
    88 */
    99
    10 #include <ctype.h>
    1110#include "libbb.h"
    1211
    1312char *skip_whitespace(const char *s)
    1413{
     14    /* NB: isspace('0') returns 0 */
    1515    while (isspace(*s)) ++s;
    1616
    1717    return (char *) s;
    1818}
     19
     20char *skip_non_whitespace(const char *s)
     21{
     22    while (*s && !isspace(*s)) ++s;
     23
     24    return (char *) s;
     25}
  • branches/2.2.5/mindi-busybox/libbb/speed_table.c

    r821 r1765  
    5555};
    5656
    57 enum { NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map)) };
     57enum { NUM_SPEEDS = ARRAY_SIZE(speeds) };
    5858
    5959unsigned int tty_baud_to_value(speed_t speed)
     
    9595    speed_t s;
    9696
    97     for (v = 0 ; v < 500000 ; v++) {
     97    for (v = 0 ; v < 500000; v++) {
    9898        s = tty_value_to_baud(v);
    9999        if (s == (speed_t) -1) {
     
    105105    printf("-------------------------------\n");
    106106
    107     for (s = 0 ; s < 010017+1 ; s++) {
     107    for (s = 0 ; s < 010017+1; s++) {
    108108        v = tty_baud_to_value(s);
    109109        if (!v) {
  • branches/2.2.5/mindi-busybox/libbb/trim.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    12 #include <string.h>
    13 #include <ctype.h>
    1411#include "libbb.h"
    15 
    1612
    1713void trim(char *s)
     
    2420
    2521    /* trim leading whitespace */
    26     if(len) {
     22    if (len) {
    2723        lws = strspn(s, " \n\r\t\v");
    2824        memmove(s, s + lws, len -= lws);
    2925    }
    30     s[len] = 0;
     26    s[len] = '\0';
    3127}
  • branches/2.2.5/mindi-busybox/libbb/u_signal_names.c

    r821 r1765  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * Utility routines.
     3 * Signal name/number conversion routines.
    44 *
    5  * Copyright (C) many different people.
    6  * If you wrote this, please acknowledge your work.
     5 * Copyright 2006 Rob Landley <rob@landley.net>
    76 *
    87 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    98 */
    109
    11 #include <signal.h>
    12 #include <ctype.h>
    13 #include <string.h>
    14 #include <strings.h>
    15 #include <stdlib.h>
    16 #include <stdio.h>
    17 
    1810#include "libbb.h"
    1911
    20 struct signal_name {
    21     const char *name;
    22     int number;
     12static const char signals[32][7] = {
     13    // SUSv3 says kill must support these, and specifies the numerical values,
     14    // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
     15    // TODO: "[SIG]EXIT" shouldn't work for kill, right?
     16    // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"},
     17    // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"}
     18    // And Posix adds the following:
     19    // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
     20    // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
     21    // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
     22    // {SIGTTOU, "TTOU"}
     23    [0] = "EXIT",
     24#ifdef SIGHUP
     25    [SIGHUP   ] = "HUP",
     26#endif
     27#ifdef SIGINT
     28    [SIGINT   ] = "INT",
     29#endif
     30#ifdef SIGQUIT
     31    [SIGQUIT  ] = "QUIT",
     32#endif
     33#ifdef SIGILL
     34    [SIGILL   ] = "ILL",
     35#endif
     36#ifdef SIGTRAP
     37    [SIGTRAP  ] = "TRAP",
     38#endif
     39#ifdef SIGABRT
     40    [SIGABRT  ] = "ABRT",
     41#endif
     42#ifdef SIGBUS
     43    [SIGBUS   ] = "BUS",
     44#endif
     45#ifdef SIGFPE
     46    [SIGFPE   ] = "FPE",
     47#endif
     48#ifdef SIGKILL
     49    [SIGKILL  ] = "KILL",
     50#endif
     51#ifdef SIGUSR1
     52    [SIGUSR1  ] = "USR1",
     53#endif
     54#ifdef SIGSEGV
     55    [SIGSEGV  ] = "SEGV",
     56#endif
     57#ifdef SIGUSR2
     58    [SIGUSR2  ] = "USR2",
     59#endif
     60#ifdef SIGPIPE
     61    [SIGPIPE  ] = "PIPE",
     62#endif
     63#ifdef SIGALRM
     64    [SIGALRM  ] = "ALRM",
     65#endif
     66#ifdef SIGTERM
     67    [SIGTERM  ] = "TERM",
     68#endif
     69#ifdef SIGSTKFLT
     70    [SIGSTKFLT] = "STKFLT",
     71#endif
     72#ifdef SIGCHLD
     73    [SIGCHLD  ] = "CHLD",
     74#endif
     75#ifdef SIGCONT
     76    [SIGCONT  ] = "CONT",
     77#endif
     78#ifdef SIGSTOP
     79    [SIGSTOP  ] = "STOP",
     80#endif
     81#ifdef SIGTSTP
     82    [SIGTSTP  ] = "TSTP",
     83#endif
     84#ifdef SIGTTIN
     85    [SIGTTIN  ] = "TTIN",
     86#endif
     87#ifdef SIGTTOU
     88    [SIGTTOU  ] = "TTOU",
     89#endif
     90#ifdef SIGURG
     91    [SIGURG   ] = "URG",
     92#endif
     93#ifdef SIGXCPU
     94    [SIGXCPU  ] = "XCPU",
     95#endif
     96#ifdef SIGXFSZ
     97    [SIGXFSZ  ] = "XFSZ",
     98#endif
     99#ifdef SIGVTALRM
     100    [SIGVTALRM] = "VTALRM",
     101#endif
     102#ifdef SIGPROF
     103    [SIGPROF  ] = "PROF",
     104#endif
     105#ifdef SIGWINCH
     106    [SIGWINCH ] = "WINCH",
     107#endif
     108#ifdef SIGPOLL
     109    [SIGPOLL  ] = "POLL",
     110#endif
     111#ifdef SIGPWR
     112    [SIGPWR   ] = "PWR",
     113#endif
     114#ifdef SIGSYS
     115    [SIGSYS   ] = "SYS",
     116#endif
    23117};
    24118
    25 static const struct signal_name signames[] = {
    26     /* POSIX signals */
    27     { "EXIT",       0 },            /* 0 */
    28     { "HUP",        SIGHUP },       /* 1 */
    29     { "INT",        SIGINT },       /* 2 */
    30     { "QUIT",       SIGQUIT },      /* 3 */
    31     { "ILL",        SIGILL },       /* 4 */
    32     { "ABRT",       SIGABRT },      /* 6 */
    33     { "FPE",        SIGFPE },       /* 8 */
    34     { "KILL",       SIGKILL },      /* 9 */
    35     { "SEGV",       SIGSEGV },      /* 11 */
    36     { "PIPE",       SIGPIPE },      /* 13 */
    37     { "ALRM",       SIGALRM },      /* 14 */
    38     { "TERM",       SIGTERM },      /* 15 */
    39     { "USR1",       SIGUSR1 },      /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
    40     { "USR2",       SIGUSR2 },      /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
    41     { "CHLD",       SIGCHLD },      /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
    42     { "CONT",       SIGCONT },      /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
    43     { "STOP",       SIGSTOP },      /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
    44     { "TSTP",       SIGTSTP },      /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
    45     { "TTIN",       SIGTTIN },      /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
    46     { "TTOU",       SIGTTOU },      /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
    47     /* Miscellaneous other signals */
    48 #ifdef SIGTRAP
    49     { "TRAP",       SIGTRAP },      /* 5 */
     119// Convert signal name to number.
     120
     121int get_signum(const char *name)
     122{
     123    int i;
     124
     125    i = bb_strtou(name, NULL, 10);
     126    if (!errno)
     127        return i;
     128    if (strncasecmp(name, "SIG", 3) == 0)
     129        name += 3;
     130    for (i = 0; i < ARRAY_SIZE(signals); i++)
     131        if (strcasecmp(name, signals[i]) == 0)
     132            return i;
     133
     134#if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO))
     135    /* These are aliased to other names */
     136    if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
     137#ifdef SIGIO
     138        if (!name[2])
     139            return SIGIO;
    50140#endif
    51141#ifdef SIGIOT
    52     { "IOT",        SIGIOT },       /* 6, same as SIGABRT */
     142        if ((name[2] | 0x20) == 't' && !name[3])
     143            return SIGIOT;
    53144#endif
    54 #ifdef SIGEMT
    55     { "EMT",        SIGEMT },       /* 7 (mips,alpha,sparc*) */
     145    }
    56146#endif
    57 #ifdef SIGBUS
    58     { "BUS",        SIGBUS },       /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
    59 #endif
    60 #ifdef SIGSYS
    61     { "SYS",        SIGSYS },       /* 12 (mips,alpha,sparc*) */
    62 #endif
    63 #ifdef SIGSTKFLT
    64     { "STKFLT",     SIGSTKFLT },    /* 16 (arm,i386,m68k,ppc) */
    65 #endif
    66 #ifdef SIGURG
    67     { "URG",        SIGURG },       /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
    68 #endif
    69 #ifdef SIGIO
    70     { "IO",         SIGIO },        /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
    71 #endif
    72 #ifdef SIGPOLL
    73     { "POLL",       SIGPOLL },      /* same as SIGIO */
    74 #endif
    75 #ifdef SIGCLD
    76     { "CLD",        SIGCLD },       /* same as SIGCHLD (mips) */
    77 #endif
    78 #ifdef SIGXCPU
    79     { "XCPU",       SIGXCPU },      /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
    80 #endif
    81 #ifdef SIGXFSZ
    82     { "XFSZ",       SIGXFSZ },      /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
    83 #endif
    84 #ifdef SIGVTALRM
    85     { "VTALRM",     SIGVTALRM },    /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
    86 #endif
    87 #ifdef SIGPROF
    88     { "PROF",       SIGPROF },      /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
    89 #endif
    90 #ifdef SIGPWR
    91     { "PWR",        SIGPWR },       /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
    92 #endif
    93 #ifdef SIGINFO
    94     { "INFO",       SIGINFO },      /* 29 (alpha) */
    95 #endif
    96 #ifdef SIGLOST
    97     { "LOST",       SIGLOST },      /* 29 (arm,i386,m68k,ppc,sparc*) */
    98 #endif
    99 #ifdef SIGWINCH
    100     { "WINCH",      SIGWINCH },     /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
    101 #endif
    102 #ifdef SIGUNUSED
    103     { "UNUSED",     SIGUNUSED },    /* 31 (arm,i386,m68k,ppc) */
    104 #endif
    105     {0, 0}
    106 };
    107147
    108 /*
    109     if str_sig == NULL returned signal name [*signo],
    110     if str_sig != NULL - set *signo from signal_name,
    111         findings with digit number or with or without SIG-prefix name
     148    return -1;
     149}
    112150
    113     if startnum=0 flag for support finding zero signal,
    114         but str_sig="0" always found, (hmm - standart or realize?)
    115     if startnum<0 returned reverse signal_number  <-> signal_name
    116     if found error - returned NULL
     151// Convert signal number to name
    117152
    118 */
     153const char *get_signame(int number)
     154{
     155    if ((unsigned)number < ARRAY_SIZE(signals)) {
     156        if (signals[number][0]) /* if it's not an empty str */
     157            return signals[number];
     158    }
    119159
    120 const char *
    121 u_signal_names(const char *str_sig, int *signo, int startnum)
    122 {
    123     static char retstr[16];
    124     const struct signal_name *s = signames;
    125     static const char prefix[] = "SIG";
    126     const char *sptr;
    127 
    128     if(startnum)
    129         s++;
    130     if(str_sig==NULL) {
    131         while (s->name != 0) {
    132             if(s->number == *signo)
    133                 break;
    134             s++;
    135         }
    136     } else {
    137         if (isdigit(((unsigned char)*str_sig))) {
    138             char *endp;
    139             long int sn = strtol(str_sig, &endp, 10);
    140             /* test correct and overflow */
    141             if(*endp == 0 && sn >= 0 && sn < NSIG) {
    142                 *signo = (int)sn;
    143                 /* test for unnamed */
    144                 sptr = u_signal_names(0, signo, 0);
    145                 if(sptr==NULL)
    146                     return NULL;
    147                 if(sn!=0)
    148                     sptr += 3;
    149                 return sptr;
    150             }
    151         } else {
    152             sptr = str_sig;
    153             while (s->name != 0) {
    154                 if (strcasecmp(s->name, sptr) == 0) {
    155                     *signo = s->number;
    156                     if(startnum<0) {
    157                         sprintf(retstr, "%d", *signo);
    158                         return retstr;
    159                     }
    160                     break;
    161                 }
    162                 if(s!=signames && sptr == str_sig &&
    163                         strncasecmp(sptr, prefix, 3) == 0) {
    164                     sptr += 3;      /* strlen(prefix) */
    165                     continue;
    166                 }
    167                 sptr = str_sig;
    168                 s++;
    169             }
    170         }
    171     }
    172     if(s->name==0)
    173         return NULL;
    174     if(s!=signames)
    175         strcpy(retstr, prefix);
    176      else
    177         retstr[0] = 0;
    178     return strcat(retstr, s->name);
     160    return itoa(number);
    179161}
  • branches/2.2.5/mindi-busybox/libbb/vdprintf.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <unistd.h>
    1210#include "libbb.h"
    1311
    14 
    15 
    16 #if (__GLIBC__ < 2)
     12#if defined(__GLIBC__) && __GLIBC__ < 2
    1713int vdprintf(int d, const char *format, va_list ap)
    1814{
     
    2016    int len;
    2117
    22     len = vsprintf(buf, format, ap);
     18    len = vsnprintf(buf, BUF_SIZE, format, ap);
    2319    return write(d, buf, len);
    2420}
  • branches/2.2.5/mindi-busybox/libbb/verror_msg.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    12 #include <string.h>
    13 #include <stdlib.h>
     10#include <syslog.h>
    1411#include "libbb.h"
    1512
    16 void bb_verror_msg(const char *s, va_list p)
     13smallint logmode = LOGMODE_STDIO;
     14const char *msg_eol = "\n";
     15
     16void bb_verror_msg(const char *s, va_list p, const char* strerr)
    1717{
    18     fflush(stdout);
    19     fprintf(stderr, "%s: ", bb_applet_name);
    20     vfprintf(stderr, s, p);
     18    char *msg;
     19    int applet_len, strerr_len, msgeol_len, used;
     20
     21    if (!logmode)
     22        return;
     23
     24    if (!s) /* nomsg[_and_die] uses NULL fmt */
     25        s = ""; /* some libc don't like printf(NULL) */
     26
     27    used = vasprintf(&msg, s, p);
     28    if (used < 0)
     29        return;
     30
     31    /* This is ugly and costs +60 bytes compared to multiple
     32     * fprintf's, but is guaranteed to do a single write.
     33     * This is needed for e.g. httpd logging, when multiple
     34     * children can produce log messages simultaneously. */
     35
     36    applet_len = strlen(applet_name) + 2; /* "applet: " */
     37    strerr_len = strerr ? strlen(strerr) : 0;
     38    msgeol_len = strlen(msg_eol);
     39    /* +3 is for ": " before strerr and for terminating NUL */
     40    msg = xrealloc(msg, applet_len + used + strerr_len + msgeol_len + 3);
     41    /* TODO: maybe use writev instead of memmoving? Need full_writev? */
     42    memmove(msg + applet_len, msg, used);
     43    used += applet_len;
     44    strcpy(msg, applet_name);
     45    msg[applet_len - 2] = ':';
     46    msg[applet_len - 1] = ' ';
     47    if (strerr) {
     48        msg[used++] = ':';
     49        msg[used++] = ' ';
     50        strcpy(&msg[used], strerr);
     51        used += strerr_len;
     52    }
     53    strcpy(&msg[used], msg_eol);
     54
     55    if (logmode & LOGMODE_STDIO) {
     56        fflush(stdout);
     57        full_write(2, msg, used + msgeol_len);
     58    }
     59    if (logmode & LOGMODE_SYSLOG) {
     60        syslog(LOG_ERR, "%s", msg + applet_len);
     61    }
     62    free(msg);
    2163}
     64
     65
     66#ifdef VERSION_WITH_WRITEV
     67
     68/* Code size is approximately the same, but currently it's the only user
     69 * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */
     70
     71void bb_verror_msg(const char *s, va_list p, const char* strerr)
     72{
     73    int strerr_len, msgeol_len;
     74    struct iovec iov[3];
     75
     76#define used   (iov[2].iov_len)
     77#define msgv   (iov[2].iov_base)
     78#define msgc   ((char*)(iov[2].iov_base))
     79#define msgptr (&(iov[2].iov_base))
     80
     81    if (!logmode)
     82        return;
     83
     84    if (!s) /* nomsg[_and_die] uses NULL fmt */
     85        s = ""; /* some libc don't like printf(NULL) */
     86
     87    /* Prevent "derefing type-punned ptr will break aliasing rules" */
     88    used = vasprintf((char**)(void*)msgptr, s, p);
     89    if (used < 0)
     90        return;
     91
     92    /* This is ugly and costs +60 bytes compared to multiple
     93     * fprintf's, but is guaranteed to do a single write.
     94     * This is needed for e.g. httpd logging, when multiple
     95     * children can produce log messages simultaneously. */
     96
     97    strerr_len = strerr ? strlen(strerr) : 0;
     98    msgeol_len = strlen(msg_eol);
     99    /* +3 is for ": " before strerr and for terminating NUL */
     100    msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3);
     101    if (strerr) {
     102        msgc[used++] = ':';
     103        msgc[used++] = ' ';
     104        strcpy(msgc + used, strerr);
     105        used += strerr_len;
     106    }
     107    strcpy(msgc + used, msg_eol);
     108    used += msgeol_len;
     109
     110    if (logmode & LOGMODE_STDIO) {
     111        iov[0].iov_base = (char*)applet_name;
     112        iov[0].iov_len = strlen(applet_name);
     113        iov[1].iov_base = (char*)": ";
     114        iov[1].iov_len = 2;
     115        /*iov[2].iov_base = msgc;*/
     116        /*iov[2].iov_len = used;*/
     117        fflush(stdout);
     118        writev(2, iov, 3);
     119    }
     120    if (logmode & LOGMODE_SYSLOG) {
     121        syslog(LOG_ERR, "%s", msgc);
     122    }
     123    free(msgc);
     124}
     125#endif
  • branches/2.2.5/mindi-busybox/libbb/vfork_daemon_rexec.c

    r821 r1765  
    1616 */
    1717
    18 #include <unistd.h>
    19 #include <stdio.h>
    20 #include <fcntl.h>
    2118#include <paths.h>
    22 #include "libbb.h"
    23 
    24 
    25 #ifdef BB_NOMMU
    26 void vfork_daemon_rexec(int nochdir, int noclose,
    27         int argc, char **argv, char *foreground_opt)
     19#include "busybox.h" /* for struct bb_applet */
     20
     21/* This does a fork/exec in one call, using vfork().  Returns PID of new child,
     22 * -1 for failure.  Runs argv[0], searching path if that has no / in it. */
     23pid_t spawn(char **argv)
     24{
     25    /* Compiler should not optimize stores here */
     26    volatile int failed;
     27    pid_t pid;
     28
     29// Ain't it a good place to fflush(NULL)?
     30
     31    /* Be nice to nommu machines. */
     32    failed = 0;
     33    pid = vfork();
     34    if (pid < 0) /* error */
     35        return pid;
     36    if (!pid) { /* child */
     37        /* This macro is ok - it doesn't do NOEXEC/NOFORK tricks */
     38        BB_EXECVP(argv[0], argv);
     39
     40        /* We are (maybe) sharing a stack with blocked parent,
     41         * let parent know we failed and then exit to unblock parent
     42         * (but don't run atexit() stuff, which would screw up parent.)
     43         */
     44        failed = errno;
     45        _exit(111);
     46    }
     47    /* parent */
     48    /* Unfortunately, this is not reliable: according to standards
     49     * vfork() can be equivalent to fork() and we won't see value
     50     * of 'failed'.
     51     * Interested party can wait on pid and learn exit code.
     52     * If 111 - then it (most probably) failed to exec */
     53    if (failed) {
     54        errno = failed;
     55        return -1;
     56    }
     57    return pid;
     58}
     59
     60/* Die with an error message if we can't spawn a child process. */
     61pid_t xspawn(char **argv)
     62{
     63    pid_t pid = spawn(argv);
     64    if (pid < 0)
     65        bb_perror_msg_and_die("%s", *argv);
     66    return pid;
     67}
     68
     69// Wait for the specified child PID to exit, returning child's error return.
     70int wait4pid(int pid)
     71{
     72    int status;
     73
     74    if (pid <= 0) {
     75        /*errno = ECHILD; -- wrong. */
     76        /* we expect errno to be already set from failed [v]fork/exec */
     77        return -1;
     78    }
     79    if (waitpid(pid, &status, 0) == -1)
     80        return -1;
     81    if (WIFEXITED(status))
     82        return WEXITSTATUS(status);
     83    if (WIFSIGNALED(status))
     84        return WTERMSIG(status) + 1000;
     85    return 0;
     86}
     87
     88int wait_nohang(int *wstat)
     89{
     90    return waitpid(-1, wstat, WNOHANG);
     91}
     92
     93int wait_pid(int *wstat, int pid)
     94{
     95    int r;
     96
     97    do
     98        r = waitpid(pid, wstat, 0);
     99    while ((r == -1) && (errno == EINTR));
     100    return r;
     101}
     102
     103#if ENABLE_FEATURE_PREFER_APPLETS
     104void save_nofork_data(struct nofork_save_area *save)
     105{
     106    memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
     107    save->current_applet = current_applet;
     108    save->xfunc_error_retval = xfunc_error_retval;
     109    save->option_mask32 = option_mask32;
     110    save->die_sleep = die_sleep;
     111    save->saved = 1;
     112}
     113
     114void restore_nofork_data(struct nofork_save_area *save)
     115{
     116    memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
     117    current_applet = save->current_applet;
     118    xfunc_error_retval = save->xfunc_error_retval;
     119    option_mask32 = save->option_mask32;
     120    die_sleep = save->die_sleep;
     121
     122    applet_name = current_applet->name;
     123}
     124
     125int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv)
     126{
     127    int rc, argc;
     128
     129    current_applet = a;
     130    applet_name = a->name;
     131    xfunc_error_retval = EXIT_FAILURE;
     132    /*option_mask32 = 0; - not needed */
     133    /* special flag for xfunc_die(). If xfunc will "die"
     134     * in NOFORK applet, xfunc_die() sees negative
     135     * die_sleep and longjmp here instead. */
     136    die_sleep = -1;
     137
     138    argc = 1;
     139    while (argv[argc])
     140        argc++;
     141
     142    rc = setjmp(die_jmp);
     143    if (!rc) {
     144        /* Some callers (xargs)
     145         * need argv untouched because they free argv[i]! */
     146        char *tmp_argv[argc+1];
     147        memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
     148        /* Finally we can call NOFORK applet's main() */
     149        rc = a->main(argc, tmp_argv);
     150    } else { /* xfunc died in NOFORK applet */
     151        /* in case they meant to return 0... */
     152        if (rc == -2222)
     153            rc = 0;
     154    }
     155
     156    /* Restoring globals */
     157    restore_nofork_data(old);
     158    return rc;
     159}
     160
     161int run_nofork_applet(const struct bb_applet *a, char **argv)
     162{
     163    struct nofork_save_area old;
     164
     165    /* Saving globals */
     166    save_nofork_data(&old);
     167    return run_nofork_applet_prime(&old, a, argv);
     168}
     169#endif /* FEATURE_PREFER_APPLETS */
     170
     171int spawn_and_wait(char **argv)
     172{
     173    int rc;
     174#if ENABLE_FEATURE_PREFER_APPLETS
     175    const struct bb_applet *a = find_applet_by_name(argv[0]);
     176
     177    if (a && (a->nofork
     178#if BB_MMU
     179         || a->noexec /* NOEXEC trick needs fork() */
     180#endif
     181    )) {
     182#if BB_MMU
     183        if (a->nofork)
     184#endif
     185        {
     186            return run_nofork_applet(a, argv);
     187        }
     188#if BB_MMU
     189        /* MMU only */
     190        /* a->noexec is true */
     191        rc = fork();
     192        if (rc) /* parent or error */
     193            return wait4pid(rc);
     194        /* child */
     195        xfunc_error_retval = EXIT_FAILURE;
     196        current_applet = a;
     197        run_current_applet_and_exit(argv);
     198#endif
     199    }
     200#endif /* FEATURE_PREFER_APPLETS */
     201    rc = spawn(argv);
     202    return wait4pid(rc);
     203}
     204
     205#if !BB_MMU
     206void re_exec(char **argv)
     207{
     208    /* high-order bit of first char in argv[0] is a hidden
     209     * "we have (already) re-execed, don't do it again" flag */
     210    argv[0][0] |= 0x80;
     211    execv(bb_busybox_exec_path, argv);
     212    bb_perror_msg_and_die("exec %s", bb_busybox_exec_path);
     213}
     214
     215void forkexit_or_rexec(char **argv)
     216{
     217    pid_t pid;
     218    /* Maybe we are already re-execed and come here again? */
     219    if (re_execed)
     220        return;
     221
     222    pid = vfork();
     223    if (pid < 0) /* wtf? */
     224        bb_perror_msg_and_die("vfork");
     225    if (pid) /* parent */
     226        exit(0);
     227    /* child - re-exec ourself */
     228    re_exec(argv);
     229}
     230#else
     231/* Dance around (void)...*/
     232#undef forkexit_or_rexec
     233void forkexit_or_rexec(void)
     234{
     235    pid_t pid;
     236    pid = fork();
     237    if (pid < 0) /* wtf? */
     238        bb_perror_msg_and_die("fork");
     239    if (pid) /* parent */
     240        exit(0);
     241    /* child */
     242}
     243#define forkexit_or_rexec(argv) forkexit_or_rexec()
     244#endif
     245
     246/* Due to a #define in libbb.h on MMU systems we actually have 1 argument -
     247 * char **argv "vanishes" */
     248void bb_daemonize_or_rexec(int flags, char **argv)
    28249{
    29250    int fd;
    30     char **vfork_args;
    31     int a = 0;
    32 
    33     setsid();
    34 
    35     if (!nochdir)
    36         chdir("/");
    37 
    38     if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) {
    39         dup2(fd, STDIN_FILENO);
    40         dup2(fd, STDOUT_FILENO);
    41         dup2(fd, STDERR_FILENO);
    42         if (fd > 2)
    43             close(fd);
    44     }
    45 
    46     vfork_args = xcalloc(sizeof(char *), argc + 3);
    47     vfork_args[a++] = "/bin/busybox";
    48     while(*argv) {
    49         vfork_args[a++] = *argv;
    50         argv++;
    51     }
    52     vfork_args[a] = foreground_opt;
    53     switch (vfork()) {
    54     case 0: /* child */
    55         /* Make certain we are not a session leader, or else we
    56          * might reacquire a controlling terminal */
    57         if (vfork())
    58             _exit(0);
    59         execv(vfork_args[0], vfork_args);
    60         bb_perror_msg_and_die("execv %s", vfork_args[0]);
    61     case -1: /* error */
    62         bb_perror_msg_and_die("vfork");
    63     default: /* parent */
    64         exit(0);
    65     }
    66 }
    67 #endif /* BB_NOMMU */
     251
     252    if (flags & DAEMON_CHDIR_ROOT)
     253        xchdir("/");
     254
     255    if (flags & DAEMON_DEVNULL_STDIO) {
     256        close(0);
     257        close(1);
     258        close(2);
     259    }
     260
     261    fd = xopen(bb_dev_null, O_RDWR);
     262
     263    while ((unsigned)fd < 2)
     264        fd = dup(fd); /* have 0,1,2 open at least to /dev/null */
     265
     266    if (!(flags & DAEMON_ONLY_SANITIZE)) {
     267        forkexit_or_rexec(argv);
     268        /* if daemonizing, make sure we detach from stdio & ctty */
     269        setsid();
     270        dup2(fd, 0);
     271        dup2(fd, 1);
     272        dup2(fd, 2);
     273    }
     274    while (fd > 2) {
     275        close(fd--);
     276        if (!(flags & DAEMON_CLOSE_EXTRA_FDS))
     277            return;
     278        /* else close everything after fd#2 */
     279    }
     280}
     281
     282void bb_sanitize_stdio(void)
     283{
     284    bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE, NULL);
     285}
  • branches/2.2.5/mindi-busybox/libbb/warn_ignoring_args.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    23 #include <libbb.h>
     10#include "libbb.h"
    2411
    2512void bb_warn_ignoring_args(int n)
    2613{
    2714    if (n) {
    28         bb_perror_msg("ignoring all arguments");
     15        bb_error_msg("ignoring all arguments");
    2916    }
    3017}
  • branches/2.2.5/mindi-busybox/libbb/wfopen.c

    r821 r1765  
    88 */
    99
    10 #include <stdio.h>
    11 #include <errno.h>
    1210#include "libbb.h"
    1311
    14 FILE *bb_wfopen(const char *path, const char *mode)
     12FILE *fopen_or_warn(const char *path, const char *mode)
    1513{
    16     FILE *fp;
    17     if ((fp = fopen(path, mode)) == NULL) {
     14    FILE *fp = fopen(path, mode);
     15    if (!fp) {
    1816        bb_perror_msg("%s", path);
    1917        errno = 0;
  • branches/2.2.5/mindi-busybox/libbb/wfopen_input.c

    r821 r1765  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
     
    2512 * we avoid testing everywhere by consolidating things in this routine.
    2613 *
    27  * Note: We also consider "" to main stdin (for 'cmp' at least).
     14 * Note: we also consider "" to mean stdin (for 'cmp' at least).
    2815 */
    2916
    30 #include <stdio.h>
    31 #include <sys/stat.h>
    32 #include <libbb.h>
     17#include "libbb.h"
    3318
    34 FILE *bb_wfopen_input(const char *filename)
     19FILE *fopen_or_warn_stdin(const char *filename)
    3520{
    3621    FILE *fp = stdin;
    3722
    38     if ((filename != bb_msg_standard_input)
    39         && filename[0] && ((filename[0] != '-') || filename[1])
     23    if (filename != bb_msg_standard_input
     24     && filename[0]
     25     && NOT_LONE_DASH(filename)
    4026    ) {
    41         fp = bb_wfopen(filename, "r");
     27        fp = fopen_or_warn(filename, "r");
    4228    }
    4329
  • branches/2.2.5/mindi-busybox/libbb/xconnect.c

    r821 r1765  
    77 */
    88
    9 #include <unistd.h>
    10 #include <string.h>
    11 #include <stdlib.h>
    12 #include <sys/types.h>
    13 #include <sys/socket.h>
    14 #include <errno.h>
    15 #include <netdb.h>
    16 #include <sys/socket.h>
    179#include <netinet/in.h>
    18 #include <arpa/inet.h>
    1910#include "libbb.h"
    2011
    21 /* Return network byte ordered port number for a service.
     12void setsockopt_reuseaddr(int fd)
     13{
     14    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1));
     15}
     16int setsockopt_broadcast(int fd)
     17{
     18    return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1));
     19}
     20
     21void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
     22{
     23    if (connect(s, s_addr, addrlen) < 0) {
     24        if (ENABLE_FEATURE_CLEAN_UP)
     25            close(s);
     26        if (s_addr->sa_family == AF_INET)
     27            bb_perror_msg_and_die("%s (%s)",
     28                "cannot connect to remote host",
     29                inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr));
     30        bb_perror_msg_and_die("cannot connect to remote host");
     31    }
     32}
     33
     34/* Return port number for a service.
    2235 * If "port" is a number use it as the port.
    2336 * If "port" is a name it is looked up in /etc/services, if it isnt found return
    24  * default_port
    25  */
    26 unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port)
    27 {
    28     unsigned short port_nr = htons(default_port);
     37 * default_port */
     38unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port)
     39{
     40    unsigned port_nr = default_port;
    2941    if (port) {
    30         char *endptr;
    3142        int old_errno;
    32         long port_long;
    3343
    3444        /* Since this is a lib function, we're not allowed to reset errno to 0.
    3545         * Doing so could break an app that is deferring checking of errno. */
    3646        old_errno = errno;
    37         errno = 0;
    38         port_long = strtol(port, &endptr, 10);
    39         if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) {
     47        port_nr = bb_strtou(port, NULL, 10);
     48        if (errno || port_nr > 65535) {
    4049            struct servent *tserv = getservbyname(port, protocol);
    41             if (tserv) {
    42                 port_nr = tserv->s_port;
    43             }
    44         } else {
    45             port_nr = htons(port_long);
     50            port_nr = default_port;
     51            if (tserv)
     52                port_nr = ntohs(tserv->s_port);
    4653        }
    4754        errno = old_errno;
    4855    }
    49     return port_nr;
    50 }
    51 
     56    return (uint16_t)port_nr;
     57}
     58
     59
     60/* "Old" networking API - only IPv4 */
     61
     62/*
    5263void bb_lookup_host(struct sockaddr_in *s_in, const char *host)
    5364{
     
    6071}
    6172
    62 int xconnect(struct sockaddr_in *s_addr)
    63 {
    64     int s = bb_xsocket(AF_INET, SOCK_STREAM, 0);
    65     if (connect(s, (struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0)
    66     {
    67         if (ENABLE_FEATURE_CLEAN_UP) close(s);
    68         bb_perror_msg_and_die("Unable to connect to remote host (%s)",
    69                 inet_ntoa(s_addr->sin_addr));
    70     }
     73
     74int xconnect_tcp_v4(struct sockaddr_in *s_addr)
     75{
     76    int s = xsocket(AF_INET, SOCK_STREAM, 0);
     77    xconnect(s, (struct sockaddr*) s_addr, sizeof(*s_addr));
    7178    return s;
    7279}
     80*/
     81
     82/* "New" networking API */
     83
     84
     85int get_nport(const struct sockaddr *sa)
     86{
     87#if ENABLE_FEATURE_IPV6
     88    if (sa->sa_family == AF_INET6) {
     89        return ((struct sockaddr_in6*)sa)->sin6_port;
     90    }
     91#endif
     92    if (sa->sa_family == AF_INET) {
     93        return ((struct sockaddr_in*)sa)->sin_port;
     94    }
     95    /* What? UNIX socket? IPX?? :) */
     96    return -1;
     97}
     98
     99void set_nport(len_and_sockaddr *lsa, unsigned port)
     100{
     101#if ENABLE_FEATURE_IPV6
     102    if (lsa->sa.sa_family == AF_INET6) {
     103        lsa->sin6.sin6_port = port;
     104        return;
     105    }
     106#endif
     107    if (lsa->sa.sa_family == AF_INET) {
     108        lsa->sin.sin_port = port;
     109        return;
     110    }
     111    /* What? UNIX socket? IPX?? :) */
     112}
     113
     114/* We hijack this constant to mean something else */
     115/* It doesn't hurt because we will remove this bit anyway */
     116#define DIE_ON_ERROR AI_CANONNAME
     117
     118/* host: "1.2.3.4[:port]", "www.google.com[:port]"
     119 * port: if neither of above specifies port # */
     120static len_and_sockaddr* str2sockaddr(
     121        const char *host, int port,
     122USE_FEATURE_IPV6(sa_family_t af,)
     123        int ai_flags)
     124{
     125    int rc;
     126    len_and_sockaddr *r = NULL;
     127    struct addrinfo *result = NULL;
     128    const char *org_host = host; /* only for error msg */
     129    const char *cp;
     130    struct addrinfo hint;
     131
     132    /* Ugly parsing of host:addr */
     133    if (ENABLE_FEATURE_IPV6 && host[0] == '[') {
     134        host++;
     135        cp = strchr(host, ']');
     136        if (!cp || cp[1] != ':') /* Malformed: must have [xx]:nn */
     137            bb_error_msg_and_die("bad address '%s'", org_host);
     138            //return r; /* return NULL */
     139    } else {
     140        cp = strrchr(host, ':');
     141        if (ENABLE_FEATURE_IPV6 && cp && strchr(host, ':') != cp) {
     142            /* There is more than one ':' (e.g. "::1") */
     143            cp = NULL; /* it's not a port spec */
     144        }
     145    }
     146    if (cp) {
     147        int sz = cp - host + 1;
     148        host = safe_strncpy(alloca(sz), host, sz);
     149        if (ENABLE_FEATURE_IPV6 && *cp != ':')
     150            cp++; /* skip ']' */
     151        cp++; /* skip ':' */
     152        port = xatou16(cp);
     153    }
     154
     155    memset(&hint, 0 , sizeof(hint));
     156#if !ENABLE_FEATURE_IPV6
     157    hint.ai_family = AF_INET; /* do not try to find IPv6 */
     158#else
     159    hint.ai_family = af;
     160#endif
     161    /* Needed. Or else we will get each address thrice (or more)
     162     * for each possible socket type (tcp,udp,raw...): */
     163    hint.ai_socktype = SOCK_STREAM;
     164    hint.ai_flags = ai_flags & ~DIE_ON_ERROR;
     165    rc = getaddrinfo(host, NULL, &hint, &result);
     166    if (rc || !result) {
     167        bb_error_msg("bad address '%s'", org_host);
     168        if (ai_flags & DIE_ON_ERROR)
     169            xfunc_die();
     170        goto ret;
     171    }
     172    r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen);
     173    r->len = result->ai_addrlen;
     174    memcpy(&r->sa, result->ai_addr, result->ai_addrlen);
     175    set_nport(r, htons(port));
     176 ret:
     177    freeaddrinfo(result);
     178    return r;
     179}
     180#if !ENABLE_FEATURE_IPV6
     181#define str2sockaddr(host, port, af, ai_flags) str2sockaddr(host, port, ai_flags)
     182#endif
     183
     184#if ENABLE_FEATURE_IPV6
     185len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af)
     186{
     187    return str2sockaddr(host, port, af, 0);
     188}
     189
     190len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af)
     191{
     192    return str2sockaddr(host, port, af, DIE_ON_ERROR);
     193}
     194#endif
     195
     196len_and_sockaddr* host2sockaddr(const char *host, int port)
     197{
     198    return str2sockaddr(host, port, AF_UNSPEC, 0);
     199}
     200
     201len_and_sockaddr* xhost2sockaddr(const char *host, int port)
     202{
     203    return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR);
     204}
     205
     206len_and_sockaddr* xdotted2sockaddr(const char *host, int port)
     207{
     208    return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR);
     209}
     210
     211int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type)
     212{
     213    SKIP_FEATURE_IPV6(enum { family = AF_INET };)
     214    len_and_sockaddr *lsa;
     215    int fd;
     216    int len;
     217
     218#if ENABLE_FEATURE_IPV6
     219    if (family == AF_UNSPEC) {
     220        fd = socket(AF_INET6, sock_type, 0);
     221        if (fd >= 0) {
     222            family = AF_INET6;
     223            goto done;
     224        }
     225        family = AF_INET;
     226    }
     227#endif
     228    fd = xsocket(family, sock_type, 0);
     229    len = sizeof(struct sockaddr_in);
     230#if ENABLE_FEATURE_IPV6
     231    if (family == AF_INET6) {
     232 done:
     233        len = sizeof(struct sockaddr_in6);
     234    }
     235#endif
     236    lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len);
     237    lsa->len = len;
     238    lsa->sa.sa_family = family;
     239    *lsap = lsa;
     240    return fd;
     241}
     242
     243int xsocket_stream(len_and_sockaddr **lsap)
     244{
     245    return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM);
     246}
     247
     248static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type)
     249{
     250    int fd;
     251    len_and_sockaddr *lsa;
     252
     253    if (bindaddr && bindaddr[0]) {
     254        lsa = xdotted2sockaddr(bindaddr, port);
     255        /* user specified bind addr dictates family */
     256        fd = xsocket(lsa->sa.sa_family, sock_type, 0);
     257    } else {
     258        fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type);
     259        set_nport(lsa, htons(port));
     260    }
     261    setsockopt_reuseaddr(fd);
     262    xbind(fd, &lsa->sa, lsa->len);
     263    free(lsa);
     264    return fd;
     265}
     266
     267int create_and_bind_stream_or_die(const char *bindaddr, int port)
     268{
     269    return create_and_bind_or_die(bindaddr, port, SOCK_STREAM);
     270}
     271
     272int create_and_bind_dgram_or_die(const char *bindaddr, int port)
     273{
     274    return create_and_bind_or_die(bindaddr, port, SOCK_DGRAM);
     275}
     276
     277
     278int create_and_connect_stream_or_die(const char *peer, int port)
     279{
     280    int fd;
     281    len_and_sockaddr *lsa;
     282
     283    lsa = xhost2sockaddr(peer, port);
     284    fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0);
     285    setsockopt_reuseaddr(fd);
     286    xconnect(fd, &lsa->sa, lsa->len);
     287    free(lsa);
     288    return fd;
     289}
     290
     291int xconnect_stream(const len_and_sockaddr *lsa)
     292{
     293    int fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0);
     294    xconnect(fd, &lsa->sa, lsa->len);
     295    return fd;
     296}
     297
     298/* We hijack this constant to mean something else */
     299/* It doesn't hurt because we will add this bit anyway */
     300#define IGNORE_PORT NI_NUMERICSERV
     301static char* sockaddr2str(const struct sockaddr *sa, int flags)
     302{
     303    char host[128];
     304    char serv[16];
     305    int rc;
     306    socklen_t salen;
     307
     308    salen = LSA_SIZEOF_SA;
     309#if ENABLE_FEATURE_IPV6
     310    if (sa->sa_family == AF_INET)
     311        salen = sizeof(struct sockaddr_in);
     312    if (sa->sa_family == AF_INET6)
     313        salen = sizeof(struct sockaddr_in6);
     314#endif
     315    rc = getnameinfo(sa, salen,
     316            host, sizeof(host),
     317    /* can do ((flags & IGNORE_PORT) ? NULL : serv) but why bother? */
     318            serv, sizeof(serv),
     319            /* do not resolve port# into service _name_ */
     320            flags | NI_NUMERICSERV
     321    );
     322    if (rc)
     323        return NULL;
     324    if (flags & IGNORE_PORT)
     325        return xstrdup(host);
     326#if ENABLE_FEATURE_IPV6
     327    if (sa->sa_family == AF_INET6) {
     328        if (strchr(host, ':')) /* heh, it's not a resolved hostname */
     329            return xasprintf("[%s]:%s", host, serv);
     330        /*return xasprintf("%s:%s", host, serv);*/
     331        /* - fall through instead */
     332    }
     333#endif
     334    /* For now we don't support anything else, so it has to be INET */
     335    /*if (sa->sa_family == AF_INET)*/
     336        return xasprintf("%s:%s", host, serv);
     337    /*return xstrdup(host);*/
     338}
     339
     340char* xmalloc_sockaddr2host(const struct sockaddr *sa)
     341{
     342    return sockaddr2str(sa, 0);
     343}
     344
     345char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa)
     346{
     347    return sockaddr2str(sa, IGNORE_PORT);
     348}
     349
     350char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa)
     351{
     352    return sockaddr2str(sa, NI_NAMEREQD | IGNORE_PORT);
     353}
     354char* xmalloc_sockaddr2dotted(const struct sockaddr *sa)
     355{
     356    return sockaddr2str(sa, NI_NUMERICHOST);
     357}
     358
     359char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa)
     360{
     361    return sockaddr2str(sa, NI_NUMERICHOST | IGNORE_PORT);
     362}
  • branches/2.2.5/mindi-busybox/libbb/xfuncs.c

    r821 r1765  
    44 *
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
     6 * Copyright (C) 2006 Rob Landley
     7 * Copyright (C) 2006 Denis Vlasenko
    68 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
    810 */
    911
    10 #include <sys/types.h>
    11 #include <sys/stat.h>
    12 #include <sys/wait.h>
    13 #include <stdio.h>
    14 #include <string.h>
    15 #include <stdlib.h>
    16 #include <unistd.h>
    17 #include <fcntl.h>
    18 #include "busybox.h"
     12#include "libbb.h"
     13
     14/* All the functions starting with "x" call bb_error_msg_and_die() if they
     15 * fail, so callers never need to check for errors.  If it returned, it
     16 * succeeded. */
    1917
    2018#ifndef DMALLOC
    21 #ifdef L_xmalloc
     19/* dmalloc provides variants of these that do abort() on failure.
     20 * Since dmalloc's prototypes overwrite the impls here as they are
     21 * included after these prototypes in libbb.h, all is well.
     22 */
     23// Warn if we can't allocate size bytes of memory.
     24void *malloc_or_warn(size_t size)
     25{
     26    void *ptr = malloc(size);
     27    if (ptr == NULL && size != 0)
     28        bb_error_msg(bb_msg_memory_exhausted);
     29    return ptr;
     30}
     31
     32// Die if we can't allocate size bytes of memory.
    2233void *xmalloc(size_t size)
    2334{
     
    2738    return ptr;
    2839}
    29 #endif
    30 
    31 #ifdef L_xrealloc
     40
     41// Die if we can't resize previously allocated memory.  (This returns a pointer
     42// to the new memory, which may or may not be the same as the old memory.
     43// It'll copy the contents to a new chunk and free the old one if necessary.)
    3244void *xrealloc(void *ptr, size_t size)
    3345{
     
    3749    return ptr;
    3850}
    39 #endif
    40 
    41 #ifdef L_xzalloc
     51#endif /* DMALLOC */
     52
     53// Die if we can't allocate and zero size bytes of memory.
    4254void *xzalloc(size_t size)
    4355{
     
    4658    return ptr;
    4759}
    48 #endif
    49 
    50 #ifdef L_xcalloc
    51 void *xcalloc(size_t nmemb, size_t size)
    52 {
    53     void *ptr = calloc(nmemb, size);
    54     if (ptr == NULL && nmemb != 0 && size != 0)
    55         bb_error_msg_and_die(bb_msg_memory_exhausted);
    56     return ptr;
    57 }
    58 #endif
    59 #endif /* DMALLOC */
    60 
    61 #ifdef L_xstrdup
    62 char * bb_xstrdup (const char *s)
     60
     61// Die if we can't copy a string to freshly allocated memory.
     62char * xstrdup(const char *s)
    6363{
    6464    char *t;
     
    6767        return NULL;
    6868
    69     t = strdup (s);
     69    t = strdup(s);
    7070
    7171    if (t == NULL)
     
    7474    return t;
    7575}
    76 #endif
    77 
    78 #ifdef L_xstrndup
    79 char * bb_xstrndup (const char *s, int n)
    80 {
     76
     77// Die if we can't allocate n+1 bytes (space for the null terminator) and copy
     78// the (possibly truncated to length n) string into it.
     79char * xstrndup(const char *s, int n)
     80{
     81    int m;
    8182    char *t;
    8283
    8384    if (ENABLE_DEBUG && s == NULL)
    84         bb_error_msg_and_die("bb_xstrndup bug");
    85 
    86     t = xmalloc(++n);
    87 
    88     return safe_strncpy(t,s,n);
    89 }
    90 #endif
    91 
    92 #ifdef L_xfopen
    93 FILE *bb_xfopen(const char *path, const char *mode)
    94 {
    95     FILE *fp;
    96     if ((fp = fopen(path, mode)) == NULL)
    97         bb_perror_msg_and_die("%s", path);
     85        bb_error_msg_and_die("xstrndup bug");
     86
     87    /* We can just xmalloc(n+1) and strncpy into it, */
     88    /* but think about xstrndup("abc", 10000) wastage! */
     89    m = n;
     90    t = (char*) s;
     91    while (m) {
     92        if (!*t) break;
     93        m--;
     94        t++;
     95    }
     96    n -= m;
     97    t = xmalloc(n + 1);
     98    t[n] = '\0';
     99
     100    return memcpy(t, s, n);
     101}
     102
     103// Die if we can't open a file and return a FILE * to it.
     104// Notice we haven't got xfread(), This is for use with fscanf() and friends.
     105FILE *xfopen(const char *path, const char *mode)
     106{
     107    FILE *fp = fopen(path, mode);
     108    if (fp == NULL)
     109        bb_perror_msg_and_die("can't open '%s'", path);
    98110    return fp;
    99111}
    100 #endif
    101 
    102 #ifdef L_xopen
    103 int bb_xopen(const char *pathname, int flags)
    104 {
    105     return bb_xopen3(pathname, flags, 0777);
    106 }
    107 #endif
    108 
    109 #ifdef L_xopen3
    110 int bb_xopen3(const char *pathname, int flags, int mode)
     112
     113// Die if we can't open a file and return a fd.
     114int xopen3(const char *pathname, int flags, int mode)
    111115{
    112116    int ret;
     
    114118    ret = open(pathname, flags, mode);
    115119    if (ret < 0) {
    116         bb_perror_msg_and_die("%s", pathname);
     120        bb_perror_msg_and_die("can't open '%s'", pathname);
    117121    }
    118122    return ret;
    119123}
    120 #endif
    121 
    122 #ifdef L_xread
    123 ssize_t bb_xread(int fd, void *buf, size_t count)
    124 {
    125     ssize_t size;
    126 
    127     size = read(fd, buf, count);
    128     if (size < 0) {
    129         bb_perror_msg_and_die(bb_msg_read_error);
    130     }
    131     return(size);
    132 }
    133 #endif
    134 
    135 #ifdef L_xread_all
    136 void bb_xread_all(int fd, void *buf, size_t count)
    137 {
    138     ssize_t size;
    139 
    140     while (count) {
    141         if ((size = bb_xread(fd, buf, count)) == 0) {   /* EOF */
    142             bb_error_msg_and_die("Short read");
    143         }
    144         count -= size;
    145         buf = ((char *) buf) + size;
    146     }
    147     return;
    148 }
    149 #endif
    150 
    151 #ifdef L_xread_char
    152 unsigned char bb_xread_char(int fd)
    153 {
    154     char tmp;
    155 
    156     bb_xread_all(fd, &tmp, 1);
    157 
    158     return(tmp);
    159 }
    160 #endif
    161 
    162 #ifdef L_xferror
    163 void bb_xferror(FILE *fp, const char *fn)
     124
     125// Die if we can't open an existing file and return a fd.
     126int xopen(const char *pathname, int flags)
     127{
     128    return xopen3(pathname, flags, 0666);
     129}
     130
     131// Warn if we can't open a file and return a fd.
     132int open3_or_warn(const char *pathname, int flags, int mode)
     133{
     134    int ret;
     135
     136    ret = open(pathname, flags, mode);
     137    if (ret < 0) {
     138        bb_perror_msg("can't open '%s'", pathname);
     139    }
     140    return ret;
     141}
     142
     143// Warn if we can't open a file and return a fd.
     144int open_or_warn(const char *pathname, int flags)
     145{
     146    return open3_or_warn(pathname, flags, 0666);
     147}
     148
     149void xpipe(int filedes[2])
     150{
     151    if (pipe(filedes))
     152        bb_perror_msg_and_die("can't create pipe");
     153}
     154
     155void xunlink(const char *pathname)
     156{
     157    if (unlink(pathname))
     158        bb_perror_msg_and_die("can't remove file '%s'", pathname);
     159}
     160
     161// Turn on nonblocking I/O on a fd
     162int ndelay_on(int fd)
     163{
     164    return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
     165}
     166
     167int ndelay_off(int fd)
     168{
     169    return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK);
     170}
     171
     172void xdup2(int from, int to)
     173{
     174    if (dup2(from, to) != to)
     175        bb_perror_msg_and_die("can't duplicate file descriptor");
     176}
     177
     178// "Renumber" opened fd
     179void xmove_fd(int from, int to)
     180{
     181    if (from == to)
     182        return;
     183    xdup2(from, to);
     184    close(from);
     185}
     186
     187// Die with an error message if we can't write the entire buffer.
     188void xwrite(int fd, const void *buf, size_t count)
     189{
     190    if (count) {
     191        ssize_t size = full_write(fd, buf, count);
     192        if (size != count)
     193            bb_error_msg_and_die("short write");
     194    }
     195}
     196
     197// Die with an error message if we can't lseek to the right spot.
     198off_t xlseek(int fd, off_t offset, int whence)
     199{
     200    off_t off = lseek(fd, offset, whence);
     201    if (off == (off_t)-1) {
     202        if (whence == SEEK_SET)
     203            bb_perror_msg_and_die("lseek(%"OFF_FMT"u)", offset);
     204        bb_perror_msg_and_die("lseek");
     205    }
     206    return off;
     207}
     208
     209// Die with supplied filename if this FILE * has ferror set.
     210void die_if_ferror(FILE *fp, const char *fn)
    164211{
    165212    if (ferror(fp)) {
    166         bb_error_msg_and_die("%s", fn);
    167     }
    168 }
    169 #endif
    170 
    171 #ifdef L_xferror_stdout
    172 void bb_xferror_stdout(void)
    173 {
    174     bb_xferror(stdout, bb_msg_standard_output);
    175 }
    176 #endif
    177 
    178 #ifdef L_xfflush_stdout
    179 void bb_xfflush_stdout(void)
     213        /* ferror doesn't set useful errno */
     214        bb_error_msg_and_die("%s: I/O error", fn);
     215    }
     216}
     217
     218// Die with an error message if stdout has ferror set.
     219void die_if_ferror_stdout(void)
     220{
     221    die_if_ferror(stdout, bb_msg_standard_output);
     222}
     223
     224// Die with an error message if we have trouble flushing stdout.
     225void xfflush_stdout(void)
    180226{
    181227    if (fflush(stdout)) {
     
    183229    }
    184230}
     231
     232void sig_block(int sig)
     233{
     234    sigset_t ss;
     235    sigemptyset(&ss);
     236    sigaddset(&ss, sig);
     237    sigprocmask(SIG_BLOCK, &ss, NULL);
     238}
     239
     240void sig_unblock(int sig)
     241{
     242    sigset_t ss;
     243    sigemptyset(&ss);
     244    sigaddset(&ss, sig);
     245    sigprocmask(SIG_UNBLOCK, &ss, NULL);
     246}
     247
     248#if 0
     249void sig_blocknone(void)
     250{
     251    sigset_t ss;
     252    sigemptyset(&ss);
     253    sigprocmask(SIG_SETMASK, &ss, NULL);
     254}
    185255#endif
    186256
    187 #ifdef L_spawn
    188 // This does a fork/exec in one call, using vfork().
    189 pid_t bb_spawn(char **argv)
    190 {
    191     static int failed;
    192     pid_t pid;
    193     void *app = find_applet_by_name(argv[0]);
    194 
    195     // Be nice to nommu machines.
    196     failed = 0;
    197     pid = vfork();
    198     if (pid < 0) return pid;
    199     if (!pid) {
    200         execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv);
    201 
    202         // We're sharing a stack with blocked parent, let parent know we failed
    203         // and then exit to unblock parent (but don't run atexit() stuff, which
    204         // would screw up parent.)
    205 
    206         failed = -1;
    207         _exit(0);
    208     }
    209     return failed ? failed : pid;
    210 }
     257void sig_catch(int sig, void (*f)(int))
     258{
     259    struct sigaction sa;
     260    sa.sa_handler = f;
     261    sa.sa_flags = 0;
     262    sigemptyset(&sa.sa_mask);
     263    sigaction(sig, &sa, NULL);
     264}
     265
     266void sig_pause(void)
     267{
     268    sigset_t ss;
     269    sigemptyset(&ss);
     270    sigsuspend(&ss);
     271}
     272
     273
     274void xsetenv(const char *key, const char *value)
     275{
     276    if (setenv(key, value, 1))
     277        bb_error_msg_and_die(bb_msg_memory_exhausted);
     278}
     279
     280// Converts unsigned long long value into compact 4-char
     281// representation. Examples: "1234", "1.2k", " 27M", "123T"
     282// Fifth char is always '\0'
     283void smart_ulltoa5(unsigned long long ul, char buf[5])
     284{
     285    const char *fmt;
     286    char c;
     287    unsigned v,idx = 0;
     288    ul *= 10;
     289    if (ul > 9999*10) { // do not scale if 9999 or less
     290        while (ul >= 10000) {
     291            ul /= 1024;
     292            idx++;
     293        }
     294    }
     295    v = ul; // ullong divisions are expensive, avoid them
     296
     297    fmt = " 123456789";
     298    if (!idx) {     // 9999 or less: use 1234 format
     299        c = buf[0] = " 123456789"[v/10000];
     300        if (c != ' ') fmt = "0123456789";
     301        c = buf[1] = fmt[v/1000%10];
     302        if (c != ' ') fmt = "0123456789";
     303        buf[2] = fmt[v/100%10];
     304        buf[3] = "0123456789"[v/10%10];
     305    } else {
     306        if (v >= 10*10) {   // scaled value is >=10: use 123M format
     307            c = buf[0] = " 123456789"[v/1000];
     308            if (c != ' ') fmt = "0123456789";
     309            buf[1] = fmt[v/100%10];
     310            buf[2] = "0123456789"[v/10%10];
     311        } else {    // scaled value is <10: use 1.2M format
     312            buf[0] = "0123456789"[v/10];
     313            buf[1] = '.';
     314            buf[2] = "0123456789"[v%10];
     315        }
     316        // see http://en.wikipedia.org/wiki/Tera
     317        buf[3] = " kMGTPEZY"[idx];
     318    }
     319    buf[4] = '\0';
     320}
     321
     322// Convert unsigned integer to ascii, writing into supplied buffer.
     323// A truncated result contains the first few digits of the result ala strncpy.
     324// Returns a pointer past last generated digit, does _not_ store NUL.
     325void BUG_sizeof_unsigned_not_4(void);
     326char *utoa_to_buf(unsigned n, char *buf, unsigned buflen)
     327{
     328    unsigned i, out, res;
     329    if (sizeof(unsigned) != 4)
     330        BUG_sizeof_unsigned_not_4();
     331    if (buflen) {
     332        out = 0;
     333        for (i = 1000000000; i; i /= 10) {
     334            res = n / i;
     335            if (res || out || i == 1) {
     336                if (!--buflen) break;
     337                out++;
     338                n -= res*i;
     339                *buf++ = '0' + res;
     340            }
     341        }
     342    }
     343    return buf;
     344}
     345
     346// Convert signed integer to ascii, like utoa_to_buf()
     347char *itoa_to_buf(int n, char *buf, unsigned buflen)
     348{
     349    if (buflen && n<0) {
     350        n = -n;
     351        *buf++ = '-';
     352        buflen--;
     353    }
     354    return utoa_to_buf((unsigned)n, buf, buflen);
     355}
     356
     357// The following two functions use a static buffer, so calling either one a
     358// second time will overwrite previous results.
     359//
     360// The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes.
     361// Int should always be 32 bits on any remotely Unix-like system, see
     362// http://www.unix.org/whitepapers/64bit.html for the reasons why.
     363
     364static char local_buf[12];
     365
     366// Convert unsigned integer to ascii using a static buffer (returned).
     367char *utoa(unsigned n)
     368{
     369    *(utoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';
     370
     371    return local_buf;
     372}
     373
     374// Convert signed integer to ascii using a static buffer (returned).
     375char *itoa(int n)
     376{
     377    *(itoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';
     378
     379    return local_buf;
     380}
     381
     382// Emit a string of hex representation of bytes
     383char *bin2hex(char *p, const char *cp, int count)
     384{
     385    while (count) {
     386        unsigned char c = *cp++;
     387        /* put lowercase hex digits */
     388        *p++ = 0x20 | bb_hexdigits_upcase[c >> 4];
     389        *p++ = 0x20 | bb_hexdigits_upcase[c & 0xf];
     390        count--;
     391    }
     392    return p;
     393}
     394
     395// Die with an error message if we can't set gid.  (Because resource limits may
     396// limit this user to a given number of processes, and if that fills up the
     397// setgid() will fail and we'll _still_be_root_, which is bad.)
     398void xsetgid(gid_t gid)
     399{
     400    if (setgid(gid)) bb_perror_msg_and_die("setgid");
     401}
     402
     403// Die with an error message if we can't set uid.  (See xsetgid() for why.)
     404void xsetuid(uid_t uid)
     405{
     406    if (setuid(uid)) bb_perror_msg_and_die("setuid");
     407}
     408
     409// Return how long the file at fd is, if there's any way to determine it.
     410off_t fdlength(int fd)
     411{
     412    off_t bottom = 0, top = 0, pos;
     413    long size;
     414
     415    // If the ioctl works for this, return it.
     416
     417    if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
     418
     419    // FIXME: explain why lseek(SEEK_END) is not used here!
     420
     421    // If not, do a binary search for the last location we can read.  (Some
     422    // block devices don't do BLKGETSIZE right.)
     423
     424    do {
     425        char temp;
     426
     427        pos = bottom + (top - bottom) / 2;
     428
     429        // If we can read from the current location, it's bigger.
     430
     431        if (lseek(fd, pos, SEEK_SET)>=0 && safe_read(fd, &temp, 1)==1) {
     432            if (bottom == top) bottom = top = (top+1) * 2;
     433            else bottom = pos;
     434
     435        // If we can't, it's smaller.
     436
     437        } else {
     438            if (bottom == top) {
     439                if (!top) return 0;
     440                bottom = top/2;
     441            }
     442            else top = pos;
     443        }
     444    } while (bottom + 1 != top);
     445
     446    return pos + 1;
     447}
     448
     449// Die with an error message if we can't malloc() enough space and do an
     450// sprintf() into that space.
     451char *xasprintf(const char *format, ...)
     452{
     453    va_list p;
     454    int r;
     455    char *string_ptr;
     456
     457#if 1
     458    // GNU extension
     459    va_start(p, format);
     460    r = vasprintf(&string_ptr, format, p);
     461    va_end(p);
     462#else
     463    // Bloat for systems that haven't got the GNU extension.
     464    va_start(p, format);
     465    r = vsnprintf(NULL, 0, format, p);
     466    va_end(p);
     467    string_ptr = xmalloc(r+1);
     468    va_start(p, format);
     469    r = vsnprintf(string_ptr, r+1, format, p);
     470    va_end(p);
    211471#endif
    212472
    213 #ifdef L_xspawn
    214 pid_t bb_xspawn(char **argv)
    215 {
    216     pid_t pid = bb_spawn(argv);
    217     if (pid < 0) bb_perror_msg_and_die("%s", *argv);
    218     return pid;
    219 }
     473    if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted);
     474    return string_ptr;
     475}
     476
     477#if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */
     478int fdprintf(int fd, const char *format, ...)
     479{
     480    va_list p;
     481    int r;
     482    char *string_ptr;
     483
     484#if 1
     485    // GNU extension
     486    va_start(p, format);
     487    r = vasprintf(&string_ptr, format, p);
     488    va_end(p);
     489#else
     490    // Bloat for systems that haven't got the GNU extension.
     491    va_start(p, format);
     492    r = vsnprintf(NULL, 0, format, p) + 1;
     493    va_end(p);
     494    string_ptr = malloc(r);
     495    if (string_ptr) {
     496        va_start(p, format);
     497        r = vsnprintf(string_ptr, r, format, p);
     498        va_end(p);
     499    }
    220500#endif
    221501
    222 #ifdef L_wait4
    223 int wait4pid(int pid)
    224 {
    225     int status;
    226 
    227     if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1;
    228     if (WIFEXITED(status)) return WEXITSTATUS(status);
    229     if (WIFSIGNALED(status)) return WTERMSIG(status);
    230     return 0;
    231 }
    232 #endif 
    233 
    234 #ifdef L_setuid
    235 void xsetgid(gid_t gid)
    236 {
    237     if (setgid(gid)) bb_error_msg_and_die("setgid");
    238 }
    239 
    240 void xsetuid(uid_t uid)
    241 {
    242     if (setuid(uid)) bb_error_msg_and_die("setuid");
     502    if (r >= 0) {
     503        full_write(fd, string_ptr, r);
     504        free(string_ptr);
     505    }
     506    return r;
    243507}
    244508#endif
     509
     510// Die with an error message if we can't copy an entire FILE * to stdout, then
     511// close that file.
     512void xprint_and_close_file(FILE *file)
     513{
     514    fflush(stdout);
     515    // copyfd outputs error messages for us.
     516    if (bb_copyfd_eof(fileno(file), 1) == -1)
     517        xfunc_die();
     518
     519    fclose(file);
     520}
     521
     522// Die if we can't chdir to a new path.
     523void xchdir(const char *path)
     524{
     525    if (chdir(path))
     526        bb_perror_msg_and_die("chdir(%s)", path);
     527}
     528
     529// Print a warning message if opendir() fails, but don't die.
     530DIR *warn_opendir(const char *path)
     531{
     532    DIR *dp;
     533
     534    dp = opendir(path);
     535    if (!dp)
     536        bb_perror_msg("can't open '%s'", path);
     537    return dp;
     538}
     539
     540// Die with an error message if opendir() fails.
     541DIR *xopendir(const char *path)
     542{
     543    DIR *dp;
     544
     545    dp = opendir(path);
     546    if (!dp)
     547        bb_perror_msg_and_die("can't open '%s'", path);
     548    return dp;
     549}
     550
     551// Die with an error message if we can't open a new socket.
     552int xsocket(int domain, int type, int protocol)
     553{
     554    int r = socket(domain, type, protocol);
     555
     556    if (r < 0) {
     557        /* Hijack vaguely related config option */
     558#if ENABLE_VERBOSE_RESOLUTION_ERRORS
     559        const char *s = "INET";
     560        if (domain == AF_PACKET) s = "PACKET";
     561        if (domain == AF_NETLINK) s = "NETLINK";
     562USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
     563        bb_perror_msg_and_die("socket(AF_%s)", s);
     564#else
     565        bb_perror_msg_and_die("socket");
     566#endif
     567    }
     568
     569    return r;
     570}
     571
     572// Die with an error message if we can't bind a socket to an address.
     573void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
     574{
     575    if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
     576}
     577
     578// Die with an error message if we can't listen for connections on a socket.
     579void xlisten(int s, int backlog)
     580{
     581    if (listen(s, backlog)) bb_perror_msg_and_die("listen");
     582}
     583
     584/* Die with an error message if sendto failed.
     585 * Return bytes sent otherwise  */
     586ssize_t xsendto(int s, const  void *buf, size_t len, const struct sockaddr *to,
     587                socklen_t tolen)
     588{
     589    ssize_t ret = sendto(s, buf, len, 0, to, tolen);
     590    if (ret < 0) {
     591        if (ENABLE_FEATURE_CLEAN_UP)
     592            close(s);
     593        bb_perror_msg_and_die("sendto");
     594    }
     595    return ret;
     596}
     597
     598// xstat() - a stat() which dies on failure with meaningful error message
     599void xstat(const char *name, struct stat *stat_buf)
     600{
     601    if (stat(name, stat_buf))
     602        bb_perror_msg_and_die("can't stat '%s'", name);
     603}
     604
     605// selinux_or_die() - die if SELinux is disabled.
     606void selinux_or_die(void)
     607{
     608#if ENABLE_SELINUX
     609    int rc = is_selinux_enabled();
     610    if (rc == 0) {
     611        bb_error_msg_and_die("SELinux is disabled");
     612    } else if (rc < 0) {
     613        bb_error_msg_and_die("is_selinux_enabled() failed");
     614    }
     615#else
     616    bb_error_msg_and_die("SELinux support is disabled");
     617#endif
     618}
     619
     620/* It is perfectly ok to pass in a NULL for either width or for
     621 * height, in which case that value will not be set.  */
     622int get_terminal_width_height(int fd, int *width, int *height)
     623{
     624    struct winsize win = { 0, 0, 0, 0 };
     625    int ret = ioctl(fd, TIOCGWINSZ, &win);
     626
     627    if (height) {
     628        if (!win.ws_row) {
     629            char *s = getenv("LINES");
     630            if (s) win.ws_row = atoi(s);
     631        }
     632        if (win.ws_row <= 1 || win.ws_row >= 30000)
     633            win.ws_row = 24;
     634        *height = (int) win.ws_row;
     635    }
     636
     637    if (width) {
     638        if (!win.ws_col) {
     639            char *s = getenv("COLUMNS");
     640            if (s) win.ws_col = atoi(s);
     641        }
     642        if (win.ws_col <= 1 || win.ws_col >= 30000)
     643            win.ws_col = 80;
     644        *width = (int) win.ws_col;
     645    }
     646
     647    return ret;
     648}
     649
     650void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...)
     651{
     652    va_list p;
     653
     654    if (ioctl(fd, request, argp) < 0) {
     655        va_start(p, fmt);
     656        bb_verror_msg(fmt, p, strerror(errno));
     657        /* xfunc_die can actually longjmp, so be nice */
     658        va_end(p);
     659        xfunc_die();
     660    }
     661}
     662
     663int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...)
     664{
     665    va_list p;
     666    int ret = ioctl(fd, request, argp);
     667
     668    if (ret < 0) {
     669        va_start(p, fmt);
     670        bb_verror_msg(fmt, p, strerror(errno));
     671        va_end(p);
     672    }
     673    return ret;
     674}
     675
     676#if ENABLE_IOCTL_HEX2STR_ERROR
     677int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name)
     678{
     679    int ret;
     680
     681    ret = ioctl(fd, request, argp);
     682    if (ret < 0)
     683        bb_perror_msg("%s", ioctl_name);
     684    return ret;
     685}
     686void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name)
     687{
     688    if (ioctl(fd, request, argp) < 0)
     689        bb_perror_msg_and_die("%s", ioctl_name);
     690}
     691#else
     692int bb_ioctl_or_warn(int fd, int request, void *argp)
     693{
     694    int ret;
     695
     696    ret = ioctl(fd, request, argp);
     697    if (ret < 0)
     698        bb_perror_msg("ioctl %#x failed", request);
     699    return ret;
     700}
     701void bb_xioctl(int fd, int request, void *argp)
     702{
     703    if (ioctl(fd, request, argp) < 0)
     704        bb_perror_msg_and_die("ioctl %#x failed", request);
     705}
     706#endif
  • branches/2.2.5/mindi-busybox/libbb/xgetcwd.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * xgetcwd.c -- return current directory with unlimited length
     
    78*/
    89
    9 #include <stdlib.h>
    10 #include <errno.h>
    11 #include <unistd.h>
    12 #include <limits.h>
    13 #include <sys/param.h>
    1410#include "libbb.h"
    1511
     
    2319
    2420char *
    25 xgetcwd (char *cwd)
     21xrealloc_getcwd_or_warn(char *cwd)
    2622{
    27   char *ret;
    28   unsigned path_max;
     23    char *ret;
     24    unsigned path_max;
    2925
    30   path_max = (unsigned) PATH_MAX;
    31   path_max += 2;                /* The getcwd docs say to do this. */
     26    path_max = (unsigned) PATH_MAX;
     27    path_max += 2;                /* The getcwd docs say to do this. */
    3228
    33   if(cwd==0)
    34     cwd = xmalloc (path_max);
     29    if (cwd == NULL)
     30        cwd = xmalloc(path_max);
    3531
    36   while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE) {
    37       path_max += PATH_INCR;
    38       cwd = xrealloc (cwd, path_max);
    39   }
     32    while ((ret = getcwd(cwd, path_max)) == NULL && errno == ERANGE) {
     33        path_max += PATH_INCR;
     34        cwd = xrealloc(cwd, path_max);
     35    }
    4036
    41   if (ret == NULL) {
    42       free (cwd);
    43       bb_perror_msg("getcwd()");
    44       return NULL;
    45   }
     37    if (ret == NULL) {
     38        free(cwd);
     39        bb_perror_msg("getcwd");
     40        return NULL;
     41    }
    4642
    47   return cwd;
     43    return cwd;
    4844}
  • branches/2.2.5/mindi-busybox/libbb/xgethostbyname.c

    r821 r1765  
    55 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>.
    66 *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15  * General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20  *
     7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    218 */
    229
    23 #include <netdb.h>
     10//#include <netdb.h>
    2411#include "libbb.h"
    25 
    2612
    2713struct hostent *xgethostbyname(const char *name)
    2814{
    29     struct hostent *retval;
    30 
    31     if ((retval = gethostbyname(name)) == NULL)
     15    struct hostent *retval = gethostbyname(name);
     16    if (!retval)
    3217        bb_herror_msg_and_die("%s", name);
    33 
    3418    return retval;
    3519}
  • branches/2.2.5/mindi-busybox/libbb/xreadlink.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 *  xreadlink.c - safe implementation of readlink.
     
    45 */
    56
    6 #include <stdio.h>
     7#include "libbb.h"
    78
    89/*
     
    1011 * yourself. You have been warned.
    1112 */
    12 
    13 #include <unistd.h>
    14 #include "libbb.h"
    15 
    16 char *xreadlink(const char *path)
     13char *xmalloc_readlink(const char *path)
    1714{
    1815    enum { GROWBY = 80 }; /* how large we will grow strings by */
     
    2320    do {
    2421        buf = xrealloc(buf, bufsize += GROWBY);
    25         readsize = readlink(path, buf, bufsize); /* 1st try */
     22        readsize = readlink(path, buf, bufsize);
    2623        if (readsize == -1) {
    27             bb_perror_msg("%s", path);
    2824            free(buf);
    2925            return NULL;
    3026        }
    31     }
    32     while (bufsize < readsize + 1);
     27    } while (bufsize < readsize + 1);
    3328
    3429    buf[readsize] = '\0';
     
    3631    return buf;
    3732}
     33
     34char *xmalloc_readlink_or_warn(const char *path)
     35{
     36    char *buf = xmalloc_readlink(path);
     37    if (!buf) {
     38        /* EINVAL => "file: Invalid argument" => puzzled user */
     39        bb_error_msg("%s: cannot read link (not a symlink?)", path);
     40    }
     41    return buf;
     42}
     43
     44/* UNUSED */
     45#if 0
     46char *xmalloc_realpath(const char *path)
     47{
     48#if defined(__GLIBC__) && !defined(__UCLIBC__)
     49    /* glibc provides a non-standard extension */
     50    return realpath(path, NULL);
     51#else
     52    char buf[PATH_MAX+1];
     53
     54    /* on error returns NULL (xstrdup(NULL) ==NULL) */
     55    return xstrdup(realpath(path, buf));
     56#endif
     57}
     58#endif
  • branches/2.2.5/mindi-busybox/libbb/xregcomp.c

    r821 r1765  
    99 */
    1010
    11 #include <stdio.h>
    1211#include "libbb.h"
    1312#include "xregex.h"
    1413
    15 
     14char* regcomp_or_errmsg(regex_t *preg, const char *regex, int cflags)
     15{
     16    int ret = regcomp(preg, regex, cflags);
     17    if (ret) {
     18        int errmsgsz = regerror(ret, preg, NULL, 0);
     19        char *errmsg = xmalloc(errmsgsz);
     20        regerror(ret, preg, errmsg, errmsgsz);
     21        return errmsg;
     22    }
     23    return NULL;
     24}
    1625
    1726void xregcomp(regex_t *preg, const char *regex, int cflags)
    1827{
    19     int ret;
    20     if ((ret = regcomp(preg, regex, cflags)) != 0) {
    21         int errmsgsz = regerror(ret, preg, NULL, 0);
    22         char *errmsg = xmalloc(errmsgsz);
    23         regerror(ret, preg, errmsg, errmsgsz);
     28    char *errmsg = regcomp_or_errmsg(preg, regex, cflags);
     29    if (errmsg) {
    2430        bb_error_msg_and_die("xregcomp: %s", errmsg);
    2531    }
Note: See TracChangeset for help on using the changeset viewer.