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


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

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

Location:
branches/3.3
Files:
4 added
1 deleted
29 edited
1 copied

Legend:

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

    r3232 r3621  
    133133      manipulate real-time attributes of a process.
    134134      This requires sched_{g,s}etparam support in your libc.
    135 
    136 config CROND
    137     bool "crond"
    138     default y
    139     select FEATURE_SYSLOG
    140     help
    141       Crond is a background daemon that parses individual crontab
    142       files and executes commands on behalf of the users in question.
    143       This is a port of dcron from slackware. It uses files of the
    144       format /var/spool/cron/crontabs/<username> files, for example:
    145           $ cat /var/spool/cron/crontabs/root
    146           # Run daily cron jobs at 4:40 every day:
    147           40 4 * * * /etc/cron/daily > /dev/null 2>&1
    148 
    149 config FEATURE_CROND_D
    150     bool "Support option -d to redirect output to stderr"
    151     depends on CROND
    152     default y
    153     help
    154       -d sets loglevel to 0 (most verbose) and directs all output to stderr.
    155 
    156 config FEATURE_CROND_CALL_SENDMAIL
    157     bool "Report command output via email (using sendmail)"
    158     default y
    159     depends on CROND
    160     help
    161       Command output will be sent to corresponding user via email.
    162 
    163 config FEATURE_CROND_DIR
    164     string "crond spool directory"
    165     default "/var/spool/cron"
    166     depends on CROND || CRONTAB
    167     help
    168       Location of crond spool.
    169135
    170136config CRONTAB
     
    343309      'last' displays a list of the last users that logged into the system.
    344310
    345 choice
    346     prompt "Choose last implementation"
     311config FEATURE_LAST_FANCY
     312    bool "Turn on output of extra information"
     313    default y
    347314    depends on LAST
    348     default FEATURE_LAST_FANCY
    349 
    350 config FEATURE_LAST_SMALL
    351     bool "small"
    352     help
    353       This is a small version of last with just the basic set of
    354       features.
    355 
    356 config FEATURE_LAST_FANCY
    357     bool "huge"
    358315    help
    359316      'last' displays detailed information about the last users that
    360317      logged into the system (mimics sysvinit last). +900 bytes.
    361 endchoice
    362318
    363319config HDPARM
     
    504460      run this applet as a background job.
    505461
    506 config RFKILL
    507     bool "rfkill"
    508     default n  # doesn't build on Ubuntu 9.04
    509     select PLATFORM_LINUX
    510     help
    511       Enable/disable wireless devices.
    512 
    513       rfkill list : list all wireless devices
    514       rfkill list bluetooth : list all bluetooth devices
    515       rfkill list 1 : list device corresponding to the given index
    516       rfkill block|unblock wlan : block/unblock all wlan(wifi) devices
    517 
    518462config RUNLEVEL
    519463    bool "runlevel"
     
    545489      strings prints the printable character sequences for each file
    546490      specified.
    547 
    548 config TASKSET
    549     bool "taskset"
    550     default n  # doesn't build on some non-x86 targets (m68k)
    551     help
    552       Retrieve or set a processes's CPU affinity.
    553       This requires sched_{g,s}etaffinity support in your libc.
    554 
    555 config FEATURE_TASKSET_FANCY
    556     bool "Fancy output"
    557     default y
    558     depends on TASKSET
    559     help
    560       Add code for fancy output. This merely silences a compiler-warning
    561       and adds about 135 Bytes. May be needed for machines with alot
    562       of CPUs.
    563491
    564492config TIME
     
    591519    help
    592520      Prints a CD-ROM volume name.
    593 
    594 config WALL
    595     bool "wall"
    596     default y
    597     depends on FEATURE_UTMP
    598     help
    599       Write a message to all users that are logged in.
    600521
    601522config WATCHDOG
  • branches/3.3/mindi-busybox/miscutils/Kbuild.src

    r2725 r3621  
    1313lib-$(CONFIG_CHAT)        += chat.o
    1414lib-$(CONFIG_CHRT)        += chrt.o
    15 lib-$(CONFIG_CROND)       += crond.o
    1615lib-$(CONFIG_CRONTAB)     += crontab.o
    1716lib-$(CONFIG_DC)          += dc.o
     
    2726lib-$(CONFIG_HDPARM)      += hdparm.o
    2827lib-$(CONFIG_INOTIFYD)    += inotifyd.o
    29 lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o
    30 lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o
     28
     29ifeq ($(CONFIG_FEATURE_LAST_FANCY),y)
     30lib-$(CONFIG_FEATURE_LAST_FANCY) += last_fancy.o
     31else
     32lib-$(CONFIG_LAST)        += last.o
     33endif
     34
    3135lib-$(CONFIG_LESS)        += less.o
    3236lib-$(CONFIG_MAKEDEVS)    += makedevs.o
     
    3741lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o
    3842lib-$(CONFIG_READAHEAD)   += readahead.o
    39 lib-$(CONFIG_RFKILL)      += rfkill.o
    4043lib-$(CONFIG_RUNLEVEL)    += runlevel.o
    4144lib-$(CONFIG_RX)          += rx.o
    4245lib-$(CONFIG_SETSID)      += setsid.o
    4346lib-$(CONFIG_STRINGS)     += strings.o
    44 lib-$(CONFIG_TASKSET)     += taskset.o
    4547lib-$(CONFIG_TIME)        += time.o
    4648lib-$(CONFIG_TIMEOUT)     += timeout.o
    4749lib-$(CONFIG_TTYSIZE)     += ttysize.o
    4850lib-$(CONFIG_VOLNAME)     += volname.o
    49 lib-$(CONFIG_WALL)        += wall.o
    5051lib-$(CONFIG_WATCHDOG)    += watchdog.o
  • branches/3.3/mindi-busybox/miscutils/adjtimex.c

    r3232 r3621  
    1515//usage:       "[-q] [-o OFF] [-f FREQ] [-p TCONST] [-t TICK]"
    1616//usage:#define adjtimex_full_usage "\n\n"
    17 //usage:       "Read and optionally set system timebase parameters. See adjtimex(2)\n"
     17//usage:       "Read or set kernel time variables. See adjtimex(2)\n"
    1818//usage:     "\n    -q  Quiet"
    1919//usage:     "\n    -o OFF  Time offset, microseconds"
    2020//usage:     "\n    -f FREQ Frequency adjust, integer kernel units (65536 is 1ppm)"
    21 //usage:     "\n        (positive values make clock run faster)"
    2221//usage:     "\n    -t TICK Microseconds per tick, usually 10000"
     22//usage:     "\n        (positive -t or -f values make clock run faster)"
    2323//usage:     "\n    -p TCONST"
    2424
     
    3030#endif
    3131
    32 static const uint16_t statlist_bit[] = {
     32static const uint16_t statlist_bit[] ALIGN2 = {
    3333    STA_PLL,
    3434    STA_PPSFREQ,
     
    4646    0
    4747};
    48 static const char statlist_name[] =
     48static const char statlist_name[] ALIGN1 =
    4949    "PLL"       "\0"
    5050    "PPSFREQ"   "\0"
     
    6262;
    6363
    64 static const char ret_code_descript[] =
     64static const char ret_code_descript[] ALIGN1 =
    6565    "clock synchronized" "\0"
    6666    "insert leap second" "\0"
     
    112112
    113113    if (!(opt & OPT_quiet)) {
    114         int sep;
     114        const char *sep;
    115115        const char *name;
    116116
    117117        printf(
    118118            "    mode:         %d\n"
    119             "-o  offset:       %ld\n"
    120             "-f  frequency:    %ld\n"
     119            "-o  offset:       %ld us\n"
     120            "-f  freq.adjust:  %ld (65536 = 1ppm)\n"
    121121            "    maxerror:     %ld\n"
    122122            "    esterror:     %ld\n"
     
    126126
    127127        /* representative output of next code fragment:
    128            "PLL | PPSTIME" */
     128         * "PLL | PPSTIME"
     129         */
    129130        name = statlist_name;
    130         sep = 0;
     131        sep = "";
    131132        for (i = 0; statlist_bit[i]; i++) {
    132133            if (txc.status & statlist_bit[i]) {
    133                 if (sep)
    134                     fputs(" | ", stdout);
    135                 fputs(name, stdout);
    136                 sep = 1;
     134                printf("%s%s", sep, name);
     135                sep = " | ";
    137136            }
    138137            name += strlen(name) + 1;
     
    144143        printf(")\n"
    145144            "-p  timeconstant: %ld\n"
    146             "    precision:    %ld\n"
     145            "    precision:    %ld us\n"
    147146            "    tolerance:    %ld\n"
    148             "-t  tick:         %ld\n"
     147            "-t  tick:         %ld us\n"
    149148            "    time.tv_sec:  %ld\n"
    150149            "    time.tv_usec: %ld\n"
  • branches/3.3/mindi-busybox/miscutils/beep.c

    r3232 r3621  
    8989        }
    9090        while (rep) {
    91 //bb_info_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay);
     91//bb_error_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay);
    9292            xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq);
    9393            usleep(1000 * length);
  • branches/3.3/mindi-busybox/miscutils/chat.c

    r3232 r3621  
    1818
    1919#include "libbb.h"
     20#include "common_bufsiz.h"
    2021
    2122// default timeout: 45 sec
     
    286287                && (pfd.revents & POLLIN)
    287288            ) {
    288 #define buf bb_common_bufsiz1
    289289                llist_t *l;
    290290                ssize_t delta;
     291#define buf bb_common_bufsiz1
     292                setup_common_bufsiz();
    291293
    292294                // read next char from device
     
    297299                    }
    298300                    // dump device input if ECHO ON
    299                     if (echo > 0) {
     301                    if (echo) {
    300302//                      if (buf[buf_len] < ' ') {
    301303//                          full_write(STDERR_FILENO, "^", 1);
  • branches/3.3/mindi-busybox/miscutils/chrt.c

    r3232 r3621  
    2424#include <sched.h>
    2525#include "libbb.h"
    26 #ifndef _POSIX_PRIORITY_SCHEDULING
    27 #warning your system may be foobared
    28 #endif
    2926
    3027static const struct {
  • branches/3.3/mindi-busybox/miscutils/conspy.c

    r3232 r3621  
    4343
    4444#include "libbb.h"
     45#include "common_bufsiz.h"
    4546#include <sys/kd.h>
    4647
     
    364365{
    365366    char tty_name[sizeof(DEV_TTY "NN")];
    366 #define keybuf bb_common_bufsiz1
    367367    struct termios termbuf;
    368368    unsigned opts;
     
    383383    applet_long_options = getopt_longopts;
    384384#endif
     385#define keybuf bb_common_bufsiz1
     386    setup_common_bufsiz();
     387
    385388    INIT_G();
    386389    strcpy(G.vcsa_name, DEV_VCSA);
     
    514517            // Read the keys pressed
    515518            k = keybuf + G.key_count;
    516             bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count);
     519            bytes_read = read(G.kbd_fd, k, COMMON_BUFSIZE - G.key_count);
    517520            if (bytes_read < 0)
    518521                goto abort;
  • branches/3.3/mindi-busybox/miscutils/crond.c

    r3232 r3621  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * crond -d[#] -c <crondir> -f -b
    4  *
    53 * run as root, but NOT setuid root
    64 *
     
    119 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1210 */
     11//config:config CROND
     12//config:   bool "crond"
     13//config:   default y
     14//config:   select FEATURE_SYSLOG
     15//config:   help
     16//config:     Crond is a background daemon that parses individual crontab
     17//config:     files and executes commands on behalf of the users in question.
     18//config:     This is a port of dcron from slackware. It uses files of the
     19//config:     format /var/spool/cron/crontabs/<username> files, for example:
     20//config:         $ cat /var/spool/cron/crontabs/root
     21//config:         # Run daily cron jobs at 4:40 every day:
     22//config:         40 4 * * * /etc/cron/daily > /dev/null 2>&1
     23//config:
     24//config:config FEATURE_CROND_D
     25//config:   bool "Support option -d to redirect output to stderr"
     26//config:   depends on CROND
     27//config:   default y
     28//config:   help
     29//config:     -d N sets loglevel (0:most verbose) and directs all output to stderr.
     30//config:
     31//config:config FEATURE_CROND_CALL_SENDMAIL
     32//config:   bool "Report command output via email (using sendmail)"
     33//config:   default y
     34//config:   depends on CROND
     35//config:   help
     36//config:     Command output will be sent to corresponding user via email.
     37//config:
     38//config:config FEATURE_CROND_DIR
     39//config:   string "crond spool directory"
     40//config:   default "/var/spool/cron"
     41//config:   depends on CROND || CRONTAB
     42//config:   help
     43//config:     Location of crond spool.
     44
     45//applet:IF_CROND(APPLET(crond, BB_DIR_USR_SBIN, BB_SUID_DROP))
     46
     47//kbuild:lib-$(CONFIG_CROND) += crond.o
    1348
    1449//usage:#define crond_trivial_usage
     
    1853//usage:     "\n    -b  Background (default)"
    1954//usage:     "\n    -S  Log to syslog (default)"
    20 //usage:     "\n    -l  Set log level. 0 is the most verbose, default 8"
     55//usage:     "\n    -l N    Set log level. Most verbose:0, default:8"
    2156//usage:    IF_FEATURE_CROND_D(
    22 //usage:     "\n    -d  Set log level, log to stderr"
     57//usage:     "\n    -d N    Set log level, log to stderr"
    2358//usage:    )
    24 //usage:     "\n    -L  Log to file"
    25 //usage:     "\n    -c  Working dir"
     59//usage:     "\n    -L FILE Log to FILE"
     60//usage:     "\n    -c DIR  Cron dir. Default:"CONFIG_FEATURE_CROND_DIR"/crontabs"
    2661
    2762#include "libbb.h"
     63#include "common_bufsiz.h"
    2864#include <syslog.h>
    2965
     
    3773
    3874
    39 #define TMPDIR          CONFIG_FEATURE_CROND_DIR
     75#define CRON_DIR        CONFIG_FEATURE_CROND_DIR
    4076#define CRONTABS        CONFIG_FEATURE_CROND_DIR "/crontabs"
    4177#ifndef SENDMAIL
     
    70106    char *cl_mailto;                /* whom to mail results, may be NULL */
    71107#endif
     108    char *cl_shell;
    72109    /* ordered by size, not in natural order. makes code smaller: */
    73110    char cl_Dow[7];                 /* 0-6, beginning sunday */
     
    91128    OPT_d = (1 << 6) * ENABLE_FEATURE_CROND_D,
    92129};
    93 #if ENABLE_FEATURE_CROND_D
    94 # define DebugOpt (option_mask32 & OPT_d)
    95 #else
    96 # define DebugOpt 0
    97 #endif
    98 
    99130
    100131struct globals {
     
    107138    char *env_var_user;
    108139    char *env_var_home;
     140    char *env_var_shell;
     141    char *env_var_logname;
    109142#endif
    110143} FIX_ALIASING;
    111 #define G (*(struct globals*)&bb_common_bufsiz1)
     144#define G (*(struct globals*)bb_common_bufsiz1)
    112145#define INIT_G() do { \
     146    setup_common_bufsiz(); \
    113147    G.log_level = 8; \
    114148    G.crontab_dir_name = CRONTABS; \
    115149} while (0)
    116150
    117 
    118 /* 0 is the most verbose, default 8 */
    119 #define LVL5  "\x05"
    120 #define LVL7  "\x07"
    121 #define LVL8  "\x08"
    122 #define WARN9 "\x49"
    123 #define DIE9  "\xc9"
    124 /* level >= 20 is "error" */
    125 #define ERR20 "\x14"
    126 
    127 static void crondlog(const char *ctl, ...) __attribute__ ((format (printf, 1, 2)));
    128 static void crondlog(const char *ctl, ...)
     151/* Log levels:
     152 * 0 is the most verbose, default 8.
     153 * For some reason, in fact only 5, 7 and 8 are used.
     154 */
     155static void crondlog(unsigned level, const char *msg, va_list va)
     156{
     157    if (level >= G.log_level) {
     158        /*
     159         * We are called only for info meesages.
     160         * Warnings/errors use plain bb_[p]error_msg's, which
     161         * need not touch syslog_level
     162         * (they are ok with LOG_ERR default).
     163         */
     164        syslog_level = LOG_INFO;
     165        bb_verror_msg(msg, va, /* strerr: */ NULL);
     166        syslog_level = LOG_ERR;
     167    }
     168}
     169
     170static void log5(const char *msg, ...)
    129171{
    130172    va_list va;
    131     int level = (ctl[0] & 0x1f);
    132 
    133     va_start(va, ctl);
    134     if (level >= (int)G.log_level) {
    135         /* Debug mode: all to (non-redirected) stderr, */
    136         /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */
    137         if (!DebugOpt && G.log_filename) {
    138             /* Otherwise (log to file): we reopen log file at every write: */
    139             int logfd = open_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND);
    140             if (logfd >= 0)
    141                 xmove_fd(logfd, STDERR_FILENO);
    142         }
    143         /* When we log to syslog, level > 8 is logged at LOG_ERR
    144          * syslog level, level <= 8 is logged at LOG_INFO. */
    145         if (level > 8) {
    146             bb_verror_msg(ctl + 1, va, /* strerr: */ NULL);
    147         } else {
    148             char *msg = NULL;
    149             vasprintf(&msg, ctl + 1, va);
    150             bb_info_msg("%s: %s", applet_name, msg);
    151             free(msg);
    152         }
    153     }
     173    va_start(va, msg);
     174    crondlog(4, msg, va);
    154175    va_end(va);
    155     if (ctl[0] & 0x80)
    156         exit(20);
    157 }
     176}
     177
     178static void log7(const char *msg, ...)
     179{
     180    va_list va;
     181    va_start(va, msg);
     182    crondlog(7, msg, va);
     183    va_end(va);
     184}
     185
     186static void log8(const char *msg, ...)
     187{
     188    va_list va;
     189    va_start(va, msg);
     190    crondlog(8, msg, va);
     191    va_end(va);
     192}
     193
    158194
    159195static const char DowAry[] ALIGN1 =
    160196    "sun""mon""tue""wed""thu""fri""sat"
    161     /* "Sun""Mon""Tue""Wed""Thu""Fri""Sat" */
    162197;
    163198
    164199static const char MonAry[] ALIGN1 =
    165200    "jan""feb""mar""apr""may""jun""jul""aug""sep""oct""nov""dec"
    166     /* "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" */
    167201;
    168202
     
    268302    if (*ptr) {
    269303 err:
    270         crondlog(WARN9 "user %s: parse error at %s", user, base);
     304        bb_error_msg("user %s: parse error at %s", user, base);
    271305        return;
    272306    }
    273307
    274     if (DebugOpt && (G.log_level <= 5)) { /* like LVL5 */
    275         /* can't use crondlog, it inserts '\n' */
     308    /* can't use log5 (it inserts newlines), open-coding it */
     309    if (G.log_level <= 5 && logmode != LOGMODE_SYSLOG) {
    276310        int i;
    277311        for (i = 0; i < modvalue; ++i)
     
    369403    char *mailTo = NULL;
    370404#endif
     405    char *shell = NULL;
    371406
    372407    delete_cronfile(fileName);
    373408
    374409    if (!getpwnam(fileName)) {
    375         crondlog(LVL7 "ignoring file '%s' (no such user)", fileName);
     410        log7("ignoring file '%s' (no such user)", fileName);
    376411        return;
    377412    }
     
    394429            CronLine *line;
    395430
    396             if (!--maxLines)
     431            if (!--maxLines) {
     432                bb_error_msg("user %s: too many lines", fileName);
    397433                break;
     434            }
     435
    398436            n = config_read(parser, tokens, 6, 1, "# \t", PARSE_NORMAL | PARSE_KEEP_COPY);
    399437            if (!n)
    400438                break;
    401439
    402             if (DebugOpt)
    403                 crondlog(LVL5 "user:%s entry:%s", fileName, parser->data);
     440            log5("user:%s entry:%s", fileName, parser->data);
    404441
    405442            /* check if line is setting MAILTO= */
    406             if (0 == strncmp(tokens[0], "MAILTO=", 7)) {
     443            if (is_prefixed_with(tokens[0], "MAILTO=")) {
    407444#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
    408445                free(mailTo);
     
    411448                continue;
    412449            }
     450            if (is_prefixed_with(tokens[0], "SHELL=")) {
     451                free(shell);
     452                shell = xstrdup(&tokens[0][6]);
     453                continue;
     454            }
     455//TODO: handle HOME= too? "man crontab" says:
     456//name = value
     457//
     458//where the spaces around the equal-sign (=) are optional, and any subsequent
     459//non-leading spaces in value will be part of the value assigned to name.
     460//The value string may be placed in quotes (single or double, but matching)
     461//to preserve leading or trailing blanks.
     462//
     463//Several environment variables are set up automatically by the cron(8) daemon.
     464//SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd
     465//line of the crontab's owner. HOME and SHELL may be overridden by settings
     466//in the crontab; LOGNAME may not.
     467
    413468            /* check if a minimum of tokens is specified */
    414469            if (n < 6)
     
    430485            line->cl_mailto = xstrdup(mailTo);
    431486#endif
     487            line->cl_shell = xstrdup(shell);
    432488            /* copy command */
    433489            line->cl_cmd = xstrdup(tokens[5]);
    434             if (DebugOpt) {
    435                 crondlog(LVL5 " command:%s", tokens[5]);
    436             }
    437490            pline = &line->cl_next;
    438491//bb_error_msg("M[%s]F[%s][%s][%s][%s][%s][%s]", mailTo, tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]);
     
    442495        file->cf_next = G.cron_files;
    443496        G.cron_files = file;
    444 
    445         if (maxLines == 0) {
    446             crondlog(WARN9 "user %s: too many lines", fileName);
    447         }
    448497    }
    449498    config_close(parser);
     499#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
     500    free(mailTo);
     501#endif
     502    free(shell);
    450503}
    451504
     
    483536    unlink(CRONUPDATE);
    484537    /* Re-chdir, in case directory was renamed & deleted */
    485     if (chdir(G.crontab_dir_name) < 0) {
    486         crondlog(DIE9 "chdir(%s)", G.crontab_dir_name);
    487     }
     538    xchdir(G.crontab_dir_name);
    488539
    489540    /* Scan directory and add associated users */
     
    492543        struct dirent *den;
    493544
     545        /* xopendir exists, but "can't open '.'" is not informative */
    494546        if (!dir)
    495             crondlog(DIE9 "chdir(%s)", "."); /* exits */
     547            bb_error_msg_and_die("can't open '%s'", G.crontab_dir_name);
    496548        while ((den = readdir(dir)) != NULL) {
    497549            if (strchr(den->d_name, '.') != NULL) {
     
    520572#endif
    521573
    522 static void set_env_vars(struct passwd *pas)
    523 {
     574static void set_env_vars(struct passwd *pas, const char *shell)
     575{
     576    /* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL.
     577     * We assume crond inherited suitable PATH.
     578     */
    524579#if SETENV_LEAKS
     580    safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name);
    525581    safe_setenv(&G.env_var_user, "USER", pas->pw_name);
    526582    safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
    527     /* if we want to set user's shell instead: */
    528     /*safe_setenv(G.env_var_shell, "SHELL", pas->pw_shell);*/
     583    safe_setenv(&G.env_var_shell, "SHELL", shell);
    529584#else
     585    xsetenv("LOGNAME", pas->pw_name);
    530586    xsetenv("USER", pas->pw_name);
    531587    xsetenv("HOME", pas->pw_dir);
    532 #endif
    533     /* currently, we use constant one: */
    534     /*setenv("SHELL", DEFAULT_SHELL, 1); - done earlier */
     588    xsetenv("SHELL", shell);
     589#endif
    535590}
    536591
     
    540595    change_identity(pas); /* - initgroups, setgid, setuid */
    541596    if (chdir(pas->pw_dir) < 0) {
    542         crondlog(WARN9 "chdir(%s)", pas->pw_dir);
    543         if (chdir(TMPDIR) < 0) {
    544             crondlog(DIE9 "chdir(%s)", TMPDIR); /* exits */
    545         }
     597        bb_error_msg("can't change directory to '%s'", pas->pw_dir);
     598        xchdir(CRON_DIR);
    546599    }
    547600}
     
    551604
    552605static pid_t
    553 fork_job(const char *user, int mailFd,
    554         const char *prog,
    555         const char *shell_cmd /* if NULL, we run sendmail */
    556 ) {
     606fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail)
     607{
    557608    struct passwd *pas;
     609    const char *shell, *prog;
     610    smallint sv_logmode;
    558611    pid_t pid;
    559612
     
    561614    pas = getpwnam(user);
    562615    if (!pas) {
    563         crondlog(WARN9 "can't get uid for %s", user);
     616        bb_error_msg("can't get uid for %s", user);
    564617        goto err;
    565618    }
    566     set_env_vars(pas);
    567 
     619
     620    shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL;
     621    prog = run_sendmail ? SENDMAIL : shell;
     622
     623    set_env_vars(pas, shell);
     624
     625    sv_logmode = logmode;
    568626    pid = vfork();
    569627    if (pid == 0) {
    570628        /* CHILD */
    571         /* initgroups, setgid, setuid, and chdir to home or TMPDIR */
     629        /* initgroups, setgid, setuid, and chdir to home or CRON_DIR */
    572630        change_user(pas);
    573         if (DebugOpt) {
    574             crondlog(LVL5 "child running %s", prog);
    575         }
     631        log5("child running %s", prog);
    576632        if (mailFd >= 0) {
    577             xmove_fd(mailFd, shell_cmd ? 1 : 0);
     633            xmove_fd(mailFd, run_sendmail ? 0 : 1);
    578634            dup2(1, 2);
    579635        }
    580636        /* crond 3.0pl1-100 puts tasks in separate process groups */
    581637        bb_setpgrp();
    582         execlp(prog, prog, (shell_cmd ? "-c" : SENDMAIL_ARGS), shell_cmd, (char *) NULL);
    583         crondlog(ERR20 "can't execute '%s' for user %s", prog, user);
    584         if (shell_cmd) {
    585             fdprintf(1, "Exec failed: %s -c %s\n", prog, shell_cmd);
    586         }
    587         _exit(EXIT_SUCCESS);
    588     }
     638        if (!run_sendmail)
     639            execlp(prog, prog, "-c", line->cl_cmd, (char *) NULL);
     640        else
     641            execlp(prog, prog, SENDMAIL_ARGS, (char *) NULL);
     642        /*
     643         * I want this error message on stderr too,
     644         * even if other messages go only to syslog:
     645         */
     646        logmode |= LOGMODE_STDIO;
     647        bb_error_msg_and_die("can't execute '%s' for user %s", prog, user);
     648    }
     649    logmode = sv_logmode;
    589650
    590651    if (pid < 0) {
    591         /* FORK FAILED */
    592         crondlog(ERR20 "can't vfork");
     652        bb_perror_msg("vfork");
    593653 err:
    594654        pid = 0;
     
    615675    if (line->cl_mailto) {
    616676        /* Open mail file (owner is root so nobody can screw with it) */
    617         snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid());
     677        snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", CRON_DIR, user, getpid());
    618678        mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600);
    619679
     
    623683            line->cl_empty_mail_size = lseek(mailFd, 0, SEEK_CUR);
    624684        } else {
    625             crondlog(ERR20 "can't create mail file %s for user %s, "
     685            bb_error_msg("can't create mail file %s for user %s, "
    626686                    "discarding output", mailFile, user);
    627687        }
    628688    }
    629689
    630     line->cl_pid = fork_job(user, mailFd, DEFAULT_SHELL, line->cl_cmd);
     690    line->cl_pid = fork_job(user, mailFd, line, /*sendmail?*/ 0);
    631691    if (mailFd >= 0) {
    632692        if (line->cl_pid <= 0) {
     
    634694        } else {
    635695            /* rename mail-file based on pid of process */
    636             char *mailFile2 = xasprintf("%s/cron.%s.%d", TMPDIR, user, (int)line->cl_pid);
     696            char *mailFile2 = xasprintf("%s/cron.%s.%d", CRON_DIR, user, (int)line->cl_pid);
    637697            rename(mailFile, mailFile2); // TODO: xrename?
    638698            free(mailFile2);
     
    666726     * If size has changed and the file is still valid, we send it.
    667727     */
    668     snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, (int)pid);
     728    snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", CRON_DIR, user, (int)pid);
    669729    mailFd = open(mailFile, O_RDONLY);
    670730    unlink(mailFile);
     
    684744    line->cl_empty_mail_size = 0;
    685745    /* if (line->cl_mailto) - always true if cl_empty_mail_size was nonzero */
    686         line->cl_pid = fork_job(user, mailFd, SENDMAIL, NULL);
     746        line->cl_pid = fork_job(user, mailFd, line, /*sendmail?*/ 1);
    687747}
    688748
     
    691751static void start_one_job(const char *user, CronLine *line)
    692752{
     753    const char *shell;
    693754    struct passwd *pas;
    694755    pid_t pid;
     
    696757    pas = getpwnam(user);
    697758    if (!pas) {
    698         crondlog(WARN9 "can't get uid for %s", user);
     759        bb_error_msg("can't get uid for %s", user);
    699760        goto err;
    700761    }
    701762
    702763    /* Prepare things before vfork */
    703     set_env_vars(pas);
     764    shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL;
     765    set_env_vars(pas, shell);
    704766
    705767    /* Fork as the user in question and run program */
     
    707769    if (pid == 0) {
    708770        /* CHILD */
    709         /* initgroups, setgid, setuid, and chdir to home or TMPDIR */
     771        /* initgroups, setgid, setuid, and chdir to home or CRON_DIR */
    710772        change_user(pas);
    711         if (DebugOpt) {
    712             crondlog(LVL5 "child running %s", DEFAULT_SHELL);
    713         }
     773        log5("child running %s", shell);
    714774        /* crond 3.0pl1-100 puts tasks in separate process groups */
    715775        bb_setpgrp();
    716         execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", line->cl_cmd, (char *) NULL);
    717         crondlog(ERR20 "can't execute '%s' for user %s", DEFAULT_SHELL, user);
    718         _exit(EXIT_SUCCESS);
     776        execl(shell, shell, "-c", line->cl_cmd, (char *) NULL);
     777        bb_error_msg_and_die("can't execute '%s' for user %s", shell, user);
    719778    }
    720779    if (pid < 0) {
    721         /* FORK FAILED */
    722         crondlog(ERR20 "can't vfork");
     780        bb_perror_msg("vfork");
    723781 err:
    724782        pid = 0;
     
    752810        ptm = localtime(&t);
    753811        for (file = G.cron_files; file; file = file->cf_next) {
    754             if (DebugOpt)
    755                 crondlog(LVL5 "file %s:", file->cf_username);
     812            log5("file %s:", file->cf_username);
    756813            if (file->cf_deleted)
    757814                continue;
    758815            for (line = file->cf_lines; line; line = line->cl_next) {
    759                 if (DebugOpt)
    760                     crondlog(LVL5 " line %s", line->cl_cmd);
     816                log5(" line %s", line->cl_cmd);
    761817                if (line->cl_Mins[ptm->tm_min]
    762818                 && line->cl_Hrs[ptm->tm_hour]
     
    764820                 && line->cl_Mons[ptm->tm_mon]
    765821                ) {
    766                     if (DebugOpt) {
    767                         crondlog(LVL5 " job: %d %s",
     822                    log5(" job: %d %s",
    768823                            (int)line->cl_pid, line->cl_cmd);
    769                     }
    770824                    if (line->cl_pid > 0) {
    771                         crondlog(LVL8 "user %s: process already running: %s",
     825                        log8("user %s: process already running: %s",
    772826                            file->cf_username, line->cl_cmd);
    773827                    } else if (line->cl_pid == 0) {
     
    798852            start_one_job(file->cf_username, line);
    799853            pid = line->cl_pid;
    800             crondlog(LVL8 "USER %s pid %3d cmd %s",
     854            log8("USER %s pid %3d cmd %s",
    801855                file->cf_username, (int)pid, line->cl_cmd);
    802856            if (pid < 0) {
     
    850904}
    851905
     906static void reopen_logfile_to_stderr(void)
     907{
     908    if (G.log_filename) {
     909        int logfd = open_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND);
     910        if (logfd >= 0)
     911            xmove_fd(logfd, STDERR_FILENO);
     912    }
     913}
     914
    852915int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    853916int crond_main(int argc UNUSED_PARAM, char **argv)
    854917{
    855918    time_t t2;
    856     int rescan;
    857     int sleep_time;
     919    unsigned rescan;
     920    unsigned sleep_time;
    858921    unsigned opts;
    859922
     
    881944    }
    882945
     946    //signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */
     947
     948    reopen_logfile_to_stderr();
    883949    xchdir(G.crontab_dir_name);
    884     //signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */
    885     xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */
    886     crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", G.log_level);
     950    log8("crond (busybox "BB_VER") started, log level %d", G.log_level);
    887951    rescan_crontab_dir();
    888952    write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid");
     
    897961        long dt;
    898962
     963        /* Synchronize to 1 minute, minimum 1 second */
    899964        t1 = t2;
    900 
    901         /* Synchronize to 1 minute, minimum 1 second */
    902         sleep(sleep_time - (time(NULL) % sleep_time) + 1);
    903 
     965        sleep(sleep_time - (time(NULL) % sleep_time));
    904966        t2 = time(NULL);
    905967        dt = (long)t2 - (long)t1;
     968
     969        reopen_logfile_to_stderr();
    906970
    907971        /*
     
    932996        }
    933997        process_cron_update_file();
    934         if (DebugOpt)
    935             crondlog(LVL5 "wakeup dt=%ld", dt);
     998        log5("wakeup dt=%ld", dt);
    936999        if (dt < -60 * 60 || dt > 60 * 60) {
    937             crondlog(WARN9 "time disparity of %ld minutes detected", dt / 60);
     1000            bb_error_msg("time disparity of %ld minutes detected", dt / 60);
    9381001            /* and we do not run any jobs in this case */
    9391002        } else if (dt > 0) {
     
    9411004            flag_starting_jobs(t1, t2);
    9421005            start_jobs();
     1006            sleep_time = 60;
    9431007            if (check_completions() > 0) {
    9441008                /* some jobs are still running */
    9451009                sleep_time = 10;
    946             } else {
    947                 sleep_time = 60;
    9481010            }
    9491011        }
  • branches/3.3/mindi-busybox/miscutils/crontab.c

    r3232 r3621  
    5454    BB_EXECLP(ptr, ptr, file, NULL);
    5555    bb_perror_msg_and_die("can't execute '%s'", ptr);
    56 }
    57 
    58 static int open_as_user(const struct passwd *pas, const char *file)
    59 {
    60     pid_t pid;
    61     char c;
    62 
    63     pid = xvfork();
    64     if (pid) { /* PARENT */
    65         if (wait4pid(pid) == 0) {
    66             /* exitcode 0: child says it can read */
    67             return open(file, O_RDONLY);
    68         }
    69         return -1;
    70     }
    71 
    72     /* CHILD */
    73     /* initgroups, setgid, setuid */
    74     change_identity(pas);
    75     /* We just try to read one byte. If it works, file is readable
    76      * under this user. We signal that by exiting with 0. */
    77     _exit(safe_read(xopen(file, O_RDONLY), &c, 1) < 0);
    7856}
    7957
     
    138116            bb_show_usage();
    139117        if (NOT_LONE_DASH(argv[0])) {
    140             src_fd = open_as_user(pas, argv[0]);
    141             if (src_fd < 0)
    142                 bb_error_msg_and_die("user %s cannot read %s",
    143                         pas->pw_name, argv[0]);
     118            src_fd = xopen_as_uid_gid(argv[0], O_RDONLY, pas->pw_uid, pas->pw_gid);
    144119        }
    145120    }
     
    196171        /*free(tmp_fname);*/
    197172        /*free(new_fname);*/
    198 
    199173    } /* switch */
    200174
  • branches/3.3/mindi-busybox/miscutils/dc.c

    r3232 r3621  
    55
    66#include "libbb.h"
     7#include "common_bufsiz.h"
    78#include <math.h>
    89
     
    4849} FIX_ALIASING;
    4950enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(double) };
    50 #define G (*(struct globals*)&bb_common_bufsiz1)
     51#define G (*(struct globals*)bb_common_bufsiz1)
    5152#define pointer   (G.pointer   )
    5253#define base      (G.base      )
    5354#define stack     (G.stack     )
    5455#define INIT_G() do { \
     56    setup_common_bufsiz(); \
    5557    base = 10; \
    5658} while (0)
    5759
     60
     61static void check_under(void)
     62{
     63    if (pointer == 0)
     64        bb_error_msg_and_die("stack underflow");
     65}
    5866
    5967static void push(double a)
     
    6674static double pop(void)
    6775{
    68     if (pointer == 0)
    69         bb_error_msg_and_die("stack underflow");
     76    check_under();
    7077    return stack[--pointer];
    7178}
     
    188195static void print_no_pop(void)
    189196{
     197    check_under();
    190198    print_base(stack[pointer-1]);
    191199}
     
    197205
    198206static const struct op operators[] = {
    199     {"+",   add},
    200     {"add", add},
    201     {"-",   sub},
    202     {"sub", sub},
    203     {"*",   mul},
    204     {"mul", mul},
    205     {"/",   divide},
    206     {"div", divide},
    207207#if ENABLE_FEATURE_DC_LIBM
    208208    {"**",  power},
     
    217217    {"eor", eor},
    218218    {"xor", eor},
     219    {"+",   add},
     220    {"add", add},
     221    {"-",   sub},
     222    {"sub", sub},
     223    {"*",   mul},
     224    {"mul", mul},
     225    {"/",   divide},
     226    {"div", divide},
    219227    {"p", print_no_pop},
    220228    {"f", print_stack_no_pop},
     
    222230};
    223231
     232/* Feed the stack machine */
    224233static void stack_machine(const char *argument)
    225234{
    226235    char *end;
    227     double d;
     236    double number;
    228237    const struct op *o;
    229238
    230     d = strtod(argument, &end);
    231     if (end != argument && *end == '\0') {
    232         push(d);
     239 next:
     240    number = strtod(argument, &end);
     241    if (end != argument) {
     242        argument = end;
     243        push(number);
     244        goto next;
     245    }
     246
     247    /* We might have matched a digit, eventually advance the argument */
     248    argument = skip_whitespace(argument);
     249
     250    if (*argument == '\0')
    233251        return;
    234     }
    235252
    236253    o = operators;
    237254    do {
    238         if (strcmp(o->name, argument) == 0) {
     255        char *after_name = is_prefixed_with(argument, o->name);
     256        if (after_name) {
     257            argument = after_name;
    239258            o->function();
    240             return;
     259            goto next;
    241260        }
    242261        o++;
     
    255274        /* take stuff from stdin if no args are given */
    256275        char *line;
    257         char *cursor;
    258         char *token;
    259276        while ((line = xmalloc_fgetline(stdin)) != NULL) {
    260             cursor = line;
    261             while (1) {
    262                 token = skip_whitespace(cursor);
    263                 if (*token == '\0')
    264                     break;
    265                 cursor = skip_non_whitespace(token);
    266                 if (*cursor != '\0')
    267                     *cursor++ = '\0';
    268                 stack_machine(token);
    269             }
     277            stack_machine(line);
    270278            free(line);
    271279        }
    272280    } else {
    273         // why? it breaks "dc -2 2 + p"
    274         //if (argv[0][0] == '-')
    275         //  bb_show_usage();
    276281        do {
    277282            stack_machine(*argv);
  • branches/3.3/mindi-busybox/miscutils/devfsd.c

    r3232 r3621  
    285285/* Busybox stuff */
    286286#if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG
    287 #define info_logger(p, fmt, args...)                 bb_info_msg(fmt, ## args)
     287#define info_logger(p, fmt, args...)                 bb_error_msg(fmt, ## args)
    288288#define msg_logger(p, fmt, args...)                  bb_error_msg(fmt, ## args)
    289289#define msg_logger_and_die(p, fmt, args...)          bb_error_msg_and_die(fmt, ## args)
     
    10841084    struct passwd *pw_ent;
    10851085    struct group *grp_ent;
    1086     static const char *msg;
     1086    const char *msg;
     1087
     1088    if (isdigit(string[0]) || ((string[0] == '-') && isdigit(string[1])))
     1089        return atoi(string);
     1090
     1091    if (flag == UID && (pw_ent = getpwnam(string)) != NULL)
     1092        return pw_ent->pw_uid;
    10871093
    10881094    if (ENABLE_DEVFSD_VERBOSE)
    10891095        msg = "user";
    10901096
    1091     if (isdigit(string[0]) ||((string[0] == '-') && isdigit(string[1])))
    1092         return atoi(string);
    1093 
    1094     if (flag == UID && (pw_ent = getpwnam(string)) != NULL)
    1095         return pw_ent->pw_uid;
    1096 
    1097     if (flag == GID && (grp_ent = getgrnam(string)) != NULL)
    1098         return grp_ent->gr_gid;
    1099     else if (ENABLE_DEVFSD_VERBOSE)
    1100         msg = "group";
     1097    if (flag == GID) {
     1098        if ((grp_ent = getgrnam(string)) != NULL)
     1099            return grp_ent->gr_gid;
     1100        if (ENABLE_DEVFSD_VERBOSE)
     1101            msg = "group";
     1102    }
    11011103
    11021104    if (ENABLE_DEVFSD_VERBOSE)
     
    11411143static const char *get_variable(const char *variable, void *info)
    11421144{
    1143     static char sbuf[sizeof(int)*3 + 2]; /* sign and NUL */
    11441145    static char *hostname;
    11451146
    11461147    struct get_variable_info *gv_info = info;
    11471148    const char *field_names[] = {
    1148             "hostname", "mntpt", "devpath", "devname",
    1149             "uid", "gid", "mode", hostname, mount_point,
    1150             gv_info->devpath, gv_info->devname, NULL
     1149            "hostname", "mntpt", "devpath", "devname", "uid", "gid", "mode",
     1150            NULL, mount_point, gv_info->devpath, gv_info->devname, NULL
    11511151    };
    11521152    int i;
     
    11541154    if (!hostname)
    11551155        hostname = safe_gethostname();
     1156    field_names[7] = hostname;
     1157
    11561158    /* index_in_str_array returns i>=0  */
    11571159    i = index_in_str_array(field_names, variable);
     
    11631165
    11641166    if (i == 4)
    1165         sprintf(sbuf, "%u", gv_info->info->uid);
    1166     else if (i == 5)
    1167         sprintf(sbuf, "%u", gv_info->info->gid);
    1168     else if (i == 6)
    1169         sprintf(sbuf, "%o", gv_info->info->mode);
    1170     return sbuf;
     1167        return auto_string(xasprintf("%u", gv_info->info->uid));
     1168    if (i == 5)
     1169        return auto_string(xasprintf("%u", gv_info->info->gid));
     1170    /* i == 6 */
     1171    return auto_string(xasprintf("%o", gv_info->info->mode));
    11711172}   /*  End Function get_variable  */
    11721173
     
    14041405    const char *pty1;
    14051406    const char *pty2;
    1406     size_t len;
    14071407    /* 1 to 5  "scsi/" , 6 to 9 "ide/host", 10 sbp/, 11 vcc/, 12 pty/ */
    14081408    static const char *const fmt[] = {
     
    14241424
    14251425    for (trans = translate_table; trans->match != NULL; ++trans) {
    1426         len = strlen(trans->match);
    1427 
    1428         if (strncmp(devname, trans->match, len) == 0) {
     1426        char *after_match = is_prefixed_with(devname, trans->match);
     1427        if (after_match) {
    14291428            if (trans->format == NULL)
    1430                 return devname + len;
    1431             sprintf(buffer, trans->format, devname + len);
     1429                return after_match;
     1430            sprintf(buffer, trans->format, after_match);
    14321431            return buffer;
    14331432        }
  • branches/3.3/mindi-busybox/miscutils/eject.c

    r3232 r3621  
    2626#include <sys/mount.h>
    2727#include "libbb.h"
     28#if ENABLE_FEATURE_EJECT_SCSI
    2829/* Must be after libbb.h: they need size_t */
    29 #include "fix_u32.h"
    30 #include <scsi/sg.h>
    31 #include <scsi/scsi.h>
    32 
    33 /* various defines swiped from linux/cdrom.h */
    34 #define CDROMCLOSETRAY            0x5319  /* pendant of CDROMEJECT  */
    35 #define CDROMEJECT                0x5309  /* Ejects the cdrom media */
    36 #define CDROM_DRIVE_STATUS        0x5326  /* Get tray position, etc. */
    37 /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
    38 #define CDS_TRAY_OPEN        2
     30# include "fix_u32.h"
     31# include <scsi/sg.h>
     32# include <scsi/scsi.h>
     33#endif
    3934
    4035#define dev_fd 3
     
    4338 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */
    4439
     40#if ENABLE_FEATURE_EJECT_SCSI
    4541static void eject_scsi(const char *dev)
    4642{
    47     static const char sg_commands[3][6] = {
     43    static const char sg_commands[3][6] ALIGN1 = {
    4844        { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 },
    4945        { START_STOP, 0, 0, 0, 1, 0 },
     
    7773    ioctl(dev_fd, BLKRRPART);
    7874}
     75#else
     76# define eject_scsi(dev) ((void)0)
     77#endif
     78
     79/* various defines swiped from linux/cdrom.h */
     80#define CDROMCLOSETRAY            0x5319  /* pendant of CDROMEJECT  */
     81#define CDROMEJECT                0x5309  /* Ejects the cdrom media */
     82#define CDROM_DRIVE_STATUS        0x5326  /* Get tray position, etc. */
     83/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
     84#define CDS_TRAY_OPEN        2
    7985
    8086#define FLAG_CLOSE  1
  • branches/3.3/mindi-busybox/miscutils/fbsplash.c

    r3232 r3621  
    3535
    3636#include "libbb.h"
     37#include "common_bufsiz.h"
    3738#include <linux/fb.h>
    3839
     
    151152    // map the device in memory
    152153    G.addr = mmap(NULL,
    153             G.scr_var.yres * G.scr_fix.line_length,
     154            (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length,
    154155            PROT_WRITE, MAP_SHARED, fbfd, 0);
    155156    if (G.addr == MAP_FAILED)
     
    354355        theme_file = stdin;
    355356    } else {
    356         int fd = open_zipped(G.image_filename);
     357        int fd = open_zipped(G.image_filename, /*fail_if_not_compressed:*/ 0);
    357358        if (fd < 0)
    358359            bb_simple_perror_msg_and_die(G.image_filename);
     
    374375     */
    375376#define concat_buf bb_common_bufsiz1
     377    setup_common_bufsiz();
     378
    376379    read_ptr = concat_buf;
    377380    while (1) {
    378381        int w, h, max_color_val;
    379         int rem = concat_buf + sizeof(concat_buf) - read_ptr;
     382        int rem = concat_buf + COMMON_BUFSIZE - read_ptr;
    380383        if (rem < 2
    381384         || fgets(read_ptr, rem, theme_file) == NULL
     
    517520    // already in the pipe
    518521    while ((num_buf = xmalloc_fgetline(fp)) != NULL) {
    519         if (strncmp(num_buf, "exit", 4) == 0) {
     522        if (is_prefixed_with(num_buf, "exit")) {
    520523            DEBUG_MESSAGE("exit");
    521524            break;
  • branches/3.3/mindi-busybox/miscutils/flash_eraseall.c

    r3232 r3621  
    1212
    1313//usage:#define flash_eraseall_trivial_usage
    14 //usage:       "[-jq] MTD_DEVICE"
     14//usage:       "[-jNq] MTD_DEVICE"
    1515//usage:#define flash_eraseall_full_usage "\n\n"
    1616//usage:       "Erase an MTD device\n"
    1717//usage:     "\n    -j  Format the device for jffs2"
     18//usage:     "\n    -N  Don't skip bad blocks"
    1819//usage:     "\n    -q  Don't display progress messages"
    1920
     
    2324
    2425#define OPTION_J  (1 << 0)
    25 #define OPTION_Q  (1 << 1)
    26 #define IS_NAND   (1 << 2)
    27 #define BBTEST    (1 << 3)
     26#define OPTION_N  (1 << 1)
     27#define OPTION_Q  (1 << 2)
     28#define IS_NAND   (1 << 3)
    2829
    2930/* mtd/jffs2-user.h used to have this atrocity:
     
    7273
    7374    opt_complementary = "=1";
    74     flags = BBTEST | getopt32(argv, "jq");
     75    flags = getopt32(argv, "jNq");
    7576
    7677    mtd_name = argv[optind];
     
    140141    for (erase.start = 0; erase.start < meminfo.size;
    141142         erase.start += meminfo.erasesize) {
    142         if (flags & BBTEST) {
     143        if (!(flags & OPTION_N)) {
    143144            int ret;
    144145            loff_t offset = erase.start;
     
    147148            if (ret > 0) {
    148149                if (!(flags & OPTION_Q))
    149                     bb_info_msg("\nSkipping bad block at 0x%08x", erase.start);
     150                    printf("\nSkipping bad block at 0x%08x\n", erase.start);
    150151                continue;
    151152            }
     
    155156                 */
    156157                if (errno == EOPNOTSUPP) {
    157                     flags &= ~BBTEST;
     158                    flags |= OPTION_N;
    158159                    if (flags & IS_NAND)
    159160                        bb_error_msg_and_die("bad block check not available");
  • branches/3.3/mindi-busybox/miscutils/flashcp.c

    r3232 r3621  
    1717#include <mtd/mtd-user.h>
    1818
     19/* If 1, simulates "flashing" by writing to existing regular file */
    1920#define MTD_DEBUG 0
    2021
    2122#define OPT_v (1 << 0)
    2223
    23 #define BUFSIZE (8 * 1024)
     24#define BUFSIZE (4 * 1024)
    2425
    2526static void progress(int mode, uoff_t count, uoff_t total)
     
    3334        percent = (unsigned) (percent / total);
    3435    printf("\r%s: %"OFF_FMT"u/%"OFF_FMT"u (%u%%) ",
    35         (mode == 0) ? "Erasing block" : ((mode == 1) ? "Writing kb" : "Verifying kb"),
     36        (mode < 0) ? "Erasing block" : ((mode == 0) ? "Writing kb" : "Verifying kb"),
    3637        count, total, (unsigned)percent);
    3738    fflush_all();
     
    9899    e.start = 0;
    99100    for (i = 1; i <= erase_count; i++) {
    100         progress(0, i, erase_count);
    101         errno = 0;
     101        progress(-1, i, erase_count);
    102102#if !MTD_DEBUG
    103103        if (ioctl(fd_d, MEMERASE, &e) < 0) {
     
    114114    /* doing this outer loop gives significantly smaller code
    115115     * than doing two separate loops for writing and verifying */
    116     for (i = 1; i <= 2; i++) {
     116    for (i = 0; i <= 1; i++) {
    117117        uoff_t done;
    118118        unsigned count;
     
    123123        count = BUFSIZE;
    124124        while (1) {
    125             uoff_t rem = statb.st_size - done;
     125            uoff_t rem;
     126
     127            progress(i, done / 1024, (uoff_t)statb.st_size / 1024);
     128            rem = statb.st_size - done;
    126129            if (rem == 0)
    127130                break;
    128131            if (rem < BUFSIZE)
    129132                count = rem;
    130             progress(i, done / 1024, (uoff_t)statb.st_size / 1024);
    131133            xread(fd_f, buf, count);
    132             if (i == 1) {
     134            if (i == 0) {
    133135                int ret;
     136                if (count < BUFSIZE)
     137                    memset((char*)buf + count, 0, BUFSIZE - count);
    134138                errno = 0;
    135                 ret = full_write(fd_d, buf, count);
    136                 if (ret != count) {
     139                ret = full_write(fd_d, buf, BUFSIZE);
     140                if (ret != BUFSIZE) {
    137141                    bb_perror_msg_and_die("write error at 0x%"OFF_FMT"x on %s, "
    138142                        "write returned %d",
    139143                        done, devicename, ret);
    140144                }
    141             } else { /* i == 2 */
     145            } else { /* i == 1 */
    142146                xread(fd_d, buf2, count);
    143                 if (memcmp(buf, buf2, count)) {
     147                if (memcmp(buf, buf2, count) != 0) {
    144148                    bb_error_msg_and_die("verification mismatch at 0x%"OFF_FMT"x", done);
    145149                }
  • branches/3.3/mindi-busybox/miscutils/hdparm.c

    r3232 r3621  
    6464
    6565#include "libbb.h"
     66#include "common_bufsiz.h"
    6667/* must be _after_ libbb.h: */
    6768#include <linux/hdreg.h>
     
    368369#endif
    369370} FIX_ALIASING;
    370 #define G (*(struct globals*)&bb_common_bufsiz1)
    371 struct BUG_G_too_big {
    372     char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
    373 };
     371#define G (*(struct globals*)bb_common_bufsiz1)
    374372#define get_identity       (G.get_identity           )
    375373#define get_geom           (G.get_geom               )
     
    434432#define hwif_ctrl          (G.hwif_ctrl              )
    435433#define hwif_irq           (G.hwif_irq               )
    436 #define INIT_G() do { } while (0)
     434#define INIT_G() do { \
     435    setup_common_bufsiz(); \
     436    BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
     437} while (0)
    437438
    438439
     
    466467{
    467468    if (get_arg) {
    468         printf(" setting %s to %ld", s, arg);
     469        printf(" setting %s to %lu", s, arg);
    469470        on_off(arg);
    470471    }
     
    473474static void print_value_on_off(const char *str, unsigned long argp)
    474475{
    475     printf(" %s\t= %2ld", str, argp);
     476    printf(" %s\t= %2lu", str, argp);
    476477    on_off(argp != 0);
    477478}
     
    764765        like_std = 5;
    765766        if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
    766             printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
     767            puts("powers-up in standby; SET FEATURES subcmd spins-up.");
    767768        if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
    768             printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
     769            puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n");
    769770    }
    770771
     
    876877        min_std = like_std > 4 ? like_std - 3 : 1;
    877878
    878     printf("Configuration:\n");
     879    puts("Configuration:");
    879880    /* more info from the general configuration word */
    880881    if ((eqpt != CDROM) && (like_std == 1)) {
     
    910911        bbbig = 0;
    911912        if ((ll > 0x00FBFC10) && (!val[LCYLS]))
    912             printf("\tCHS addressing not supported\n");
     913            puts("\tCHS addressing not supported");
    913914        else {
    914915            jj = val[WHATS_VALID] & OK_W54_58;
     
    981982            (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
    982983    } else
    983         printf("no IORDY\n");
     984        puts("no IORDY");
    984985
    985986    if ((like_std == 1) && val[BUF_TYPE]) {
     
    10131014        printf("\tR/W multiple sector transfer: ");
    10141015        if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
    1015             printf("not supported\n");
     1016            puts("not supported");
    10161017        else {
    10171018            printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
     
    10191020                printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
    10201021            else
    1021                 printf("?\n");
     1022                puts("?");
    10221023        }
    10231024        if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
     
    10411042        /* ATAPI */
    10421043        if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
    1043             printf("\tATA sw reset required\n");
     1044            puts("\tATA sw reset required");
    10441045
    10451046        if (val[PKT_REL] || val[SVC_NBSY]) {
     
    10571058    printf("\tDMA: ");
    10581059    if (!(val[CAPAB_0] & DMA_SUP))
    1059         printf("not supported\n");
     1060        puts("not supported");
    10601061    else {
    10611062        if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
     
    10801081
    10811082        if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
    1082             printf("\t\tInterleaved DMA support\n");
     1083            puts("\t\tInterleaved DMA support");
    10831084
    10841085        if ((val[WHATS_VALID] & OK_W64_70)
     
    11221123
    11231124    if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
    1124         printf("Commands/features:\n"
    1125             "\tEnabled\tSupported:\n");
     1125        puts("Commands/features:\n"
     1126            "\tEnabled\tSupported:");
    11261127        jj = val[CMDS_SUPP_0];
    11271128        kk = val[CMDS_EN_0];
     
    11511152     && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
    11521153    ) {
    1153         printf("Security:\n");
     1154        puts("Security:");
    11541155        if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
    11551156            printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
     
    13671368    }
    13681369#endif /* __NEW_HD_DRIVE_ID */
    1369     printf("\n\n * current active mode\n\n");
     1370    puts("\n\n * current active mode\n");
    13701371}
    13711372#endif
     
    15081509        on_off(0);
    15091510    else if (value == BUSSTATE_TRISTATE)
    1510         printf(" (tristate)\n");
     1511        puts(" (tristate)");
    15111512    else
    1512         printf(" (unknown: %d)\n", value);
     1513        printf(" (unknown: %u)\n", value);
    15131514}
    15141515#endif
     
    15321533    if (standby == 254)
    15331534        printf("reserved");
    1534     printf(")\n");
     1535    puts(")");
    15351536}
    15361537
     
    15831584    else
    15841585        printf("unknown");
    1585     printf(")\n");
     1586    puts(")");
    15861587}
    15871588#endif /* HDIO_DRIVE_CMD */
     
    15901591{
    15911592    if (flag)
    1592         printf(" setting %s to %ld\n", s, value);
     1593        printf(" setting %s to %lu\n", s, value);
    15931594}
    15941595
     
    16341635            printf(" attempting to ");
    16351636            if (piomode == 255)
    1636                 printf("auto-tune PIO mode\n");
     1637                puts("auto-tune PIO mode");
    16371638            else if (piomode < 100)
    16381639                printf("set PIO mode to %d\n", piomode);
     
    17631764#define WIN_STANDBYNOW2 0x94
    17641765#endif
    1765         printf(" issuing standby command\n");
     1766        puts(" issuing standby command");
    17661767        args[0] = WIN_STANDBYNOW1;
    17671768        ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
     
    17741775#define WIN_SLEEPNOW2 0x99
    17751776#endif
    1776         printf(" issuing sleep command\n");
     1777        puts(" issuing sleep command");
    17771778        args[0] = WIN_SLEEPNOW1;
    17781779        ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
     
    17801781    if (set_seagate) {
    17811782        args[0] = 0xfb;
    1782         printf(" disabling Seagate auto powersaving mode\n");
     1783        puts(" disabling Seagate auto powersaving mode");
    17831784        ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
    17841785    }
     
    18161817            printf(" IO_support\t=%3ld (", parm);
    18171818            if (parm == 0)
    1818                 printf("default 16-bit)\n");
     1819                puts("default 16-bit)");
    18191820            else if (parm == 2)
    1820                 printf("16-bit)\n");
     1821                puts("16-bit)");
    18211822            else if (parm == 1)
    1822                 printf("32-bit)\n");
     1823                puts("32-bit)");
    18231824            else if (parm == 3)
    1824                 printf("32-bit w/sync)\n");
     1825                puts("32-bit w/sync)");
    18251826            else if (parm == 8)
    1826                 printf("Request-Queue-Bypass)\n");
     1827                puts("Request-Queue-Bypass)");
    18271828            else
    1828                 printf("\?\?\?)\n");
     1829                puts("\?\?\?)");
    18291830        }
    18301831    }
     
    18381839            printf(fmt, "using_dma", parm);
    18391840            if (parm == 8)
    1840                 printf(" (DMA-Assisted-PIO)\n");
     1841                puts(" (DMA-Assisted-PIO)");
    18411842            else
    18421843                on_off(parm != 0);
     
    19221923            dump_identity(&id);
    19231924        } else if (errno == -ENOMSG)
    1924             printf(" no identification info available\n");
     1925            puts(" no identification info available");
    19251926        else if (ENABLE_IOCTL_HEX2STR_ERROR)  /* To be coherent with ioctl_or_warn */
    19261927            bb_perror_msg("HDIO_GET_IDENTITY");
  • branches/3.3/mindi-busybox/miscutils/inotifyd.c

    r3232 r3621  
    4848//usage:     "\n    x   File can't be watched anymore"
    4949//usage:     "\nIf watching a directory:"
    50 //usage:     "\n    m   Subfile is moved into dir"
    51 //usage:     "\n    y   Subfile is moved out of dir"
     50//usage:     "\n    y   Subfile is moved into dir"
     51//usage:     "\n    m   Subfile is moved out of dir"
    5252//usage:     "\n    n   Subfile is created"
    5353//usage:     "\n    d   Subfile is deleted"
     
    5757
    5858#include "libbb.h"
     59#include "common_bufsiz.h"
    5960#include <sys/inotify.h>
    6061
     
    162163        // read out all pending events
    163164        // (NB: len must be int, not ssize_t or long!)
     165#define eventbuf bb_common_bufsiz1
     166        setup_common_bufsiz();
    164167        xioctl(pfd.fd, FIONREAD, &len);
    165 #define eventbuf bb_common_bufsiz1
    166         ie = buf = (len <= sizeof(eventbuf)) ? eventbuf : xmalloc(len);
     168        ie = buf = (len <= COMMON_BUFSIZE) ? eventbuf : xmalloc(len);
    167169        len = full_read(pfd.fd, buf, len);
    168170        // process events. N.B. events may vary in length
  • branches/3.3/mindi-busybox/miscutils/ionice.c

    r3232 r3621  
    4242};
    4343
    44 static const char to_prio[] = "none\0realtime\0best-effort\0idle";
     44static const char to_prio[] ALIGN1 = "none\0realtime\0best-effort\0idle";
    4545
    4646#define IOPRIO_CLASS_SHIFT      13
  • branches/3.3/mindi-busybox/miscutils/last.c

    r3232 r3621  
    3333#if defined UT_LINESIZE \
    3434    && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256))
    35 #error struct utmp member char[] size(s) have changed!
     35#error struct utmpx member char[] size(s) have changed!
    3636#elif defined __UT_LINESIZE \
    37     && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 64) || (__UT_HOSTSIZE != 256))
    38 #error struct utmp member char[] size(s) have changed!
     37    && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256))
     38/* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */
     39#error struct utmpx member char[] size(s) have changed!
    3940#endif
    4041
    4142#if EMPTY != 0 || RUN_LVL != 1 || BOOT_TIME != 2 || NEW_TIME != 3 || \
    4243    OLD_TIME != 4
    43 #error Values for the ut_type field of struct utmp changed
     44#error Values for the ut_type field of struct utmpx changed
    4445#endif
    4546
     
    4748int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
    4849{
    49     struct utmp ut;
     50    struct utmpx ut;
    5051    int n, file = STDIN_FILENO;
    5152    time_t t_tmp;
     
    8889                ut.ut_type = n != 3 ? n : SHUTDOWN_TIME;
    8990#else
    90             if (strncmp(ut.ut_user, "shutdown", 8) == 0)
     91            if (is_prefixed_with(ut.ut_user, "shutdown"))
    9192                ut.ut_type = SHUTDOWN_TIME;
    92             else if (strncmp(ut.ut_user, "reboot", 6) == 0)
     93            else if (is_prefixed_with(ut.ut_user, "reboot"))
    9394                ut.ut_type = BOOT_TIME;
    94             else if (strncmp(ut.ut_user, "runlevel", 8) == 0)
     95            else if (is_prefixed_with(ut.ut_user, "runlevel"))
    9596                ut.ut_type = RUN_LVL;
    9697#endif
  • branches/3.3/mindi-busybox/miscutils/last_fancy.c

    r3232 r3621  
    2323    INET6_ADDRSTRLEN, INET6_ADDRSTRLEN, "HOST", "LOGIN", "  TIME", ""
    2424
     25#if !defined __UT_LINESIZE && defined UT_LINESIZE
     26# define __UT_LINESIZE UT_LINESIZE
     27#endif
     28
    2529enum {
    2630    NORMAL,
     
    4044#define show_wide (option_mask32 & LAST_OPT_W)
    4145
    42 static void show_entry(struct utmp *ut, int state, time_t dur_secs)
     46static void show_entry(struct utmpx *ut, int state, time_t dur_secs)
    4347{
    4448    unsigned days, hours, mins;
    45     char duration[32];
     49    char duration[sizeof("(%u+02:02)") + sizeof(int)*3];
    4650    char login_time[17];
    4751    char logout_time[8];
     
    5458    tmp = ut->ut_tv.tv_sec;
    5559    safe_strncpy(login_time, ctime(&tmp), 17);
    56     snprintf(logout_time, 8, "- %s", ctime(&dur_secs) + 11);
     60    tmp = dur_secs;
     61    snprintf(logout_time, 8, "- %s", ctime(&tmp) + 11);
    5762
    5863    dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0);
     
    104109}
    105110
    106 static int get_ut_type(struct utmp *ut)
     111static int get_ut_type(struct utmpx *ut)
    107112{
    108113    if (ut->ut_line[0] == '~') {
     
    142147}
    143148
    144 static int is_runlevel_shutdown(struct utmp *ut)
     149static int is_runlevel_shutdown(struct utmpx *ut)
    145150{
    146151    if (((ut->ut_pid & 255) == '0') || ((ut->ut_pid & 255) == '6')) {
     
    154159int last_main(int argc UNUSED_PARAM, char **argv)
    155160{
    156     struct utmp ut;
     161    struct utmpx ut;
    157162    const char *filename = _PATH_WTMP;
    158163    llist_t *zlist;
     
    229234            }
    230235            /* add_entry */
    231             llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)), &ut, sizeof(ut)));
     236            llist_add_to(&zlist, xmemdup(&ut, sizeof(ut)));
    232237            break;
    233238        case USER_PROCESS: {
     
    242247                llist_t *el, *next;
    243248                for (el = zlist; el; el = next) {
    244                     struct utmp *up = (struct utmp *)el->data;
     249                    struct utmpx *up = (struct utmpx *)el->data;
    245250                    next = el->link;
    246                     if (strncmp(up->ut_line, ut.ut_line, UT_LINESIZE) == 0) {
     251                    if (strncmp(up->ut_line, ut.ut_line, __UT_LINESIZE) == 0) {
    247252                        if (show) {
    248253                            show_entry(&ut, NORMAL, up->ut_tv.tv_sec);
     
    271276            }
    272277            /* add_entry */
    273             llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)), &ut, sizeof(ut)));
     278            llist_add_to(&zlist, xmemdup(&ut, sizeof(ut)));
    274279            break;
    275280        }
  • branches/3.3/mindi-busybox/miscutils/less.c

    r3232 r3621  
    4848//config:   help
    4949//config:     The -M/-m flag enables a more sophisticated status line.
     50//config:
     51//config:config FEATURE_LESS_TRUNCATE
     52//config:   bool "Enable -S"
     53//config:   default y
     54//config:   depends on LESS
     55//config:   help
     56//config:     The -S flag causes long lines to be truncated rather than
     57//config:     wrapped.
    5058//config:
    5159//config:config FEATURE_LESS_MARKS
     
    99107
    100108//usage:#define less_trivial_usage
    101 //usage:       "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..."
     109//usage:       "[-E" IF_FEATURE_LESS_REGEXP("I")IF_FEATURE_LESS_FLAGS("Mm")
     110//usage:       "N" IF_FEATURE_LESS_TRUNCATE("S") "h~] [FILE]..."
    102111//usage:#define less_full_usage "\n\n"
    103112//usage:       "View FILE (or stdin) one screenful at a time\n"
    104113//usage:     "\n    -E  Quit once the end of a file is reached"
     114//usage:    IF_FEATURE_LESS_REGEXP(
     115//usage:     "\n    -I  Ignore case in all searches"
     116//usage:    )
    105117//usage:    IF_FEATURE_LESS_FLAGS(
    106118//usage:     "\n    -M,-m   Display status line with line numbers"
     
    108120//usage:    )
    109121//usage:     "\n    -N  Prefix line number to each line"
    110 //usage:     "\n    -I  Ignore case in all searches"
     122//usage:    IF_FEATURE_LESS_TRUNCATE(
     123//usage:     "\n    -S  Truncate long lines"
     124//usage:    )
    111125//usage:     "\n    -~  Suppress ~s displayed past EOF"
    112126
     
    114128
    115129#include "libbb.h"
     130#include "common_bufsiz.h"
    116131#if ENABLE_FEATURE_LESS_REGEXP
    117132#include "xregex.h"
     
    143158    FLAG_TILDE = 1 << 4,
    144159    FLAG_I = 1 << 5,
    145     FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_DASHCMD,
     160    FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_TRUNCATE,
    146161/* hijack command line options variable for internal state vars */
    147162    LESS_STATE_MATCH_BACKWARDS = 1 << 15,
     
    175190    char *filename;
    176191    char **files;
     192#if ENABLE_FEATURE_LESS_FLAGS
     193    int num_lines; /* a flag if < 0, line count if >= 0 */
     194# define REOPEN_AND_COUNT (-1)
     195# define REOPEN_STDIN     (-2)
     196# define NOT_REGULAR_FILE (-3)
     197#endif
    177198#if ENABLE_FEATURE_LESS_MARKS
    178199    unsigned num_marks;
     
    216237#define filename            (G.filename          )
    217238#define files               (G.files             )
     239#define num_lines           (G.num_lines         )
    218240#define num_marks           (G.num_marks         )
    219241#define mark_lines          (G.mark_lines        )
     
    318340        if (*d != '\0') {
    319341            new_line_pos++;
    320             if (*d == '\t') /* tab */
     342            if (*d == '\t') { /* tab */
    321343                new_line_pos += 7;
     344                new_line_pos &= (~7);
     345            }
    322346            s++;
    323347            d++;
     
    381405#endif
    382406
     407static int at_end(void)
     408{
     409    return (option_mask32 & FLAG_S)
     410        ? !(cur_fline <= max_fline &&
     411            max_lineno > LINENO(flines[cur_fline]) + max_displayed_line)
     412        : !(max_fline > cur_fline + max_displayed_line);
     413}
     414
    383415/* Devilishly complex routine.
    384416 *
     
    403435 *      (takes into account tabs and backspaces)
    404436 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
     437 *
     438 * "git log -p | less -m" on the kernel git tree is a good test for EAGAINs,
     439 * "/search on very long input" and "reaching max line count" corner cases.
    405440 */
    406441static void read_lines(void)
    407442{
    408 #define readbuf bb_common_bufsiz1
    409443    char *current_line, *p;
    410444    int w = width;
    411445    char last_terminated = terminated;
     446    time_t last_time = 0;
     447    int retry_EAGAIN = 2;
    412448#if ENABLE_FEATURE_LESS_REGEXP
    413449    unsigned old_max_fline = max_fline;
    414     time_t last_time = 0;
    415     unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */
    416 #endif
     450#endif
     451
     452#define readbuf bb_common_bufsiz1
     453    setup_common_bufsiz();
     454
     455    /* (careful: max_fline can be -1) */
     456    if (max_fline + 1 > MAXLINES)
     457        return;
    417458
    418459    if (option_mask32 & FLAG_N)
    419460        w -= 8;
    420461
    421  IF_FEATURE_LESS_REGEXP(again0:)
    422 
    423     p = current_line = ((char*)xmalloc(w + 4)) + 4;
    424     max_fline += last_terminated;
     462    p = current_line = ((char*)xmalloc(w + 5)) + 4;
    425463    if (!last_terminated) {
    426464        const char *cp = flines[max_fline];
    427         strcpy(p, cp);
    428         p += strlen(current_line);
    429         free(MEMPTR(flines[max_fline]));
     465        p = stpcpy(p, cp);
     466        free(MEMPTR(cp));
    430467        /* last_line_pos is still valid from previous read_lines() */
    431468    } else {
     469        max_fline++;
    432470        last_line_pos = 0;
    433471    }
     
    440478            /* if no unprocessed chars left, eat more */
    441479            if (readpos >= readeof) {
    442                 ndelay_on(0);
    443                 eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
    444                 ndelay_off(0);
     480                int flags = ndelay_on(0);
     481
     482                while (1) {
     483                    time_t t;
     484
     485                    errno = 0;
     486                    eof_error = safe_read(STDIN_FILENO, readbuf, COMMON_BUFSIZE);
     487                    if (errno != EAGAIN)
     488                        break;
     489                    t = time(NULL);
     490                    if (t != last_time) {
     491                        last_time = t;
     492                        if (--retry_EAGAIN < 0)
     493                            break;
     494                    }
     495                    sched_yield();
     496                }
     497                fcntl(0, F_SETFL, flags); /* ndelay_off(0) */
    445498                readpos = 0;
    446499                readeof = eof_error;
    447500                if (eof_error <= 0)
    448501                    goto reached_eof;
     502                retry_EAGAIN = 1;
    449503            }
    450504            c = readbuf[readpos];
     
    465519                    new_last_line_pos &= (~7);
    466520                }
    467                 if ((int)new_last_line_pos >= w)
     521                if ((int)new_last_line_pos > w)
    468522                    break;
    469523                last_line_pos = new_last_line_pos;
     
    481535            *p = '\0';
    482536        } /* end of "read chars until we have a line" loop */
     537#if 0
     538//BUG: also triggers on this:
     539// { printf "\nfoo\n"; sleep 1; printf "\nbar\n"; } | less
     540// (resulting in lost empty line between "foo" and "bar" lines)
     541// the "terminated" logic needs fixing (or explaining)
    483542        /* Corner case: linewrap with only "" wrapping to next line */
    484543        /* Looks ugly on screen, so we do not store this empty line */
     
    488547            continue;
    489548        }
     549#endif
    490550 reached_eof:
    491551        last_terminated = terminated;
     
    501561            break;
    502562        }
    503         if (!(option_mask32 & FLAG_S)
    504           ? (max_fline > cur_fline + max_displayed_line)
    505           : (max_fline >= cur_fline
    506              && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line)
    507         ) {
     563        if (!at_end()) {
    508564#if !ENABLE_FEATURE_LESS_REGEXP
    509565            break;
     
    518574        }
    519575        if (eof_error <= 0) {
    520             if (eof_error < 0) {
    521                 if (errno == EAGAIN) {
    522                     /* not yet eof or error, reset flag (or else
    523                      * we will hog CPU - select() will return
    524                      * immediately */
    525                     eof_error = 1;
    526                 } else {
    527                     print_statusline(bb_msg_read_error);
    528                 }
    529             }
    530 #if !ENABLE_FEATURE_LESS_REGEXP
    531576            break;
    532 #else
    533             if (wanted_match < num_matches) {
    534                 break;
    535             } else { /* goto_match called us */
    536                 time_t t = time(NULL);
    537                 if (t != last_time) {
    538                     last_time = t;
    539                     if (--seconds_p1 == 0)
    540                         break;
    541                 }
    542                 sched_yield();
    543                 goto again0; /* go loop again (max 2 seconds) */
    544             }
    545 #endif
    546577        }
    547578        max_fline++;
    548         current_line = ((char*)xmalloc(w + 4)) + 4;
     579        current_line = ((char*)xmalloc(w + 5)) + 4;
    549580        p = current_line;
    550581        last_line_pos = 0;
    551582    } /* end of "read lines until we reach cur_fline" loop */
     583
     584    if (eof_error < 0) {
     585        if (errno == EAGAIN) {
     586            eof_error = 1;
     587        } else {
     588            print_statusline(bb_msg_read_error);
     589        }
     590    }
     591#if ENABLE_FEATURE_LESS_FLAGS
     592    else if (eof_error == 0)
     593        num_lines = max_lineno;
     594#endif
     595
    552596    fill_match_lines(old_max_fline);
    553597#if ENABLE_FEATURE_LESS_REGEXP
     
    559603
    560604#if ENABLE_FEATURE_LESS_FLAGS
    561 /* Interestingly, writing calc_percent as a function saves around 32 bytes
    562  * on my build. */
    563 static int calc_percent(void)
    564 {
    565     unsigned p = (100 * (cur_fline+max_displayed_line+1) + max_fline/2) / (max_fline+1);
    566     return p <= 100 ? p : 100;
     605static int safe_lineno(int fline)
     606{
     607    if (fline >= max_fline)
     608        fline = max_fline - 1;
     609
     610    /* also catches empty file (max_fline == 0) */
     611    if (fline < 0)
     612        return 0;
     613
     614    return LINENO(flines[fline]) + 1;
     615}
     616
     617/* count number of lines in file */
     618static void update_num_lines(void)
     619{
     620    int count, fd;
     621    struct stat stbuf;
     622    ssize_t len, i;
     623    char buf[4096];
     624
     625    /* only do this for regular files */
     626    if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) {
     627        count = 0;
     628        fd = open("/proc/self/fd/0", O_RDONLY);
     629        if (fd < 0 && num_lines == REOPEN_AND_COUNT) {
     630            /* "filename" is valid only if REOPEN_AND_COUNT */
     631            fd = open(filename, O_RDONLY);
     632        }
     633        if (fd < 0) {
     634            /* somebody stole my file! */
     635            num_lines = NOT_REGULAR_FILE;
     636            return;
     637        }
     638        if (fstat(fd, &stbuf) != 0 || !S_ISREG(stbuf.st_mode)) {
     639            num_lines = NOT_REGULAR_FILE;
     640            goto do_close;
     641        }
     642        while ((len = safe_read(fd, buf, sizeof(buf))) > 0) {
     643            for (i = 0; i < len; ++i) {
     644                if (buf[i] == '\n' && ++count == MAXLINES)
     645                    goto done;
     646            }
     647        }
     648 done:
     649        num_lines = count;
     650 do_close:
     651        close(fd);
     652    }
    567653}
    568654
     
    570656static void m_status_print(void)
    571657{
    572     int percentage;
     658    int first, last;
     659    unsigned percent;
    573660
    574661    if (less_gets_pos >= 0) /* don't touch statusline while input is done! */
     
    579666    if (num_files > 1)
    580667        printf(" (file %i of %i)", current_file, num_files);
    581     printf(" lines %i-%i/%i ",
    582             cur_fline + 1, cur_fline + max_displayed_line + 1,
    583             max_fline + 1);
    584     if (cur_fline >= (int)(max_fline - max_displayed_line)) {
    585         printf("(END)"NORMAL);
     668
     669    first = safe_lineno(cur_fline);
     670    last = (option_mask32 & FLAG_S)
     671            ? MIN(first + max_displayed_line, max_lineno)
     672            : safe_lineno(cur_fline + max_displayed_line);
     673    printf(" lines %i-%i", first, last);
     674
     675    update_num_lines();
     676    if (num_lines >= 0)
     677        printf("/%i", num_lines);
     678
     679    if (at_end()) {
     680        printf(" (END)");
    586681        if (num_files > 1 && current_file != num_files)
    587             printf(HIGHLIGHT" - next: %s"NORMAL, files[current_file]);
    588         return;
    589     }
    590     percentage = calc_percent();
    591     printf("%i%%"NORMAL, percentage);
     682            printf(" - next: %s", files[current_file]);
     683    } else if (num_lines > 0) {
     684        percent = (100 * last + num_lines/2) / num_lines;
     685        printf(" %i%%", percent <= 100 ? percent : 100);
     686    }
     687    printf(NORMAL);
    592688}
    593689#endif
     
    611707
    612708    clear_line();
    613     if (cur_fline && cur_fline < (int)(max_fline - max_displayed_line)) {
     709    if (cur_fline && !at_end()) {
    614710        bb_putchar(':');
    615711        return;
     
    624720    }
    625721    print_hilite(p);
    626 }
    627 
    628 static void cap_cur_fline(int nlines)
    629 {
    630     int diff;
    631     if (cur_fline < 0)
    632         cur_fline = 0;
    633     if (cur_fline + max_displayed_line > max_fline + TILDES) {
    634         cur_fline -= nlines;
    635         if (cur_fline < 0)
    636             cur_fline = 0;
    637         diff = max_fline - (cur_fline + max_displayed_line) + TILDES;
    638         /* As the number of lines requested was too large, we just move
    639          * to the end of the file */
    640         if (diff > 0)
    641             cur_fline += diff;
    642     }
    643722}
    644723
     
    654733    "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
    655734
    656 static void lineno_str(char *nbuf9, const char *line)
    657 {
    658     nbuf9[0] = '\0';
    659     if (option_mask32 & FLAG_N) {
    660         const char *fmt;
    661         unsigned n;
    662 
    663         if (line == empty_line_marker) {
    664             memset(nbuf9, ' ', 8);
    665             nbuf9[8] = '\0';
    666             return;
    667         }
     735static void print_lineno(const char *line)
     736{
     737    const char *fmt = "        ";
     738    unsigned n = n; /* for compiler */
     739
     740    if (line != empty_line_marker) {
    668741        /* Width of 7 preserves tab spacing in the text */
    669742        fmt = "%7u ";
    670743        n = LINENO(line) + 1;
    671         if (n > 9999999) {
     744        if (n > 9999999 && MAXLINES > 9999999) {
    672745            n %= 10000000;
    673746            fmt = "%07u ";
    674747        }
    675         sprintf(nbuf9, fmt, n);
    676     }
     748    }
     749    printf(fmt, n);
    677750}
    678751
     
    686759    regmatch_t match_structs;
    687760
    688     char buf[width];
    689     char nbuf9[9];
     761    char buf[width+1];
    690762    const char *str = line;
    691763    char *p = buf;
     
    737809    }
    738810
    739     lineno_str(nbuf9, line);
    740     if (!growline) {
    741         printf(CLEAR_2_EOL"%s%s\n", nbuf9, str);
    742         return;
    743     }
    744     printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str);
     811    printf("%s%s\n", growline ? growline : "", str);
    745812    free(growline);
    746813}
     
    751818static void print_ascii(const char *str)
    752819{
    753     char buf[width];
    754     char nbuf9[9];
     820    char buf[width+1];
    755821    char *p;
    756822    size_t n;
    757 
    758     lineno_str(nbuf9, str);
    759     printf(CLEAR_2_EOL"%s", nbuf9);
    760823
    761824    while (*str) {
     
    791854
    792855    move_cursor(0, 0);
    793     for (i = 0; i <= max_displayed_line; i++)
     856    for (i = 0; i <= max_displayed_line; i++) {
     857        printf(CLEAR_2_EOL);
     858        if (option_mask32 & FLAG_N)
     859            print_lineno(buffer[i]);
    794860        if (pattern_valid)
    795861            print_found(buffer[i]);
    796862        else
    797863            print_ascii(buffer[i]);
     864    }
     865    if ((option_mask32 & FLAG_E)
     866     && eof_error <= 0
     867     && (max_fline - cur_fline) <= max_displayed_line
     868    ) {
     869        less_exit(EXIT_SUCCESS);
     870    }
    798871    status_print();
    799872}
     
    802875{
    803876    unsigned i;
    804 #if ENABLE_FEATURE_LESS_DASHCMD
     877#if ENABLE_FEATURE_LESS_TRUNCATE
    805878    int fpos = cur_fline;
    806879
     
    834907}
    835908
     909/* move cur_fline to a given line number, reading lines if necessary */
     910static void goto_lineno(int target)
     911{
     912    if (target <= 0 ) {
     913        cur_fline = 0;
     914    }
     915    else if (target > LINENO(flines[cur_fline])) {
     916 retry:
     917        while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline)
     918            ++cur_fline;
     919        /* target not reached but more input is available */
     920        if (LINENO(flines[cur_fline]) != target && eof_error > 0) {
     921            read_lines();
     922            goto retry;
     923        }
     924    }
     925    else {
     926        /* search backwards through already-read lines */
     927        while (LINENO(flines[cur_fline]) != target && cur_fline > 0)
     928            --cur_fline;
     929    }
     930}
     931
     932static void cap_cur_fline(void)
     933{
     934    if ((option_mask32 & FLAG_S)) {
     935        if (cur_fline > max_fline)
     936            cur_fline = max_fline;
     937        if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) {
     938            goto_lineno(max_lineno - max_displayed_line + TILDES);
     939            read_lines();
     940        }
     941    }
     942    else {
     943        if (cur_fline + max_displayed_line > max_fline + TILDES)
     944            cur_fline = max_fline - max_displayed_line + TILDES;
     945        if (cur_fline < 0)
     946            cur_fline = 0;
     947    }
     948}
     949
    836950/* Move the buffer up and down in the file in order to scroll */
    837951static void buffer_down(int nlines)
    838952{
    839     cur_fline += nlines;
     953    if ((option_mask32 & FLAG_S))
     954        goto_lineno(LINENO(flines[cur_fline]) + nlines);
     955    else
     956        cur_fline += nlines;
    840957    read_lines();
    841     cap_cur_fline(nlines);
     958    cap_cur_fline();
    842959    buffer_fill_and_print();
    843960}
     
    845962static void buffer_up(int nlines)
    846963{
    847     cur_fline -= nlines;
    848     if (cur_fline < 0) cur_fline = 0;
     964    if ((option_mask32 & FLAG_S)) {
     965        goto_lineno(LINENO(flines[cur_fline]) - nlines);
     966    }
     967    else {
     968        cur_fline -= nlines;
     969        if (cur_fline < 0)
     970            cur_fline = 0;
     971    }
    849972    read_lines();
    850973    buffer_fill_and_print();
    851974}
    852975
     976/* display a given line where the argument can be either an index into
     977 * the flines array or a line number */
     978static void buffer_to_line(int linenum, int is_lineno)
     979{
     980    if (linenum <= 0)
     981        cur_fline = 0;
     982    else if (is_lineno)
     983        goto_lineno(linenum);
     984    else
     985        cur_fline = linenum;
     986    read_lines();
     987    cap_cur_fline();
     988    buffer_fill_and_print();
     989}
     990
    853991static void buffer_line(int linenum)
    854992{
    855     if (linenum < 0)
    856         linenum = 0;
    857     cur_fline = linenum;
    858     read_lines();
    859     if (linenum + max_displayed_line > max_fline)
    860         linenum = max_fline - max_displayed_line + TILDES;
    861     if (linenum < 0)
    862         linenum = 0;
    863     cur_fline = linenum;
    864     buffer_fill_and_print();
     993    buffer_to_line(linenum, FALSE);
     994}
     995
     996static void buffer_lineno(int lineno)
     997{
     998    buffer_to_line(lineno, TRUE);
    865999}
    8661000
     
    8691003    if (filename) {
    8701004        xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO);
     1005#if ENABLE_FEATURE_LESS_FLAGS
     1006        num_lines = REOPEN_AND_COUNT;
     1007#endif
    8711008    } else {
    8721009        /* "less" with no arguments in argv[] */
    8731010        /* For status line only */
    8741011        filename = xstrdup(bb_msg_standard_input);
     1012#if ENABLE_FEATURE_LESS_FLAGS
     1013        num_lines = REOPEN_STDIN;
     1014#endif
    8751015    }
    8761016    readpos = 0;
     
    9241064    rd = 1;
    9251065    /* Are we interested in stdin? */
    926 //TODO: reuse code for determining this
    927     if (!(option_mask32 & FLAG_S)
    928        ? !(max_fline > cur_fline + max_displayed_line)
    929        : !(max_fline >= cur_fline
    930            && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line)
    931     ) {
     1066    if (at_end()) {
    9321067        if (eof_error > 0) /* did NOT reach eof yet */
    9331068            rd = 0; /* yes, we are interested in stdin */
     
    12401375    while (i < sizeof(num_input)-1) {
    12411376        keypress = less_getch(i + 1);
    1242         if ((unsigned)keypress > 255 || !isdigit(num_input[i]))
     1377        if ((unsigned)keypress > 255 || !isdigit(keypress))
    12431378            break;
    12441379        num_input[i] = keypress;
     
    12641399        break;
    12651400    case 'g': case '<': case 'G': case '>':
    1266         cur_fline = num + max_displayed_line;
    1267         read_lines();
    1268         buffer_line(num - 1);
     1401        buffer_lineno(num - 1);
    12691402        break;
    12701403    case 'p': case '%':
    1271         num = num * (max_fline / 100); /* + max_fline / 2; */
    1272         cur_fline = num + max_displayed_line;
    1273         read_lines();
    1274         buffer_line(num);
     1404#if ENABLE_FEATURE_LESS_FLAGS
     1405        update_num_lines();
     1406        num = num * (num_lines > 0 ? num_lines : max_lineno) / 100;
     1407#else
     1408        num = num * max_lineno / 100;
     1409#endif
     1410        buffer_lineno(num);
    12751411        break;
    12761412#if ENABLE_FEATURE_LESS_REGEXP
     
    13121448        option_mask32 ^= FLAG_TILDE;
    13131449        break;
     1450#if ENABLE_FEATURE_LESS_TRUNCATE
    13141451    case 'S':
    13151452        option_mask32 ^= FLAG_S;
    13161453        buffer_fill_and_print();
    13171454        break;
     1455#endif
    13181456#if ENABLE_FEATURE_LESS_LINENUMS
    13191457    case 'N':
     
    16091747int less_main(int argc, char **argv)
    16101748{
     1749    char *tty_name;
     1750    int tty_fd;
     1751
    16111752    INIT_G();
    16121753
    1613     /* TODO: -x: do not interpret backspace, -xx: tab also */
    1614     /* -xxx: newline also */
    1615     /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */
    1616     getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S"));
     1754    /* TODO: -x: do not interpret backspace, -xx: tab also
     1755     * -xxx: newline also
     1756     * -w N: assume width N (-xxx -w 32: hex viewer of sorts)
     1757     * -s: condense many empty lines to one
     1758     *     (used by some setups for manpage display)
     1759     */
     1760    getopt32(argv, "EMmN~I" IF_FEATURE_LESS_TRUNCATE("S") /*ignored:*/"s");
    16171761    argc -= optind;
    16181762    argv += optind;
     
    16381782        empty_line_marker = "";
    16391783
    1640     kbd_fd = open(CURRENT_TTY, O_RDONLY);
    1641     if (kbd_fd < 0)
    1642         return bb_cat(argv);
    1643     ndelay_on(kbd_fd);
     1784    /* Some versions of less can survive w/o controlling tty,
     1785     * try to do the same. This also allows to specify an alternative
     1786     * tty via "less 1<>TTY".
     1787     * We don't try to use STDOUT_FILENO directly,
     1788     * since we want to set this fd to non-blocking mode,
     1789     * and not bother with restoring it on exit.
     1790     */
     1791    tty_name = xmalloc_ttyname(STDOUT_FILENO);
     1792    if (tty_name) {
     1793        tty_fd = open(tty_name, O_RDONLY);
     1794        free(tty_name);
     1795        if (tty_fd < 0)
     1796            goto try_ctty;
     1797    } else {
     1798        /* Try controlling tty */
     1799 try_ctty:
     1800        tty_fd = open(CURRENT_TTY, O_RDONLY);
     1801        if (tty_fd < 0)
     1802            return bb_cat(argv);
     1803    }
     1804    ndelay_on(tty_fd);
     1805    kbd_fd = tty_fd; /* save in a global */
    16441806
    16451807    tcgetattr(kbd_fd, &term_orig);
     
    18061968        or from within less by using the - or -- command.
    18071969        Options may be given in one of two forms: either a single
    1808         character preceded by a -, or a name preceeded by --.
     1970        character preceded by a -, or a name preceded by --.
    18091971  -?  ........  --help
    18101972                  Display help (from command line).
  • branches/3.3/mindi-busybox/miscutils/man.c

    r3232 r3621  
    6767
    6868        line = xmalloc_open_zipped_read_close(man_filename, NULL);
    69         if (!line || strncmp(line, ".so ", 4) != 0) {
     69        if (!line || !is_prefixed_with(line, ".so ")) {
    7070            free(line);
    7171            goto ordinary_manpage;
     
    103103 ordinary_manpage:
    104104    close(STDIN_FILENO);
    105     open_zipped(man_filename); /* guaranteed to use fd 0 (STDIN_FILENO) */
     105    open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */
    106106    /* "2>&1" is added so that nroff errors are shown in pager too.
    107107     * Otherwise it may show just empty screen */
    108108    cmd = xasprintf(
    109         man ? "gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s"
     109        /* replaced -Tlatin1 with -Tascii for non-UTF8 displays */
     110        man ? "gtbl | nroff -Tascii -mandoc 2>&1 | %s"
    110111            : "%s",
    111112        pager);
     
    147148}
    148149
     150static char **add_MANPATH(char **man_path_list, int *count_mp, char *path)
     151{
     152    if (path) while (*path) {
     153        char *next_path;
     154        char **path_element;
     155
     156        next_path = strchr(path, ':');
     157        if (next_path) {
     158            if (next_path == path) /* "::"? */
     159                goto next;
     160            *next_path = '\0';
     161        }
     162        /* Do we already have path? */
     163        path_element = man_path_list;
     164        if (path_element) while (*path_element) {
     165            if (strcmp(*path_element, path) == 0)
     166                goto skip;
     167            path_element++;
     168        }
     169        man_path_list = xrealloc_vector(man_path_list, 4, *count_mp);
     170        man_path_list[*count_mp] = xstrdup(path);
     171        (*count_mp)++;
     172        /* man_path_list is NULL terminated */
     173        /* man_path_list[*count_mp] = NULL; - xrealloc_vector did it */
     174 skip:
     175        if (!next_path)
     176            break;
     177        /* "path" may be a result of getenv(), be nice and don't mangle it */
     178        *next_path = ':';
     179 next:
     180        path = next_path + 1;
     181    }
     182    return man_path_list;
     183}
     184
    149185int man_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    150186int man_main(int argc UNUSED_PARAM, char **argv)
    151187{
    152188    parser_t *parser;
    153     const char *pager;
    154     char **man_path_list;
     189    const char *pager = ENABLE_LESS ? "less" : "more";
    155190    char *sec_list;
    156191    char *cur_path, *cur_sect;
    157     int count_mp, cur_mp;
     192    char **man_path_list;
     193    int count_mp;
     194    int cur_mp;
    158195    int opt, not_found;
    159196    char *token[2];
     
    163200    argv += optind;
    164201
    165     sec_list = xstrdup("1:2:3:4:5:6:7:8:9");
    166     /* Last valid man_path_list[] is [0x10] */
     202    sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9");
     203
    167204    count_mp = 0;
    168     man_path_list = xzalloc(0x11 * sizeof(man_path_list[0]));
    169     man_path_list[0] = getenv("MANPATH");
    170     if (!man_path_list[0]) /* default, may be overridden by /etc/man.conf */
     205    man_path_list = add_MANPATH(NULL, &count_mp,
     206            getenv("MANDATORY_MANPATH"+10) /* "MANPATH" */
     207    );
     208    if (!man_path_list) {
     209        /* default, may be overridden by /etc/man.conf */
     210        man_path_list = xzalloc(2 * sizeof(man_path_list[0]));
    171211        man_path_list[0] = (char*)"/usr/man";
    172     else
    173         count_mp++;
    174     pager = getenv("MANPAGER");
    175     if (!pager) {
    176         pager = getenv("PAGER");
    177         if (!pager)
    178             pager = "more";
     212        /* count_mp stays 0.
     213         * Thus, man.conf will overwrite man_path_list[0]
     214         * if a path is defined there.
     215         */
    179216    }
    180217
     
    191228        if (!token[1])
    192229            continue;
     230        if (strcmp("DEFINE", token[0]) == 0) {
     231            if (is_prefixed_with("pager", token[1])) {
     232                pager = xstrdup(skip_whitespace(token[1]) + 5);
     233            }
     234        } else
    193235        if (strcmp("MANDATORY_MANPATH"+10, token[0]) == 0 /* "MANPATH"? */
    194236         || strcmp("MANDATORY_MANPATH", token[0]) == 0
    195237        ) {
    196             char *path = token[1];
    197             while (*path) {
    198                 char *next_path;
    199                 char **path_element;
    200 
    201                 next_path = strchr(path, ':');
    202                 if (next_path) {
    203                     *next_path = '\0';
    204                     if (next_path++ == path) /* "::"? */
    205                         goto next;
    206                 }
    207                 /* Do we already have path? */
    208                 path_element = man_path_list;
    209                 while (*path_element) {
    210                     if (strcmp(*path_element, path) == 0)
    211                         goto skip;
    212                     path_element++;
    213                 }
    214                 man_path_list = xrealloc_vector(man_path_list, 4, count_mp);
    215                 man_path_list[count_mp] = xstrdup(path);
    216                 count_mp++;
    217                 /* man_path_list is NULL terminated */
    218                 /*man_path_list[count_mp] = NULL; - xrealloc_vector did it */
    219  skip:
    220                 if (!next_path)
    221                     break;
    222  next:
    223                 path = next_path;
    224             }
     238            man_path_list = add_MANPATH(man_path_list, &count_mp, token[1]);
    225239        }
    226240        if (strcmp("MANSECT", token[0]) == 0) {
     
    230244    }
    231245    config_close(parser);
     246
     247    {
     248        /* environment overrides setting from man.config */
     249        char *env_pager = getenv("MANPAGER");
     250        if (!env_pager)
     251            env_pager = getenv("PAGER");
     252        if (env_pager)
     253            pager = env_pager;
     254    }
    232255
    233256    not_found = 0;
  • branches/3.3/mindi-busybox/miscutils/microcom.c

    r3232 r3621  
    2020
    2121#include "libbb.h"
     22#include "common_bufsiz.h"
    2223
    2324// set raw tty mode
     
    156157        }
    157158        if (pfd[0].revents) {
     159            ssize_t len;
    158160#define iobuf bb_common_bufsiz1
    159             ssize_t len;
     161            setup_common_bufsiz();
    160162            // read from device -> write to stdout
    161             len = safe_read(sfd, iobuf, sizeof(iobuf));
     163            len = safe_read(sfd, iobuf, COMMON_BUFSIZE);
    162164            if (len > 0)
    163165                full_write(STDOUT_FILENO, iobuf, len);
  • branches/3.3/mindi-busybox/miscutils/nandwrite.c

    r3232 r3621  
    2424
    2525//applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP))
    26 //applet:IF_NANDWRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump))
     26//applet:IF_NANDDUMP(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump))
    2727
    2828//kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o
     
    3030
    3131//usage:#define nandwrite_trivial_usage
    32 //usage:    "[-p] [-s ADDR] MTD_DEVICE [FILE]"
     32//usage:    "[-np] [-s ADDR] MTD_DEVICE [FILE]"
    3333//usage:#define nandwrite_full_usage "\n\n"
    34 //usage:    "Write to the specified MTD device\n"
     34//usage:    "Write to MTD_DEVICE\n"
     35//usage:     "\n    -n  Write without ecc"
    3536//usage:     "\n    -p  Pad to page size"
    3637//usage:     "\n    -s ADDR Start address"
    3738
    3839//usage:#define nanddump_trivial_usage
    39 //usage:    "[-o] [-b] [-s ADDR] [-f FILE] MTD_DEVICE"
     40//usage:    "[-no]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE"
    4041//usage:#define nanddump_full_usage "\n\n"
    41 //usage:    "Dump the specified MTD device\n"
     42//usage:    "Dump MTD_DEVICE\n"
     43//usage:     "\n    -n  Read without ecc"
    4244//usage:     "\n    -o  Dump oob data"
    43 //usage:     "\n    -b  Omit bad block from the dump"
    4445//usage:     "\n    -s ADDR Start address"
    4546//usage:     "\n    -l LEN  Length"
    4647//usage:     "\n    -f FILE Dump to file ('-' for stdout)"
     48//usage:     IF_LONG_OPTS(
     49//usage:     "\n    --bb=METHOD:"
     50//usage:     "\n        skipbad: skip bad blocks"
     51//usage:     "\n        padbad: substitute bad blocks by 0xff (default)"
     52//usage:     )
    4753
    4854#include "libbb.h"
     
    5460#define OPT_p  (1 << 0) /* nandwrite only */
    5561#define OPT_o  (1 << 0) /* nanddump only */
    56 #define OPT_s  (1 << 1)
    57 #define OPT_b  (1 << 2)
     62#define OPT_n  (1 << 1)
     63#define OPT_s  (1 << 2)
    5864#define OPT_f  (1 << 3)
    5965#define OPT_l  (1 << 4)
     66#define OPT_bb (1 << 5) /* must be the last one in the list */
     67
     68#define BB_PADBAD (1 << 0)
     69#define BB_SKIPBAD (1 << 1)
    6070
    6171/* helper for writing out 0xff for bad blocks pad */
     
    6575    unsigned count;
    6676
    67     /* round len to the next page */
    68     len = (len | ~(meminfo->writesize - 1)) + 1;
     77    /* round len to the next page only if len is not already on a page */
     78    len = ((len - 1) | (meminfo->writesize - 1)) + 1;
    6979
    7080    memset(buf, 0xff, sizeof(buf));
     
    103113    unsigned char *oobbuf;
    104114    unsigned opts;
     115    unsigned bb_method = BB_SKIPBAD;
    105116    int fd;
    106117    ssize_t cnt;
     
    110121    struct mtd_oob_buf oob;
    111122    unsigned char *filebuf;
    112     const char *opt_s = "0", *opt_f = "-", *opt_l;
     123    const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb;
    113124
    114125    if (IS_NANDDUMP) {
    115126        opt_complementary = "=1";
    116         opts = getopt32(argv, "os:bf:l:", &opt_s, &opt_f, &opt_l);
     127#if ENABLE_LONG_OPTS
     128        applet_long_options =
     129            "bb\0" Required_argument "\xff"; /* no short equivalent */
     130#endif
     131        opts = getopt32(argv, "ons:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb);
    117132    } else { /* nandwrite */
    118133        opt_complementary = "-1:?2";
    119         opts = getopt32(argv, "ps:", &opt_s);
     134        opts = getopt32(argv, "pns:", &opt_s);
    120135    }
    121136    argv += optind;
     
    133148    xioctl(fd, MEMGETINFO, &meminfo);
    134149
     150    if (opts & OPT_n)
     151        xioctl(fd, MTDFILEMODE, (void *)MTD_FILE_MODE_RAW);
     152
    135153    mtdoffset = xstrtou(opt_s, 0);
    136154    if (IS_NANDDUMP && (opts & OPT_l)) {
     
    138156        if (length < meminfo.size - mtdoffset)
    139157            end_addr = mtdoffset + length;
     158    }
     159    if (IS_NANDDUMP && (opts & OPT_bb)) {
     160        if (strcmp("skipbad", opt_bb) == 0)
     161            bb_method = BB_SKIPBAD;
     162        else if (strcmp("padbad", opt_bb) == 0)
     163            bb_method = BB_PADBAD;
     164        else
     165            bb_show_usage();
    140166    }
    141167
     
    163189        if (tmp != blockstart) {
    164190            /* bad block(s), advance mtdoffset */
    165             if (IS_NANDDUMP && !(opts & OPT_b)) {
    166                 int bad_len = MIN(tmp, end_addr) - mtdoffset;
    167                 dump_bad(&meminfo, bad_len, opts & OPT_o);
     191            if (IS_NANDDUMP) {
     192                if (bb_method == BB_PADBAD) {
     193                    int bad_len = MIN(tmp, end_addr) - mtdoffset;
     194                    dump_bad(&meminfo, bad_len, opts & OPT_o);
     195                }
     196                /* with option skipbad, increase the total length */
     197                if (bb_method == BB_SKIPBAD) {
     198                    end_addr += (tmp - blockstart);
     199                }
    168200            }
    169201            mtdoffset = tmp;
     
    183215            if (IS_NANDWRITE)
    184216                printf("Writing at 0x%08x\n", mtdoffset);
    185             else if (mtdoffset > blockstart && !(opts & OPT_b)) {
    186                 int bad_len = MIN(mtdoffset, limit) - blockstart;
    187                 dump_bad(&meminfo, bad_len, opts & OPT_o);
     217            else if (mtdoffset > blockstart) {
     218                if (bb_method == BB_PADBAD) {
     219                    /* dump FF padded bad block */
     220                    int bad_len = MIN(mtdoffset, limit) - blockstart;
     221                    dump_bad(&meminfo, bad_len, opts & OPT_o);
     222                } else if (bb_method == BB_SKIPBAD) {
     223                    /* for skipbad, increase the length */
     224                    if ((end_addr + mtdoffset - blockstart) > end_addr)
     225                        end_addr += (mtdoffset - blockstart);
     226                    else
     227                        end_addr = ~0;
     228                    limit = MIN(meminfo.size, end_addr);
     229                }
    188230            }
    189231            if (mtdoffset >= limit)
  • branches/3.3/mindi-busybox/miscutils/rfkill.c

    r3232 r3621  
    77* Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88*/
     9
     10//config:config RFKILL
     11//config:   bool "rfkill"
     12//config:   default n # doesn't build on Ubuntu 9.04
     13//config:   select PLATFORM_LINUX
     14//config:   help
     15//config:     Enable/disable wireless devices.
     16//config:
     17//config:     rfkill list : list all wireless devices
     18//config:     rfkill list bluetooth : list all bluetooth devices
     19//config:     rfkill list 1 : list device corresponding to the given index
     20//config:     rfkill block|unblock wlan : block/unblock all wlan(wifi) devices
     21//config:
     22
     23//applet:IF_RFKILL(APPLET(rfkill, BB_DIR_USR_SBIN, BB_SUID_DROP))
     24
     25//kbuild:lib-$(CONFIG_RFKILL) += rfkill.o
    926
    1027//usage:#define rfkill_trivial_usage
  • branches/3.3/mindi-busybox/miscutils/runlevel.c

    r3232 r3621  
    3030int runlevel_main(int argc UNUSED_PARAM, char **argv)
    3131{
    32     struct utmp *ut;
     32    struct utmpx *ut;
    3333    char prev;
    3434
    35     if (argv[1]) utmpname(argv[1]);
     35    if (argv[1]) utmpxname(argv[1]);
    3636
    37     setutent();
    38     while ((ut = getutent()) != NULL) {
     37    setutxent();
     38    while ((ut = getutxent()) != NULL) {
    3939        if (ut->ut_type == RUN_LVL) {
    4040            prev = ut->ut_pid / 256;
     
    4242            printf("%c %c\n", prev, ut->ut_pid % 256);
    4343            if (ENABLE_FEATURE_CLEAN_UP)
    44                 endutent();
     44                endutxent();
    4545            return 0;
    4646        }
     
    5050
    5151    if (ENABLE_FEATURE_CLEAN_UP)
    52         endutent();
     52        endutxent();
    5353    return 1;
    5454}
  • branches/3.3/mindi-busybox/miscutils/setsid.c

    r3232 r3621  
    1616
    1717//usage:#define setsid_trivial_usage
    18 //usage:       "PROG ARGS"
     18//usage:       "[-c] PROG ARGS"
    1919//usage:#define setsid_full_usage "\n\n"
    2020//usage:       "Run PROG in a new session. PROG will have no controlling terminal\n"
    21 //usage:       "and will not be affected by keyboard signals (Ctrl-C etc).\n"
    22 //usage:       "See setsid(2) for details."
     21//usage:       "and will not be affected by keyboard signals (^C etc).\n"
     22//usage:     "\n    -c  Set controlling terminal to stdin"
    2323
    2424#include "libbb.h"
     
    2727int setsid_main(int argc UNUSED_PARAM, char **argv)
    2828{
    29     if (!argv[1])
    30         bb_show_usage();
     29    unsigned opt;
     30
     31    opt_complementary = "-1"; /* at least one arg */
     32    opt = getopt32(argv, "+c"); /* +: stop on first non-opt */
     33    argv += optind;
    3134
    3235    /* setsid() is allowed only when we are not a process group leader.
    3336     * Otherwise our PID serves as PGID of some existing process group
    34      * and cannot be used as PGID of a new process group. */
     37     * and cannot be used as PGID of a new process group.
     38     *
     39     * Example: setsid() below fails when run alone in interactive shell:
     40     *  $ setsid PROG
     41     * because shell's child (setsid) is put in a new process group.
     42     * But doesn't fail if shell is not interactive
     43     * (and therefore doesn't create process groups for pipes),
     44     * or if setsid is not the first process in the process group:
     45     *  $ true | setsid PROG
     46     * or if setsid is executed in backquotes (`setsid PROG`)...
     47     */
    3548    if (setsid() < 0) {
    3649        pid_t pid = fork_or_rexec(argv);
     
    4457             * does not do such trick.
    4558             */
    46             exit(EXIT_SUCCESS);
     59            return EXIT_SUCCESS;
    4760        }
    4861
     
    5265    }
    5366
    54     argv++;
     67    if (opt) {
     68        /* -c: set (with stealing) controlling tty */
     69        ioctl(0, TIOCSCTTY, 1);
     70    }
     71
    5572    BB_EXECVP_or_die(argv);
    5673}
  • branches/3.3/mindi-busybox/miscutils/taskset.c

    r3232 r3621  
    66 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    77 */
     8
     9//config:config TASKSET
     10//config:   bool "taskset"
     11//config:   default n  # doesn't build on some non-x86 targets (m68k)
     12//config:   help
     13//config:     Retrieve or set a processes's CPU affinity.
     14//config:     This requires sched_{g,s}etaffinity support in your libc.
     15//config:
     16//config:config FEATURE_TASKSET_FANCY
     17//config:   bool "Fancy output"
     18//config:   default y
     19//config:   depends on TASKSET
     20//config:   help
     21//config:     Add code for fancy output. This merely silences a compiler-warning
     22//config:     and adds about 135 Bytes. May be needed for machines with alot
     23//config:     of CPUs.
     24
     25//applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP))
     26//kbuild:lib-$(CONFIG_TASKSET) += taskset.o
    827
    928//usage:#define taskset_trivial_usage
     
    2342//usage:       "$ taskset -p 1\n"
    2443//usage:       "pid 1's current affinity mask: 3\n"
     44/*
     45 Not yet implemented:
     46 * -a/--all-tasks (affect all threads)
     47 * -c/--cpu-list  (specify CPUs via "1,3,5-7")
     48 */
    2549
    2650#include <sched.h>
     
    5276static unsigned long long from_cpuset(cpu_set_t *mask)
    5377{
    54     struct BUG_CPU_SETSIZE_is_too_small {
    55         char BUG_CPU_SETSIZE_is_too_small[
    56             CPU_SETSIZE < sizeof(int) ? -1 : 1];
    57     };
    58     char *p = (void*)mask;
    59 
    60     /* Take the least significant bits. Careful!
    61      * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases
     78    BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int));
     79
     80    /* Take the least significant bits. Assume cpu_set_t is
     81     * implemented as an array of unsigned long or unsigned
     82     * int.
    6283     */
    63 #if BB_BIG_ENDIAN
    64     /* For big endian, it means LAST bits */
    65     if (CPU_SETSIZE < sizeof(long))
    66         p += CPU_SETSIZE - sizeof(int);
    67     else if (CPU_SETSIZE < sizeof(long long))
    68         p += CPU_SETSIZE - sizeof(long);
    69     else
    70         p += CPU_SETSIZE - sizeof(long long);
    71 #endif
    72     if (CPU_SETSIZE < sizeof(long))
    73         return *(unsigned*)p;
    74     if (CPU_SETSIZE < sizeof(long long))
    75         return *(unsigned long*)p;
    76     return *(unsigned long long*)p;
     84    if (CPU_SETSIZE < 8*sizeof(long))
     85        return *(unsigned*)mask;
     86    if (CPU_SETSIZE < 8*sizeof(long long))
     87        return *(unsigned long*)mask;
     88# if BB_BIG_ENDIAN
     89    if (sizeof(long long) > sizeof(long)) {
     90        /* We can put two long in the long long, but they have to
     91         * be swapped: the least significant word comes first in the
     92         * array */
     93        unsigned long *p = (void*)mask;
     94        return p[0] + ((unsigned long long)p[1] << (8*sizeof(long)));
     95    }
     96# endif
     97    return *(unsigned long long*)mask;
    7798}
    7899#endif
     
    129150    }
    130151
    131     { /* Affinity was specified, translate it into cpu_set_t */
     152    /* Affinity was specified, translate it into cpu_set_t */
     153    CPU_ZERO(&mask);
     154    if (!ENABLE_FEATURE_TASKSET_FANCY) {
    132155        unsigned i;
     156        unsigned long long m;
     157
    133158        /* Do not allow zero mask: */
    134         unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
    135         enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 };
    136 
    137         CPU_ZERO(&mask);
    138         for (i = 0; i < CNT_BIT; i++) {
    139             unsigned long long bit = (1ULL << i);
    140             if (bit & m)
     159        m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
     160        i = 0;
     161        do {
     162            if (m & 1)
    141163                CPU_SET(i, &mask);
     164            i++;
     165            m >>= 1;
     166        } while (m != 0);
     167    } else {
     168        unsigned i;
     169        char *last_byte;
     170        char *bin;
     171        uint8_t bit_in_byte;
     172
     173        /* Cheap way to get "long enough" buffer */
     174        bin = xstrdup(aff);
     175
     176        if (aff[0] != '0' || (aff[1]|0x20) != 'x') {
     177/* TODO: decimal/octal masks are still limited to 2^64 */
     178            unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
     179            bin += strlen(bin);
     180            last_byte = bin - 1;
     181            while (m) {
     182                *--bin = m & 0xff;
     183                m >>= 8;
     184            }
     185        } else {
     186            /* aff is "0x.....", we accept very long masks in this form */
     187            last_byte = hex2bin(bin, aff + 2, INT_MAX);
     188            if (!last_byte) {
     189 bad_aff:
     190                bb_error_msg_and_die("bad affinity '%s'", aff);
     191            }
     192            last_byte--; /* now points to the last byte */
     193        }
     194
     195        i = 0;
     196        bit_in_byte = 1;
     197        while (last_byte >= bin) {
     198            if (bit_in_byte & *last_byte) {
     199                if (i >= CPU_SETSIZE)
     200                    goto bad_aff;
     201                CPU_SET(i, &mask);
     202                //bb_error_msg("bit %d set", i);
     203            }
     204            i++;
     205            /* bit_in_byte is uint8_t! & 0xff is implied */
     206            bit_in_byte = (bit_in_byte << 1);
     207            if (!bit_in_byte) {
     208                bit_in_byte = 1;
     209                last_byte--;
     210            }
    142211        }
    143212    }
  • branches/3.3/mindi-busybox/miscutils/wall.c

    r3232 r3621  
    66 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    77 */
     8
     9//config:config WALL
     10//config:   bool "wall"
     11//config:   default y
     12//config:   depends on FEATURE_UTMP
     13//config:   help
     14//config:     Write a message to all users that are logged in.
     15
     16/* Needs to be run by root or be suid root - needs to write to /dev/TTY: */
     17//applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE))
     18
     19//kbuild:lib-$(CONFIG_WALL) += wall.o
    820
    921//usage:#define wall_trivial_usage
     
    2133int wall_main(int argc UNUSED_PARAM, char **argv)
    2234{
    23     struct utmp *ut;
     35    struct utmpx *ut;
    2436    char *msg;
    25     int fd = argv[1] ? xopen(argv[1], O_RDONLY) : STDIN_FILENO;
     37    int fd;
    2638
     39    fd = STDIN_FILENO;
     40    if (argv[1]) {
     41        /* The applet is setuid.
     42         * Access to the file must be under user's uid/gid.
     43         */
     44        fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid());
     45    }
    2746    msg = xmalloc_read(fd, NULL);
    2847    if (ENABLE_FEATURE_CLEAN_UP && argv[1])
    2948        close(fd);
    30     setutent();
    31     while ((ut = getutent()) != NULL) {
     49    setutxent();
     50    while ((ut = getutxent()) != NULL) {
    3251        char *line;
    3352        if (ut->ut_type != USER_PROCESS)
     
    3857    }
    3958    if (ENABLE_FEATURE_CLEAN_UP) {
    40         endutent();
     59        endutxent();
    4160        free(msg);
    4261    }
Note: See TracChangeset for help on using the changeset viewer.