Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/libbb


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

in the future for sure)

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

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

Location:
branches/stable/mindi-busybox/libbb
Files:
27 deleted
81 edited
20 copied

Legend:

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

    r821 r1770  
    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/stable/mindi-busybox/libbb/ask_confirmation.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/bb_askpass.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/bb_do_delay.c

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

    r821 r1770  
    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/stable/mindi-busybox/libbb/change_identity.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/chomp.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/compare_string_array.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/concat_path_file.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/concat_subpath_file.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/copy_file.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/copyfd.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/correct_password.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/crc32.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/create_icmp6_socket.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/create_icmp_socket.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/default_error_retval.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/device_open.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/dump.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/error_msg.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/error_msg_and_die.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/fclose_nonstdin.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/fflush_stdout_and_exit.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/fgets_str.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/find_mount_point.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/find_pid_by_name.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/find_root_device.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/full_write.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/get_console.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/get_last_path_component.c

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

    r821 r1770  
    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/stable/mindi-busybox/libbb/herror_msg.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/herror_msg_and_die.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/human_readable.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/inet_common.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/inode_hash.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/kernel_version.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/last_char_is.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/llist.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/login.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/loop.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/make_directory.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/md5.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/messages.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/mode_string.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/mtab.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/mtab_file.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/obscure.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/parse_mode.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/perror_msg.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/perror_msg_and_die.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/perror_nomsg.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/perror_nomsg_and_die.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/process_escape_sequence.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/procps.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/pw_encrypt.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/recursive_action.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/remove_file.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/restricted_shell.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/run_shell.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/safe_strncpy.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/safe_write.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/setup_environment.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/sha1.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/simplify_path.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/skip_whitespace.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/speed_table.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/trim.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/u_signal_names.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/vdprintf.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/verror_msg.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/vfork_daemon_rexec.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/warn_ignoring_args.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/wfopen.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/wfopen_input.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/xconnect.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/xfuncs.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/xgetcwd.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/xgethostbyname.c

    r821 r1770  
    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/stable/mindi-busybox/libbb/xreadlink.c

    r821 r1770  
     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/stable/mindi-busybox/libbb/xregcomp.c

    r821 r1770  
    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.