Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/debianutils


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
Location:
branches/2.2.9/mindi-busybox/debianutils
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/debianutils/Config.in

    r1765 r2725  
     1# DO NOT EDIT. This file is generated from Config.src
    12#
    23# For a description of the syntax of this configuration file,
     
    67menu "Debian Utilities"
    78
     9
     10
    811config MKTEMP
    912    bool "mktemp"
    10     default n
     13    default y
    1114    help
    1215      mktemp is used to create unique temporary files
     
    1417config PIPE_PROGRESS
    1518    bool "pipe_progress"
    16     default n
     19    default y
    1720    help
    1821      Display a dot to indicate pipe activity.
     
    2023config RUN_PARTS
    2124    bool "run-parts"
    22     default n
     25    default y
    2326    help
    2427      run-parts is a utility designed to run all the scripts in a directory.
     
    2730      execute all the scripts in that directory.
    2831
    29       In this implementation of run-parts some features (such as report mode)
    30       are not implemented.
     32      In this implementation of run-parts some features (such as report
     33      mode) are not implemented.
    3134
    3235      Unless you know that run-parts is used in some of your scripts
     
    3538config FEATURE_RUN_PARTS_LONG_OPTIONS
    3639    bool "Enable long options"
    37     default n
    38     depends on RUN_PARTS && GETOPT_LONG
     40    default y
     41    depends on RUN_PARTS && LONG_OPTS
    3942    help
    4043      Support long options for the run-parts applet.
     
    4245config FEATURE_RUN_PARTS_FANCY
    4346    bool "Support additional arguments"
    44     default n
     47    default y
    4548    depends on RUN_PARTS
    4649    help
     
    6568      -o|--oknodo ignored since we exit with 0 anyway
    6669      -v|--verbose
     70      -N|--nicelevel N
    6771
    6872config FEATURE_START_STOP_DAEMON_LONG_OPTIONS
    6973    bool "Enable long options"
    70     default n
    71     depends on START_STOP_DAEMON && GETOPT_LONG
     74    default y
     75    depends on START_STOP_DAEMON && LONG_OPTS
    7276    help
    7377      Support long options for the start-stop-daemon applet.
     
    7579config WHICH
    7680    bool "which"
    77     default n
     81    default y
    7882    help
    7983      which is used to find programs in your PATH and
     
    8185
    8286endmenu
    83 
  • branches/2.2.9/mindi-busybox/debianutils/Kbuild

    r1765 r2725  
     1# DO NOT EDIT. This file is generated from Kbuild.src
    12# Makefile for busybox
    23#
    34# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
    45#
    5 # Licensed under the GPL v2, see the file LICENSE in this tarball.
     6# Licensed under GPLv2, see file LICENSE in this source tree.
    67
    78lib-y:=
     9
     10
    811lib-$(CONFIG_MKTEMP)            += mktemp.o
    912lib-$(CONFIG_PIPE_PROGRESS)     += pipe_progress.o
  • branches/2.2.9/mindi-busybox/debianutils/mktemp.c

    r1765 r2725  
    77 * Written by Daniel Jacobowitz <dan@debian.org>
    88 *
    9  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1010 */
     11
     12/* Coreutils 6.12 man page says:
     13 *        mktemp [OPTION]... [TEMPLATE]
     14 * Create a temporary file or directory, safely, and print its name. If
     15 * TEMPLATE is not specified, use tmp.XXXXXXXXXX.
     16 * -d, --directory
     17 *        create a directory, not a file
     18 * -q, --quiet
     19 *        suppress diagnostics about file/dir-creation failure
     20 * -u, --dry-run
     21 *        do not create anything; merely print a name (unsafe)
     22 * --tmpdir[=DIR]
     23 *        interpret TEMPLATE relative to DIR. If DIR is not specified,
     24 *        use  $TMPDIR if set, else /tmp.  With this option, TEMPLATE must
     25 *        not be an absolute name. Unlike with -t, TEMPLATE may contain
     26 *        slashes, but even here, mktemp still creates only the final com-
     27 *        ponent.
     28 * -p DIR use DIR as a prefix; implies -t [deprecated]
     29 * -t     interpret TEMPLATE as a single file name component, relative  to
     30 *        a  directory:  $TMPDIR, if set; else the directory specified via
     31 *        -p; else /tmp [deprecated]
     32 */
     33
    1134
    1235#include "libbb.h"
    1336
    14 int mktemp_main(int argc, char **argv);
    15 int mktemp_main(int argc, char **argv)
     37int mktemp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     38int mktemp_main(int argc UNUSED_PARAM, char **argv)
    1639{
    17     unsigned long flags = getopt32(argv, "dqt");
     40    const char *path;
    1841    char *chp;
     42    unsigned opts;
    1943
    20     if (optind + 1 != argc)
    21         bb_show_usage();
     44    path = getenv("TMPDIR");
     45    if (!path || path[0] == '\0')
     46        path = "/tmp";
    2247
    23     chp = argv[optind];
     48    /* -q and -t are ignored */
     49    opt_complementary = "?1"; /* 1 argument max */
     50    opts = getopt32(argv, "dqtp:", &path);
    2451
    25     if (flags & 4) {
    26         char *dir = getenv("TMPDIR");
    27         if (dir && *dir != '\0')
    28             chp = concat_path_file(dir, chp);
    29         else
    30             chp = concat_path_file("/tmp/", chp);
    31     }
     52    chp = argv[optind] ? argv[optind] : xstrdup("tmp.XXXXXX");
     53    if (!strchr(chp, '/') || (opts & 8))
     54        chp = concat_path_file(path, chp);
    3255
    33     if (flags & 1) {
     56    if (opts & 1) { /* -d */
    3457        if (mkdtemp(chp) == NULL)
    3558            return EXIT_FAILURE;
  • branches/2.2.9/mindi-busybox/debianutils/pipe_progress.c

    r1765 r2725  
    55 * Copyright (C) 2003 by Rob Landley <rob@landley.net>, Joey Hess
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
    9 
    109#include "libbb.h"
    1110
     
    1514 * Activity is indicated by a '.' to stderr
    1615 */
    17 int pipe_progress_main(int argc, char **argv);
    18 int pipe_progress_main(int argc, char **argv)
     16int pipe_progress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     17int pipe_progress_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
    1918{
    20     RESERVE_CONFIG_BUFFER(buf, PIPE_PROGRESS_SIZE);
     19    char buf[PIPE_PROGRESS_SIZE];
    2120    time_t t = time(NULL);
    22     size_t len;
     21    int len;
    2322
    24     while ((len = fread(buf, 1, PIPE_PROGRESS_SIZE, stdin)) > 0) {
     23    while ((len = safe_read(STDIN_FILENO, buf, PIPE_PROGRESS_SIZE)) > 0) {
    2524        time_t new_time = time(NULL);
    2625        if (new_time != t) {
    2726            t = new_time;
    28             fputc('.', stderr);
     27            bb_putchar_stderr('.');
    2928        }
    30         fwrite(buf, len, 1, stdout);
     29        full_write(STDOUT_FILENO, buf, len);
    3130    }
    3231
    33     fputc('\n', stderr);
    34 
    35     if (ENABLE_FEATURE_CLEAN_UP)
    36         RELEASE_CONFIG_BUFFER(buf);
     32    bb_putchar_stderr('\n');
    3733
    3834    return 0;
  • branches/2.2.9/mindi-busybox/debianutils/run_parts.c

    r1765 r2725  
    33 * Mini run-parts implementation for busybox
    44 *
    5  * Copyright (C) 2007 Bernhard Fischer
     5 * Copyright (C) 2007 Bernhard Reutner-Fischer
    66 *
    77 * Based on a older version that was in busybox which was 1k big..
     
    1313 *
    1414 *
    15  * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
     15 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1616 */
    1717
     
    2424 * broken compatibility because the BusyBox policy doesn't allow them.
    2525 * The supported options are:
    26  * -t           test. Print the name of the files to be executed, without
    27  *              execute them.
    28  * -a ARG       argument. Pass ARG as an argument the program executed. It can
    29  *              be repeated to pass multiple arguments.
    30  * -u MASK      umask. Set the umask of the program executed to MASK.
     26 * -t           test. Print the name of the files to be executed, without
     27 *              execute them.
     28 * -a ARG       argument. Pass ARG as an argument the program executed. It can
     29 *              be repeated to pass multiple arguments.
     30 * -u MASK      umask. Set the umask of the program executed to MASK.
    3131 */
    32 
    33 #include <getopt.h>
    3432
    3533#include "libbb.h"
    3634
    37 #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
    38 static const char runparts_longopts[] ALIGN1 =
    39     "arg\0"     Required_argument "a"
    40     "umask\0"   Required_argument "u"
    41     "test\0"    No_argument       "t"
     35struct globals {
     36    char **names;
     37    int    cur;
     38    char  *cmd[1];
     39} FIX_ALIASING;
     40#define G (*(struct globals*)&bb_common_bufsiz1)
     41#define names (G.names)
     42#define cur   (G.cur  )
     43#define cmd   (G.cmd  )
     44
     45enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 };
     46
     47enum {
     48    OPT_r = (1 << 0),
     49    OPT_a = (1 << 1),
     50    OPT_u = (1 << 2),
     51    OPT_t = (1 << 3),
     52    OPT_l = (1 << 4) * ENABLE_FEATURE_RUN_PARTS_FANCY,
     53};
     54
    4255#if ENABLE_FEATURE_RUN_PARTS_FANCY
    43     "list\0"    No_argument       "l"
    44 //TODO: "reverse\0" No_argument       "r"
    45 //TODO: "verbose\0" No_argument       "v"
    46 #endif
    47     ;
     56#define list_mode (option_mask32 & OPT_l)
     57#else
     58#define list_mode 0
    4859#endif
    4960
    50 struct globals {
    51     smalluint mode;
    52     char *cmd[10]; /* merely arbitrary arg count */
    53 };
    54 #define G (*(struct globals*)&bb_common_bufsiz1)
    55 
    56 /* valid_name */
    57 /* True or false? Is this a valid filename (upper/lower alpha, digits,
     61/* Is this a valid filename (upper/lower alpha, digits,
    5862 * underscores, and hyphens only?)
    5963 */
     
    6872}
    6973
    70 #define RUN_PARTS_OPT_a (1<<0)
    71 #define RUN_PARTS_OPT_u (1<<1)
    72 #define RUN_PARTS_OPT_t (1<<2)
    73 #if ENABLE_FEATURE_RUN_PARTS_FANCY
    74 #define RUN_PARTS_OPT_l (1<<3)
    75 #endif
     74static int bb_alphasort(const void *p1, const void *p2)
     75{
     76    int r = strcmp(*(char **) p1, *(char **) p2);
     77    return (option_mask32 & OPT_r) ? -r : r;
     78}
    7679
    77 #define test_mode (G.mode & RUN_PARTS_OPT_t)
    78 #if ENABLE_FEATURE_RUN_PARTS_FANCY
    79 #define list_mode (G.mode & RUN_PARTS_OPT_l)
    80 #else
    81 #define list_mode (0)
    82 #endif
    83 
    84 static int act(const char *file, struct stat *statbuf, void *args, int depth)
     80static int FAST_FUNC act(const char *file, struct stat *statbuf, void *args UNUSED_PARAM, int depth)
    8581{
    86     int ret;
    87 
    8882    if (depth == 1)
    8983        return TRUE;
    9084
    91     if (depth == 2 &&
    92         ((!list_mode && access(file, X_OK)) ||
    93          invalid_name(file) ||
    94          !(statbuf->st_mode & (S_IFREG | S_IFLNK))) )
     85    if (depth == 2
     86     && (  !(statbuf->st_mode & (S_IFREG | S_IFLNK))
     87        || invalid_name(file)
     88        || (!list_mode && access(file, X_OK) != 0))
     89    ) {
    9590        return SKIP;
     91    }
    9692
    97     if (test_mode || list_mode) {
    98         puts(file);
    99         return TRUE;
    100     }
    101     G.cmd[0] = (char*)file;
    102     ret = wait4pid(spawn(G.cmd));
    103     if (ret < 0) {
    104         bb_perror_msg("failed to exec %s", file);
    105     } else if (ret > 0) {
    106         bb_error_msg("%s exited with return code %d", file, ret);
    107     }
    108     return !ret;
     93    names = xrealloc_vector(names, 4, cur);
     94    names[cur++] = xstrdup(file);
     95    /*names[cur] = NULL; - xrealloc_vector did it */
     96
     97    return TRUE;
    10998}
    11099
    111 int run_parts_main(int argc, char **argv);
    112 int run_parts_main(int argc, char **argv)
     100#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
     101static const char runparts_longopts[] ALIGN1 =
     102    "arg\0"     Required_argument "a"
     103    "umask\0"   Required_argument "u"
     104    "test\0"    No_argument       "t"
     105#if ENABLE_FEATURE_RUN_PARTS_FANCY
     106    "list\0"    No_argument       "l"
     107    "reverse\0" No_argument       "r"
     108//TODO: "verbose\0" No_argument       "v"
     109#endif
     110    ;
     111#endif
     112
     113int run_parts_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     114int run_parts_main(int argc UNUSED_PARAM, char **argv)
    113115{
    114     char *umask_p;
     116    const char *umask_p = "22";
    115117    llist_t *arg_list = NULL;
    116     unsigned tmp;
     118    unsigned n;
     119    int ret;
    117120
    118     umask(022);
    119     /* We require exactly one argument: the directory name */
    120     opt_complementary = "=1:a::";
    121121#if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS
    122122    applet_long_options = runparts_longopts;
    123123#endif
    124     tmp = getopt32(argv, "a:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p);
    125     G.mode = tmp &~ (RUN_PARTS_OPT_a|RUN_PARTS_OPT_u);
    126     if (tmp & RUN_PARTS_OPT_u) {
    127         /* Check and set the umask of the program executed.
    128          * As stated in the original run-parts, the octal conversion in
    129          * libc is not foolproof; it will take the 8 and 9 digits under
    130          * some circumstances. We'll just have to live with it.
    131          */
    132         umask(xstrtoul_range(umask_p, 8, 0, 07777));
     124    /* We require exactly one argument: the directory name */
     125    opt_complementary = "=1:a::";
     126    getopt32(argv, "ra:u:t"IF_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p);
     127
     128    umask(xstrtou_range(umask_p, 8, 0, 07777));
     129
     130    n = 1;
     131    while (arg_list && n < NUM_CMD) {
     132        cmd[n++] = llist_pop(&arg_list);
    133133    }
    134     for (tmp = 1; arg_list; arg_list = arg_list->link, tmp++)
    135         G.cmd[tmp] = arg_list->data;
    136     /* G.cmd[tmp] = NULL; - G is already zeroed out */
    137     if (!recursive_action(argv[argc - 1],
     134    /* cmd[n] = NULL; - is already zeroed out */
     135
     136    /* run-parts has to sort executables by name before running them */
     137
     138    recursive_action(argv[optind],
    138139            ACTION_RECURSE|ACTION_FOLLOWLINKS,
    139             act,        /* file action */
    140             act,        /* dir action */
    141             NULL,       /* user data */
    142             1           /* depth */
    143             ))
    144             return EXIT_FAILURE;
    145     return EXIT_SUCCESS;
     140            act,            /* file action */
     141            act,            /* dir action */
     142            NULL,           /* user data */
     143            1               /* depth */
     144        );
     145
     146    if (!names)
     147        return 0;
     148
     149    qsort(names, cur, sizeof(char *), bb_alphasort);
     150
     151    n = 0;
     152    while (1) {
     153        char *name = *names++;
     154        if (!name)
     155            break;
     156        if (option_mask32 & (OPT_t | OPT_l)) {
     157            puts(name);
     158            continue;
     159        }
     160        cmd[0] = name;
     161        ret = spawn_and_wait(cmd);
     162        if (ret == 0)
     163            continue;
     164        n = 1;
     165        if (ret < 0)
     166            bb_perror_msg("can't execute '%s'", name);
     167        else /* ret > 0 */
     168            bb_error_msg("%s exited with code %d", name, ret & 0xff);
     169    }
     170
     171    return n;
    146172}
  • branches/2.2.9/mindi-busybox/debianutils/start_stop_daemon.c

    r1765 r2725  
    66 * Adapted for busybox David Kimdon <dwhedon@gordian.com>
    77 *
    8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 */
    1010
    11 /* NB: we have a problem here with /proc/NN/exe usage, similar to
    12  * one fixed in killall/pidof */
    13 
    14 #include <getopt.h>
     11/*
     12This is how it is supposed to work:
     13
     14start-stop-daemon [OPTIONS] [--start|--stop] [[--] arguments...]
     15
     16One (only) of these must be given:
     17        -S,--start              Start
     18        -K,--stop               Stop
     19
     20Search for matching processes.
     21If --stop is given, stop all matching processes (by sending a signal).
     22If --start is given, start a new process unless a matching process was found.
     23
     24Options controlling process matching
     25(if multiple conditions are specified, all must match):
     26        -u,--user USERNAME|UID  Only consider this user's processes
     27        -n,--name PROCESS_NAME  Look for processes by matching PROCESS_NAME
     28                                with comm field in /proc/$PID/stat.
     29                                Only basename is compared:
     30                                "ntpd" == "./ntpd" == "/path/to/ntpd".
     31[TODO: can PROCESS_NAME be a full pathname? Should we require full match then
     32with /proc/$PID/exe or argv[0] (comm can't be matched, it never contains path)]
     33        -x,--exec EXECUTABLE    Look for processes that were started with this
     34                                command in /proc/$PID/cmdline.
     35                                Unlike -n, we match against the full path:
     36                                "ntpd" != "./ntpd" != "/path/to/ntpd"
     37        -p,--pidfile PID_FILE   Look for processes with PID from this file
     38
     39Options which are valid for --start only:
     40        -x,--exec EXECUTABLE    Program to run (1st arg of execvp). Mandatory.
     41        -a,--startas NAME       argv[0] (defaults to EXECUTABLE)
     42        -b,--background         Put process into background
     43        -N,--nicelevel N        Add N to process' nice level
     44        -c,--chuid USER[:[GRP]] Change to specified user [and group]
     45        -m,--make-pidfile       Write PID to the pidfile
     46                                (both -m and -p must be given!)
     47
     48Options which are valid for --stop only:
     49        -s,--signal SIG         Signal to send (default:TERM)
     50        -t,--test               Exit with status 0 if process is found
     51                                (we don't actually start or stop daemons)
     52
     53Misc options:
     54        -o,--oknodo             Exit with status 0 if nothing is done
     55        -q,--quiet              Quiet
     56        -v,--verbose            Verbose
     57*/
     58
    1559#include <sys/resource.h>
    1660
     
    1862#define WANT_PIDFILE 1
    1963#include "libbb.h"
    20 
    21 static int signal_nr = 15;
    22 static int user_id = -1;
    23 static char *userspec;
    24 static char *cmdname;
    25 static char *execname;
    26 static char *pidfile;
    27 static smallint quiet;
    2864
    2965struct pid_list {
     
    3268};
    3369
    34 static struct pid_list *found;
    35 
    36 static int pid_is_exec(pid_t pid, const char *name)
    37 {
    38     char buf[sizeof("/proc//exe") + sizeof(int)*3];
    39     char *execbuf;
    40     int n;
    41 
    42     sprintf(buf, "/proc/%u/exe", pid);
    43     n = strlen(name) + 1;
    44     execbuf = xzalloc(n + 1);
    45     readlink(buf, execbuf, n);
    46 
    47     /* if readlink fails, execbuf still contains "" */
    48     n = strcmp(execbuf, name);
    49     if (ENABLE_FEATURE_CLEAN_UP)
    50         free(execbuf);
    51     return !n; /* nonzero (true) if execbuf == name */
    52 }
    53 
    54 static int pid_is_user(int pid, int uid)
     70enum {
     71    CTX_STOP       = (1 <<  0),
     72    CTX_START      = (1 <<  1),
     73    OPT_BACKGROUND = (1 <<  2), // -b
     74    OPT_QUIET      = (1 <<  3), // -q
     75    OPT_TEST       = (1 <<  4), // -t
     76    OPT_MAKEPID    = (1 <<  5), // -m
     77    OPT_a          = (1 <<  6), // -a
     78    OPT_n          = (1 <<  7), // -n
     79    OPT_s          = (1 <<  8), // -s
     80    OPT_u          = (1 <<  9), // -u
     81    OPT_c          = (1 << 10), // -c
     82    OPT_x          = (1 << 11), // -x
     83    OPT_p          = (1 << 12), // -p
     84    OPT_OKNODO     = (1 << 13) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o
     85    OPT_VERBOSE    = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v
     86    OPT_NICELEVEL  = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N
     87};
     88#define QUIET (option_mask32 & OPT_QUIET)
     89#define TEST  (option_mask32 & OPT_TEST)
     90
     91struct globals {
     92    struct pid_list *found_procs;
     93    char *userspec;
     94    char *cmdname;
     95    char *execname;
     96    char *pidfile;
     97    char *execname_cmpbuf;
     98    unsigned execname_sizeof;
     99    int user_id;
     100    smallint signal_nr;
     101} FIX_ALIASING;
     102#define G (*(struct globals*)&bb_common_bufsiz1)
     103#define userspec          (G.userspec            )
     104#define cmdname           (G.cmdname             )
     105#define execname          (G.execname            )
     106#define pidfile           (G.pidfile             )
     107#define user_id           (G.user_id             )
     108#define signal_nr         (G.signal_nr           )
     109#define INIT_G() do { \
     110    user_id = -1; \
     111    signal_nr = 15; \
     112} while (0)
     113
     114#ifdef OLDER_VERSION_OF_X
     115/* -x,--exec EXECUTABLE
     116 * Look for processes with matching /proc/$PID/exe.
     117 * Match is performed using device+inode.
     118 */
     119static int pid_is_exec(pid_t pid)
     120{
     121    struct stat st;
     122    char buf[sizeof("/proc/%u/exe") + sizeof(int)*3];
     123
     124    sprintf(buf, "/proc/%u/exe", (unsigned)pid);
     125    if (stat(buf, &st) < 0)
     126        return 0;
     127    if (st.st_dev == execstat.st_dev
     128     && st.st_ino == execstat.st_ino)
     129        return 1;
     130    return 0;
     131}
     132#endif
     133
     134static int pid_is_exec(pid_t pid)
     135{
     136    ssize_t bytes;
     137    char buf[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
     138
     139    sprintf(buf, "/proc/%u/cmdline", (unsigned)pid);
     140    bytes = open_read_close(buf, G.execname_cmpbuf, G.execname_sizeof);
     141    if (bytes > 0) {
     142        G.execname_cmpbuf[bytes] = '\0';
     143        return strcmp(execname, G.execname_cmpbuf) == 0;
     144    }
     145    return 0;
     146}
     147
     148static int pid_is_name(pid_t pid)
     149{
     150    /* /proc/PID/stat is "PID (comm_15_bytes_max) ..." */
     151    char buf[32]; /* should be enough */
     152    char *p, *pe;
     153
     154    sprintf(buf, "/proc/%u/stat", (unsigned)pid);
     155    if (open_read_close(buf, buf, sizeof(buf) - 1) < 0)
     156        return 0;
     157    buf[sizeof(buf) - 1] = '\0'; /* paranoia */
     158    p = strchr(buf, '(');
     159    if (!p)
     160        return 0;
     161    pe = strrchr(++p, ')');
     162    if (!pe)
     163        return 0;
     164    *pe = '\0';
     165    /* we require comm to match and to not be truncated */
     166    /* in Linux, if comm is 15 chars, it may be a truncated
     167     * name, so we don't allow that to match */
     168    if (strlen(p) >= COMM_LEN - 1) /* COMM_LEN is 16 */
     169        return 0;
     170    return strcmp(p, cmdname) == 0;
     171}
     172
     173static int pid_is_user(int pid)
    55174{
    56175    struct stat sb;
    57176    char buf[sizeof("/proc/") + sizeof(int)*3];
    58177
    59     sprintf(buf, "/proc/%u", pid);
     178    sprintf(buf, "/proc/%u", (unsigned)pid);
    60179    if (stat(buf, &sb) != 0)
    61180        return 0;
    62     return (sb.st_uid == uid);
    63 }
    64 
    65 static int pid_is_cmd(pid_t pid, const char *name)
    66 {
    67     char fname[sizeof("/proc//stat") + sizeof(int)*3];
    68     char *buf;
    69     int r = 0;
    70 
    71     sprintf(fname, "/proc/%u/stat", pid);
    72     buf = xmalloc_open_read_close(fname, NULL);
    73     if (buf) {
    74         char *p = strchr(buf, '(');
    75         if (p) {
    76             char *pe = strrchr(++p, ')');
    77             if (pe) {
    78                 *pe = '\0';
    79                 r = !strcmp(p, name);
    80             }
    81         }
    82         free(buf);
    83     }
    84     return r;
     181    return (sb.st_uid == (uid_t)user_id);
    85182}
    86183
     
    89186    struct pid_list *p;
    90187
    91     if (execname && !pid_is_exec(pid, execname)) {
     188    if (execname && !pid_is_exec(pid)) {
    92189        return;
    93190    }
    94     if (userspec && !pid_is_user(pid, user_id)) {
     191    if (cmdname && !pid_is_name(pid)) {
    95192        return;
    96193    }
    97     if (cmdname && !pid_is_cmd(pid, cmdname)) {
     194    if (userspec && !pid_is_user(pid)) {
    98195        return;
    99196    }
    100197    p = xmalloc(sizeof(*p));
    101     p->next = found;
     198    p->next = G.found_procs;
    102199    p->pid = pid;
    103     found = p;
     200    G.found_procs = p;
    104201}
    105202
     
    109206    unsigned pid;
    110207
    111     f = fopen(pidfile, "r");
     208    f = fopen_for_read(pidfile);
    112209    if (f) {
    113210        if (fscanf(f, "%u", &pid) == 1)
     
    122219    DIR *procdir;
    123220    struct dirent *entry;
    124     int foundany, pid;
     221    int pid;
    125222
    126223    if (pidfile) {
     
    131228    procdir = xopendir("/proc");
    132229
    133     foundany = 0;
    134     while ((entry = readdir(procdir)) != NULL) {
     230    pid = 0;
     231    while (1) {
     232        errno = 0; /* clear any previous error */
     233        entry = readdir(procdir);
     234// TODO: this check is too generic, it's better
     235// to check for exact errno(s) which mean that we got stale entry
     236        if (errno) /* Stale entry, process has died after opendir */
     237            continue;
     238        if (!entry) /* EOF, no more entries */
     239            break;
    135240        pid = bb_strtou(entry->d_name, NULL, 10);
    136         if (errno)
     241        if (errno) /* NaN */
    137242            continue;
    138         foundany++;
    139243        check(pid);
    140244    }
    141245    closedir(procdir);
    142     if (!foundany)
     246    if (!pid)
    143247        bb_error_msg_and_die("nothing in /proc - not mounted?");
    144248}
     
    149253    struct pid_list *p;
    150254    int killed = 0;
    151 
    152     do_procinit();
    153255
    154256    if (cmdname) {
     
    158260        if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(execname);
    159261        if (!ENABLE_FEATURE_CLEAN_UP) what = execname;
    160     } else if (pidfile)
     262    } else if (pidfile) {
    161263        what = xasprintf("process in pidfile '%s'", pidfile);
    162     else if (userspec)
     264    } else if (userspec) {
    163265        what = xasprintf("process(es) owned by '%s'", userspec);
    164     else
     266    } else {
    165267        bb_error_msg_and_die("internal error, please report");
    166 
    167     if (!found) {
    168         if (!quiet)
     268    }
     269
     270    if (!G.found_procs) {
     271        if (!QUIET)
    169272            printf("no %s found; none killed\n", what);
    170273        killed = -1;
    171274        goto ret;
    172275    }
    173     for (p = found; p; p = p->next) {
    174         if (kill(p->pid, signal_nr) == 0) {
    175             p->pid = - p->pid;
     276    for (p = G.found_procs; p; p = p->next) {
     277        if (TEST || kill(p->pid, signal_nr) == 0) {
    176278            killed++;
    177279        } else {
    178             bb_perror_msg("warning: killing process %u", p->pid);
     280            p->pid = 0;
     281            bb_perror_msg("warning: killing process %u", (unsigned)p->pid);
    179282        }
    180283    }
    181     if (!quiet && killed) {
     284    if (!QUIET && killed) {
    182285        printf("stopped %s (pid", what);
    183         for (p = found; p; p = p->next)
    184             if (p->pid < 0)
    185                 printf(" %u", - p->pid);
     286        for (p = G.found_procs; p; p = p->next)
     287            if (p->pid)
     288                printf(" %u", (unsigned)p->pid);
    186289        puts(")");
    187290    }
     
    198301    "background\0"   No_argument       "b"
    199302    "quiet\0"        No_argument       "q"
     303    "test\0"         No_argument       "t"
    200304    "make-pidfile\0" No_argument       "m"
    201305#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
     
    217321#endif
    218322
    219 enum {
    220     CTX_STOP       = 0x1,
    221     CTX_START      = 0x2,
    222     OPT_BACKGROUND = 0x4, // -b
    223     OPT_QUIET      = 0x8, // -q
    224     OPT_MAKEPID    = 0x10, // -m
    225     OPT_a          = 0x20, // -a
    226     OPT_n          = 0x40, // -n
    227     OPT_s          = 0x80, // -s
    228     OPT_u          = 0x100, // -u
    229     OPT_c          = 0x200, // -c
    230     OPT_x          = 0x400, // -x
    231     OPT_p          = 0x800, // -p
    232     OPT_OKNODO     = 0x1000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o
    233     OPT_VERBOSE    = 0x2000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v
    234     OPT_NICELEVEL  = 0x4000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N
    235 };
    236 
    237 int start_stop_daemon_main(int argc, char **argv);
    238 int start_stop_daemon_main(int argc, char **argv)
     323int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     324int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
    239325{
    240326    unsigned opt;
     
    242328    char *startas;
    243329    char *chuid;
     330#ifdef OLDER_VERSION_OF_X
     331    struct stat execstat;
     332#endif
    244333#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
    245334//  char *retry_arg = NULL;
     
    247336    char *opt_N;
    248337#endif
     338
     339    INIT_G();
     340
    249341#if ENABLE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
    250342    applet_long_options = start_stop_daemon_longopts;
    251343#endif
    252344
    253     /* Check required one context option was given */
    254     opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa";
    255     opt = getopt32(argv, "KSbqma:n:s:u:c:x:p:"
    256         USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:"),
    257 //      USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"),
     345    /* -K or -S is required; they are mutually exclusive */
     346    /* -p is required if -m is given */
     347    /* -xpun (at least one) is required if -K is given */
     348    /* -xa (at least one) is required if -S is given */
     349    /* -q turns off -v */
     350    opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa"
     351        IF_FEATURE_START_STOP_DAEMON_FANCY("q-v");
     352    opt = getopt32(argv, "KSbqtma:n:s:u:c:x:p:"
     353        IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"),
    258354        &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile
    259         USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
    260 //      USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg)
     355        IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
     356        /* We accept and ignore -R <param> / --retry <param> */
     357        IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL)
    261358    );
    262 
    263     quiet = (opt & OPT_QUIET) && !(opt & OPT_VERBOSE);
    264359
    265360    if (opt & OPT_s) {
     
    270365    if (!(opt & OPT_a))
    271366        startas = execname;
    272 
    273 //  USE_FEATURE_START_STOP_DAEMON_FANCY(
     367    if (!execname) /* in case -a is given and -x is not */
     368        execname = startas;
     369    if (execname) {
     370        G.execname_sizeof = strlen(execname) + 1;
     371        G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1);
     372    }
     373
     374//  IF_FEATURE_START_STOP_DAEMON_FANCY(
    274375//      if (retry_arg)
    275 //          retries = xatoi_u(retry_arg);
     376//          retries = xatoi_positive(retry_arg);
    276377//  )
    277     argc -= optind;
     378    //argc -= optind;
    278379    argv += optind;
    279380
     
    283384            user_id = xuname2uid(userspec);
    284385    }
     386    /* Both start and stop need to know current processes */
     387    do_procinit();
    285388
    286389    if (opt & CTX_STOP) {
     
    289392    }
    290393
    291     do_procinit();
    292 
    293     if (found) {
    294         if (!quiet)
    295             printf("%s already running\n%d\n", execname, found->pid);
     394    if (G.found_procs) {
     395        if (!QUIET)
     396            printf("%s is already running\n%u\n", execname, (unsigned)G.found_procs->pid);
    296397        return !(opt & OPT_OKNODO);
    297398    }
     399
     400#ifdef OLDER_VERSION_OF_X
     401    if (execname)
     402        xstat(execname, &execstat);
     403#endif
     404
    298405    *--argv = startas;
    299406    if (opt & OPT_BACKGROUND) {
    300407#if BB_MMU
    301         bb_daemonize(0);
     408        bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS);
     409        /* DAEMON_DEVNULL_STDIO is superfluous -
     410         * it's always done by bb_daemonize() */
    302411#else
    303         pid_t pid = vfork();
    304         if (pid < 0) /* error */
    305             bb_perror_msg_and_die("vfork");
     412        pid_t pid = xvfork();
    306413        if (pid != 0) {
    307414            /* parent */
    308415            /* why _exit? the child may have changed the stack,
    309416             * so "return 0" may do bad things */
    310             _exit(0);
     417            _exit(EXIT_SUCCESS);
    311418        }
    312         /* child */
     419        /* Child */
    313420        setsid(); /* detach from controlling tty */
    314421        /* Redirect stdio to /dev/null, close extra FDs.
    315422         * We do not actually daemonize because of DAEMON_ONLY_SANITIZE */
    316         bb_daemonize_or_rexec(
    317             DAEMON_DEVNULL_STDIO
     423        bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO
    318424            + DAEMON_CLOSE_EXTRA_FDS
    319425            + DAEMON_ONLY_SANITIZE,
     
    322428    }
    323429    if (opt & OPT_MAKEPID) {
    324         /* user wants _us_ to make the pidfile */
     430        /* User wants _us_ to make the pidfile */
    325431        write_pidfile(pidfile);
    326432    }
    327433    if (opt & OPT_c) {
    328         struct bb_uidgid_t ugid;
     434        struct bb_uidgid_t ugid = { -1, -1 };
    329435        parse_chown_usergroup_or_die(&ugid, chuid);
    330436        if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid);
     
    340446    }
    341447#endif
    342     execv(startas, argv);
    343     bb_perror_msg_and_die("cannot start %s", startas);
    344 }
     448    execvp(startas, argv);
     449    bb_perror_msg_and_die("can't execute '%s'", startas);
     450}
  • branches/2.2.9/mindi-busybox/debianutils/which.c

    r1765 r2725  
    66 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
    77 *
    8  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 *
    1010 * Based on which from debianutils
     
    1313#include "libbb.h"
    1414
    15 int which_main(int argc, char **argv);
    16 int which_main(int argc, char **argv)
     15int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     16int which_main(int argc UNUSED_PARAM, char **argv)
    1717{
     18    IF_DESKTOP(int opt;)
    1819    int status = EXIT_SUCCESS;
     20    char *path;
    1921    char *p;
    2022
    21     if (argc <= 1 || argv[1][0] == '-') {
    22         bb_show_usage();
     23    opt_complementary = "-1"; /* at least one argument */
     24    IF_DESKTOP(opt =) getopt32(argv, "a");
     25    argv += optind;
     26
     27    /* This matches what is seen on e.g. ubuntu.
     28     * "which" there is a shell script. */
     29    path = getenv("PATH");
     30    if (!path) {
     31        path = (char*)bb_PATH_root_path;
     32        putenv(path);
     33        path += 5; /* skip "PATH=" */
    2334    }
    2435
    25 /* We shouldn't do this. Ever. Not our business.
    26     if (!getenv("PATH")) {
    27         putenv((char*)bb_PATH_root_path);
    28     }
    29 */
     36    do {
     37#if ENABLE_DESKTOP
     38/* Much bloat just to support -a */
     39        if (strchr(*argv, '/')) {
     40            if (execable_file(*argv)) {
     41                puts(*argv);
     42                continue;
     43            }
     44            status = EXIT_FAILURE;
     45        } else {
     46            char *path2 = xstrdup(path);
     47            char *tmp = path2;
    3048
    31     while (--argc > 0) {
    32         argv++;
     49            p = find_execable(*argv, &tmp);
     50            if (!p)
     51                status = EXIT_FAILURE;
     52            else {
     53 print:
     54                puts(p);
     55                free(p);
     56                if (opt) {
     57                    /* -a: show matches in all PATH components */
     58                    if (tmp) {
     59                        p = find_execable(*argv, &tmp);
     60                        if (p)
     61                            goto print;
     62                    }
     63                }
     64            }
     65            free(path2);
     66        }
     67#else
     68/* Just ignoring -a */
    3369        if (strchr(*argv, '/')) {
    3470            if (execable_file(*argv)) {
     
    3773            }
    3874        } else {
    39             p = find_execable(*argv);
     75            char *path2 = xstrdup(path);
     76            char *tmp = path2;
     77            p = find_execable(*argv, &tmp);
     78            free(path2);
    4079            if (p) {
    4180                puts(p);
     
    4584        }
    4685        status = EXIT_FAILURE;
    47     }
     86#endif
     87    } while (*(++argv) != NULL);
    4888
    4989    fflush_stdout_and_exit(status);
Note: See TracChangeset for help on using the changeset viewer.