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

in the future for sure)

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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/loginutils/getty.c

    r902 r1770  
    11/* vi: set sw=4 ts=4: */
    22/* agetty.c - another getty program for Linux. By W. Z. Venema 1989
    3    Ported to Linux by Peter Orbaek <poe@daimi.aau.dk>
    4    This program is freely distributable. The entire man-page used to
    5    be here. Now read the real man-page agetty.8 instead.
    6 
    7    -f option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95
    8 
    9    1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
    10    - added Native Language Support
    11 
    12    1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net>
    13    - enable hardware flow control before displaying /etc/issue
    14 
    15 */
    16 
    17 #include <stdio.h>
    18 #include <stdlib.h>
    19 #include <unistd.h>
    20 #include <string.h>
    21 #include <sys/ioctl.h>
    22 #include <errno.h>
    23 #include <sys/stat.h>
    24 #include <signal.h>
    25 #include <fcntl.h>
    26 #include <stdarg.h>
    27 #include <ctype.h>
    28 #include <getopt.h>
    29 #include <termios.h>
    30 #include "busybox.h"
    31 
    32 #ifdef CONFIG_FEATURE_UTMP
     3 * Ported to Linux by Peter Orbaek <poe@daimi.aau.dk>
     4 * This program is freely distributable. The entire man-page used to
     5 * be here. Now read the real man-page agetty.8 instead.
     6 *
     7 * option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95
     8 *
     9 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
     10 * - added Native Language Support
     11
     12 * 1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net>
     13 * - enable hardware flow control before displaying /etc/issue
     14 *
     15 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     16 *
     17 */
     18
     19#include "libbb.h"
     20#include <syslog.h>
     21
     22#if ENABLE_FEATURE_UTMP
    3323#include <utmp.h>
    3424#endif
    3525
    36 #define _PATH_LOGIN     "/bin/login"
    37 
    38  /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */
    39 #ifdef CONFIG_SYSLOGD
    40 #include <sys/param.h>
    41 #include <syslog.h>
    42 #endif
    43 
    44 
    45  /*
    46   * Some heuristics to find out what environment we are in: if it is not
    47   * System V, assume it is SunOS 4.
    48   */
    49 
     26/*
     27 * Some heuristics to find out what environment we are in: if it is not
     28 * System V, assume it is SunOS 4.
     29 */
    5030#ifdef LOGIN_PROCESS                    /* defined in System V utmp.h */
    5131#define SYSV_STYLE                      /* select System V style getty */
    52 #ifdef CONFIG_FEATURE_WTMP
    53 extern void updwtmp(const char *filename, const struct utmp *ut);
    54 #endif
    55 #endif  /* LOGIN_PROCESS */
    56 
    57  /*
    58   * Things you may want to modify.
    59   *
    60   * You may disagree with the default line-editing etc. characters defined
    61   * below. Note, however, that DEL cannot be used for interrupt generation
    62   * and for line editing at the same time.
    63   */
    64 
    65 #ifdef  SYSV_STYLE
    6632#include <sys/utsname.h>
    6733#include <time.h>
    68 #endif
    69 
    70  /* If ISSUE is not defined, agetty will never display the contents of the
    71   * /etc/issue file. You will not want to spit out large "issue" files at the
    72   * wrong baud rate.
    73   */
     34#if ENABLE_FEATURE_WTMP
     35extern void updwtmp(const char *filename, const struct utmp *ut);
     36static void update_utmp(const char *line);
     37#endif
     38#endif  /* LOGIN_PROCESS */
     39
     40/*
     41 * Things you may want to modify.
     42 *
     43 * You may disagree with the default line-editing etc. characters defined
     44 * below. Note, however, that DEL cannot be used for interrupt generation
     45 * and for line editing at the same time.
     46 */
     47
     48/* I doubt there are systems which still need this */
     49#undef HANDLE_ALLCAPS
     50
     51#define _PATH_LOGIN "/bin/login"
     52
     53/* If ISSUE is not defined, getty will never display the contents of the
     54 * /etc/issue file. You will not want to spit out large "issue" files at the
     55 * wrong baud rate.
     56 */
    7457#define ISSUE "/etc/issue"              /* displayed before the login prompt */
    7558
    7659/* Some shorthands for control characters. */
    77 
    7860#define CTL(x)          (x ^ 0100)      /* Assumes ASCII dialect */
    7961#define CR              CTL('M')        /* carriage return */
     
    8365
    8466/* Defaults for line-editing etc. characters; you may want to change this. */
    85 
    8667#define DEF_ERASE       DEL             /* default erase character */
    8768#define DEF_INTR        CTL('C')        /* default interrupt character */
     
    9273#define DEF_SWITCH      0               /* default switch char */
    9374
    94  /*
    95   * SunOS 4.1.1 termio is broken. We must use the termios stuff instead,
    96   * because the termio -> termios translation does not clear the termios
    97   * CIBAUD bits. Therefore, the tty driver would sometimes report that input
    98   * baud rate != output baud rate. I did not notice that problem with SunOS
    99   * 4.1. We will use termios where available, and termio otherwise.
    100   */
    101 
    102 /* linux 0.12 termio is broken too, if we use it c_cc[VERASE] isn't set
    103    properly, but all is well if we use termios?! */
    104 
    105 #ifdef  TCGETS
    106 #undef  TCGETA
    107 #undef  TCSETA
    108 #undef  TCSETAW
    109 #define termio  termios
    110 #define TCGETA  TCGETS
    111 #define TCSETA  TCSETS
    112 #define TCSETAW TCSETSW
    113 #endif
    114 
    115  /*
    116   * When multiple baud rates are specified on the command line, the first one
    117   * we will try is the first one specified.
    118   */
    119 
     75/*
     76 * When multiple baud rates are specified on the command line, the first one
     77 * we will try is the first one specified.
     78 */
    12079#define FIRST_SPEED     0
    12180
     
    12685struct options {
    12786    int flags;                      /* toggle switches, see below */
    128     int timeout;                    /* time-out period */
    129     char *login;                    /* login program */
    130     char *tty;                      /* name of tty */
    131     char *initstring;               /* modem init string */
    132     char *issue;                    /* alternative issue file */
     87    unsigned timeout;               /* time-out period */
     88    const char *login;                    /* login program */
     89    const char *tty;                      /* name of tty */
     90    const char *initstring;               /* modem init string */
     91    const char *issue;                    /* alternative issue file */
    13392    int numspeed;                   /* number of baud rates to try */
    13493    int speeds[MAX_SPEED];          /* baud rates to be tried */
    13594};
    13695
    137 static const char opt_string[] = "I:LH:f:hil:mt:wn";
     96static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn";
    13897#define F_INITSTRING    (1<<0)          /* initstring is set */
    13998#define F_LOCAL         (1<<1)          /* force local */
     
    149108
    150109/* Storage for things detected while the login name was read. */
    151 
    152110struct chardata {
    153     int erase;                      /* erase character */
    154     int kill;                       /* kill character */
    155     int eol;                        /* end-of-line character */
    156     int parity;                     /* what parity did we see */
    157     int capslock;                   /* upper case without lower case */
     111    unsigned char erase;    /* erase character */
     112    unsigned char kill;     /* kill character */
     113    unsigned char eol;      /* end-of-line character */
     114    unsigned char parity;   /* what parity did we see */
     115#ifdef HANDLE_ALLCAPS
     116    unsigned char capslock; /* upper case without lower case */
     117#endif
    158118};
    159119
    160120/* Initial values for the above. */
    161 
    162 static struct chardata init_chardata = {
     121static const struct chardata init_chardata = {
    163122    DEF_ERASE,                              /* default erase character */
    164123    DEF_KILL,                               /* default kill character */
    165124    13,                                     /* default eol char */
    166125    0,                                      /* space parity */
     126#ifdef HANDLE_ALLCAPS
    167127    0,                                      /* no capslock */
     128#endif
    168129};
    169 
    170 #if 0
    171 struct Speedtab {
    172     long speed;
    173     int code;
    174 };
    175 
    176 static struct Speedtab speedtab[] = {
    177     {50, B50},
    178     {75, B75},
    179     {110, B110},
    180     {134, B134},
    181     {150, B150},
    182     {200, B200},
    183     {300, B300},
    184     {600, B600},
    185     {1200, B1200},
    186     {1800, B1800},
    187     {2400, B2400},
    188     {4800, B4800},
    189     {9600, B9600},
    190 #ifdef  B19200
    191     {19200, B19200},
    192 #endif
    193 #ifdef  B38400
    194     {38400, B38400},
    195 #endif
    196 #ifdef  EXTA
    197     {19200, EXTA},
    198 #endif
    199 #ifdef  EXTB
    200     {38400, EXTB},
    201 #endif
    202 #ifdef B57600
    203     {57600, B57600},
    204 #endif
    205 #ifdef B115200
    206     {115200, B115200},
    207 #endif
    208 #ifdef B230400
    209     {230400, B230400},
    210 #endif
    211     {0, 0},
    212 };
    213 #endif
    214 
    215 
    216 #ifdef  SYSV_STYLE
    217 #ifdef CONFIG_FEATURE_UTMP
    218 static void update_utmp(char *line);
    219 #endif
    220 #endif
    221130
    222131/* The following is used for understandable diagnostics. */
     
    229138#define debug(s) fprintf(dbf,s); fflush(dbf)
    230139#define DEBUGTERM "/dev/ttyp0"
    231 FILE *dbf;
     140static FILE *dbf;
    232141#else
    233 #define debug(s)                                /* nothing */
    234 #endif
    235 
    236 
    237 /*
    238  * output error messages
    239  */
    240 static void error(const char *fmt, ...) ATTRIBUTE_NORETURN;
    241 static void error(const char *fmt, ...)
    242 {
    243     va_list va_alist;
    244     char buf[256];
    245 
    246 #ifdef CONFIG_SYSLOGD
    247     va_start(va_alist, fmt);
    248     vsnprintf(buf, sizeof(buf), fmt, va_alist);
    249     openlog(bb_applet_name, 0, LOG_AUTH);
    250     syslog(LOG_ERR, "%s", buf);
    251     closelog();
    252 #else
    253     int fd;
    254     size_t l;
    255 
    256     snprintf(buf, sizeof(buf), "%s: ", bb_applet_name);
    257     l = strlen(buf);
    258     va_start(va_alist, fmt);
    259     vsnprintf(buf + l, sizeof(buf) - l, fmt, va_alist);
    260     l = strlen(buf);
    261     /* truncate if need */
    262     if((l + 3) > sizeof(buf))
    263         l = sizeof(buf) - 3;
    264     /* add \r\n always */
    265     buf[l++] = '\r';
    266     buf[l++] = '\n';
    267     buf[l] = 0;
    268     if ((fd = open("/dev/console", 1)) >= 0) {
    269         write(fd, buf, l);
    270         close(fd);
    271     }
    272 #endif
    273 
    274     va_end(va_alist);
    275 
    276     (void) sleep((unsigned) 10);    /* be kind to init(8) */
    277     exit(1);
    278 }
    279 
     142#define debug(s) /* nothing */
     143#endif
    280144
    281145
     
    284148{
    285149    int r;
    286     unsigned long value;
    287     if (safe_strtoul((char *)s, &value)) {
     150    unsigned value = bb_strtou(s, NULL, 10);
     151    if (errno) {
    288152        return -1;
    289153    }
    290     if ((r = tty_value_to_baud(value)) > 0) {
     154    r = tty_value_to_baud(value);
     155    if (r > 0) {
    291156        return r;
    292157    }
     
    303168    for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) {
    304169        if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0)
    305             error("bad speed: %s", cp);
     170            bb_error_msg_and_die("bad speed: %s", cp);
    306171        if (op->numspeed > MAX_SPEED)
    307             error("too many alternate speeds");
     172            bb_error_msg_and_die("too many alternate speeds");
    308173    }
    309174    debug("exiting parsespeeds\n");
     
    311176
    312177
    313 /* parse-args - parse command-line arguments */
     178/* parse_args - parse command-line arguments */
    314179static void parse_args(int argc, char **argv, struct options *op)
    315180{
    316181    char *ts;
    317182
    318     op->flags = bb_getopt_ulflags(argc, argv, opt_string,
     183    op->flags = getopt32(argv, opt_string,
    319184        &(op->initstring), &fakehost, &(op->issue),
    320185        &(op->login), &ts);
    321     if(op->flags & F_INITSTRING) {
     186    if (op->flags & F_INITSTRING) {
    322187        const char *p = op->initstring;
    323188        char *q;
    324189
    325         q = op->initstring = bb_xstrdup(op->initstring);
     190        op->initstring = q = xstrdup(op->initstring);
    326191        /* copy optarg into op->initstring decoding \ddd
    327192           octal codes into chars */
     
    337202    }
    338203    op->flags ^= F_ISSUE;           /* revert flag show /etc/issue */
    339     if(op->flags & F_TIMEOUT) {
    340         if ((op->timeout = atoi(ts)) <= 0)
    341             error("bad timeout value: %s", ts);
    342     }
     204    if (op->flags & F_TIMEOUT) {
     205        op->timeout = xatoul_range(ts, 1, INT_MAX);
     206    }
     207    argv += optind;
     208    argc -= optind;
    343209    debug("after getopt loop\n");
    344     if (argc < optind + 2)          /* check parameter count */
     210    if (argc < 2)          /* check parameter count */
    345211        bb_show_usage();
    346212
    347213    /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */
    348     if ('0' <= argv[optind][0] && argv[optind][0] <= '9') {
     214    if (isdigit(argv[0][0])) {
    349215        /* a number first, assume it's a speed (BSD style) */
    350         parse_speeds(op, argv[optind++]);       /* baud rate(s) */
    351         op->tty = argv[optind]; /* tty name */
     216        parse_speeds(op, argv[0]);       /* baud rate(s) */
     217        op->tty = argv[1]; /* tty name */
    352218    } else {
    353         op->tty = argv[optind++];       /* tty name */
    354         parse_speeds(op, argv[optind]); /* baud rate(s) */
    355     }
    356 
    357     optind++;
    358     if (argc > optind && argv[optind])
    359         setenv("TERM", argv[optind], 1);
     219        op->tty = argv[0];       /* tty name */
     220        parse_speeds(op, argv[1]); /* baud rate(s) */
     221    }
     222
     223    if (argv[2])
     224        setenv("TERM", argv[2], 1);
    360225
    361226    debug("exiting parseargs\n");
     
    363228
    364229/* open_tty - set up tty as standard { input, output, error } */
    365 static void open_tty(char *tty, struct termio *tp, int local)
     230static void open_tty(const char *tty, struct termios *tp, int local)
    366231{
    367232    int chdir_to_root = 0;
    368233
    369234    /* Set up new standard input, unless we are given an already opened port. */
    370 
    371     if (strcmp(tty, "-")) {
     235    if (NOT_LONE_DASH(tty)) {
    372236        struct stat st;
    373237        int fd;
    374238
    375239        /* Sanity checks... */
    376 
    377         if (chdir("/dev"))
    378             error("/dev: chdir() failed: %m");
     240        xchdir("/dev");
    379241        chdir_to_root = 1;
    380         if (stat(tty, &st) < 0)
    381             error("/dev/%s: %m", tty);
     242        xstat(tty, &st);
    382243        if ((st.st_mode & S_IFMT) != S_IFCHR)
    383             error("/dev/%s: not a character device", tty);
     244            bb_error_msg_and_die("%s: not a character device", tty);
    384245
    385246        /* Open the tty as standard input. */
    386 
    387         close(0);
    388247        debug("open(2)\n");
    389         fd = open(tty, O_RDWR | O_NONBLOCK, 0);
    390         if (fd != 0)
    391             error("/dev/%s: cannot open as standard input: %m", tty);
     248        fd = xopen(tty, O_RDWR | O_NONBLOCK);
     249        xdup2(fd, 0);
     250        while (fd > 2)
     251            close(fd--);
    392252    } else {
    393 
    394253        /*
    395254         * Standard input should already be connected to an open port. Make
    396255         * sure it is open for read/write.
    397256         */
    398 
    399         if ((fcntl(0, F_GETFL, 0) & O_RDWR) != O_RDWR)
    400             error("%s: not open for read/write", tty);
     257        if ((fcntl(0, F_GETFL) & O_RDWR) != O_RDWR)
     258            bb_error_msg_and_die("stdin is not open for read/write");
    401259    }
    402260
    403261    /* Replace current standard output/error fd's with new ones */
    404262    debug("duping\n");
    405     if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 ||
    406         dup2(STDIN_FILENO, STDERR_FILENO) == -1)
    407         error("%s: dup problem: %m", tty);      /* we have a problem */
     263    xdup2(0, 1);
     264    xdup2(0, 2);
    408265
    409266    /*
     
    415272     * 5 seconds seems to be a good value.
    416273     */
    417 
    418     if (ioctl(0, TCGETA, tp) < 0)
    419         error("%s: ioctl: %m", tty);
     274    ioctl_or_perror_and_die(0, TCGETS, tp, "%s: TCGETS", tty);
    420275
    421276    /*
     
    427282
    428283#ifdef DEBIAN
     284#warning Debian /dev/vcs[a]NN hack is deprecated and will be removed
    429285    {
    430286        /* tty to root.dialout 660 */
     
    432288        int id;
    433289
    434         id = (gr = getgrnam("dialout")) ? gr->gr_gid : 0;
     290        gr = getgrnam("dialout");
     291        id = gr ? gr->gr_gid : 0;
    435292        chown(tty, 0, id);
    436293        chmod(tty, 0660);
     
    440297            char *vcs, *vcsa;
    441298
    442             if (!(vcs = strdup(tty)))
    443                 error("Can't malloc for vcs");
    444             if (!(vcsa = malloc(strlen(tty) + 2)))
    445                 error("Can't malloc for vcsa");
     299            vcs = xstrdup(tty);
     300            vcsa = xmalloc(strlen(tty) + 2);
    446301            strcpy(vcs, "vcs");
    447302            strcpy(vcs + 3, tty + 3);
     
    449304            strcpy(vcsa + 4, tty + 3);
    450305
    451             id = (gr = getgrnam("sys")) ? gr->gr_gid : 0;
     306            gr = getgrnam("sys");
     307            id = gr ? gr->gr_gid : 0;
    452308            chown(vcs, 0, id);
    453309            chmod(vcs, 0600);
     
    460316    }
    461317#else
    462     (void) chown(tty, 0, 0);        /* root, sys */
    463     (void) chmod(tty, 0622);        /* crw--w--w- */
    464 #endif
    465     if(chdir_to_root && chdir("/"))
    466         error("chdir to / failed: %m");
    467 }
    468 
    469 /* termio_init - initialize termio settings */
    470 static void termio_init(struct termio *tp, int speed, struct options *op)
     318    if (NOT_LONE_DASH(tty)) {
     319        chown(tty, 0, 0);        /* 0:0 */
     320        chmod(tty, 0622);        /* crw--w--w- */
     321    }
     322#endif
     323    if (chdir_to_root)
     324        xchdir("/");
     325}
     326
     327/* termios_init - initialize termios settings */
     328static void termios_init(struct termios *tp, int speed, struct options *op)
    471329{
    472330    /*
    473      * Initial termio settings: 8-bit characters, raw-mode, blocking i/o.
     331     * Initial termios settings: 8-bit characters, raw-mode, blocking i/o.
    474332     * Special characters are set after we have read the login name; all
    475333     * reads will be done in raw mode anyway. Errors will be dealt with
    476      * lateron.
     334     * later on.
    477335     */
    478336#ifdef __linux__
    479337    /* flush input and output queues, important for modems! */
    480     (void) ioctl(0, TCFLSH, TCIOFLUSH);
     338    ioctl(0, TCFLSH, TCIOFLUSH);
    481339#endif
    482340
     
    498356#endif
    499357
    500     (void) ioctl(0, TCSETA, tp);
     358    ioctl(0, TCSETS, tp);
    501359
    502360    /* go to blocking input even in local mode */
    503     fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NONBLOCK);
     361    ndelay_off(0);
    504362
    505363    debug("term_io 2\n");
     
    507365
    508366/* auto_baud - extract baud rate from modem status message */
    509 static void auto_baud(struct termio *tp)
     367static void auto_baud(char *buf, unsigned size_buf, struct termios *tp)
    510368{
    511369    int speed;
    512370    int vmin;
    513371    unsigned iflag;
    514     char buf[BUFSIZ];
    515372    char *bp;
    516373    int nread;
     
    533390    /*
    534391     * Use 7-bit characters, don't block if input queue is empty. Errors will
    535      * be dealt with lateron.
     392     * be dealt with later on.
    536393     */
    537394
     
    540397    vmin = tp->c_cc[VMIN];
    541398    tp->c_cc[VMIN] = 0;                     /* don't block if queue empty */
    542     (void) ioctl(0, TCSETA, tp);
     399    ioctl(0, TCSETS, tp);
    543400
    544401    /*
     
    547404     */
    548405
    549     (void) sleep(1);
    550     if ((nread = read(0, buf, sizeof(buf) - 1)) > 0) {
     406    sleep(1);
     407    nread = read(0, buf, size_buf - 1);
     408    if (nread > 0) {
    551409        buf[nread] = '\0';
    552410        for (bp = buf; bp < buf + nread; bp++) {
    553411            if (isascii(*bp) && isdigit(*bp)) {
    554                 if ((speed = bcode(bp))) {
     412                speed = bcode(bp);
     413                if (speed) {
    555414                    tp->c_cflag &= ~CBAUD;
    556415                    tp->c_cflag |= speed;
     
    560419        }
    561420    }
    562     /* Restore terminal settings. Errors will be dealt with lateron. */
     421    /* Restore terminal settings. Errors will be dealt with later on. */
    563422
    564423    tp->c_iflag = iflag;
    565424    tp->c_cc[VMIN] = vmin;
    566     (void) ioctl(0, TCSETA, tp);
     425    ioctl(0, TCSETS, tp);
    567426}
    568427
    569428/* next_speed - select next baud rate */
    570 static void next_speed(struct termio *tp, struct options *op)
     429static void next_speed(struct termios *tp, struct options *op)
    571430{
    572431    static int baud_index = FIRST_SPEED;    /* current speed index */
     
    575434    tp->c_cflag &= ~CBAUD;
    576435    tp->c_cflag |= op->speeds[baud_index];
    577     (void) ioctl(0, TCSETA, tp);
     436    ioctl(0, TCSETS, tp);
    578437}
    579438
    580439
    581440/* do_prompt - show login prompt, optionally preceded by /etc/issue contents */
    582 static void do_prompt(struct options *op, struct termio *tp)
    583 {
    584 #ifdef  ISSUE                                   /* optional: show /etc/issue */
     441static void do_prompt(struct options *op, struct termios *tp)
     442{
     443#ifdef ISSUE
    585444    print_login_issue(op->issue, op->tty);
    586445#endif
     
    588447}
    589448
     449#ifdef HANDLE_ALLCAPS
    590450/* caps_lock - string contains upper case without lower case */
    591451/* returns 1 if true, 0 if false */
    592452static int caps_lock(const char *s)
    593453{
    594     int capslock;
    595 
    596     for (capslock = 0; *s; s++) {
    597         if (islower(*s))
    598             return (0);
    599         if (capslock == 0)
    600             capslock = isupper(*s);
    601     }
    602     return (capslock);
    603 }
    604 
    605 #define logname bb_common_bufsiz1
     454    while (*s)
     455        if (islower(*s++))
     456            return 0;
     457    return 1;
     458}
     459#endif
     460
    606461/* get_logname - get user name, establish parity, speed, erase, kill, eol */
    607462/* return NULL on failure, logname on success */
    608 static char *get_logname(struct options *op, struct chardata *cp, struct termio *tp)
     463static char *get_logname(char *logname, unsigned size_logname,
     464        struct options *op, struct chardata *cp, struct termios *tp)
    609465{
    610466    char *bp;
     
    613469    int bits;                       /* # of "1" bits per character */
    614470    int mask;                       /* mask with 1 bit up */
    615     static char *erase[] = {        /* backspace-space-backspace */
     471    static const char erase[][3] = {    /* backspace-space-backspace */
    616472        "\010\040\010",                 /* space parity */
    617473        "\010\040\010",                 /* odd parity */
     
    626482    /* Flush pending input (esp. after parsing or switching the baud rate). */
    627483
    628     (void) sleep(1);
    629     (void) ioctl(0, TCFLSH, TCIFLUSH);
     484    sleep(1);
     485    ioctl(0, TCFLSH, TCIFLUSH);
    630486
    631487    /* Prompt for and read a login name. */
    632488
    633     for (*logname = 0; *logname == 0; /* void */ ) {
     489    logname[0] = '\0';
     490    while (!logname[0]) {
    634491
    635492        /* Write issue file and prompt, with "parity" bit == 0. */
     
    639496        /* Read name, watch for break, parity, erase, kill, end-of-line. */
    640497
    641         for (bp = logname, cp->eol = 0; cp->eol == 0; /* void */ ) {
     498        bp = logname;
     499        cp->eol = '\0';
     500        while (cp->eol == '\0') {
    642501
    643502            /* Do not report trivial EINTR/EIO errors. */
    644 
    645503            if (read(0, &c, 1) < 1) {
    646504                if (errno == EINTR || errno == EIO)
    647505                    exit(0);
    648                 error("%s: read: %m", op->tty);
     506                bb_perror_msg_and_die("%s: read", op->tty);
    649507            }
     508
    650509            /* Do BREAK handling elsewhere. */
    651 
    652             if ((c == 0) && op->numspeed > 1)
    653                 /* return (0); */
     510            if (c == '\0' && op->numspeed > 1)
    654511                return NULL;
    655512
    656513            /* Do parity bit handling. */
    657 
    658             if (c != (ascval = (c & 0177))) {       /* "parity" bit on ? */
    659                 for (bits = 1, mask = 1; mask & 0177; mask <<= 1)
     514            ascval = c & 0177;
     515            if (c != ascval) {       /* "parity" bit on ? */
     516                bits = 1;
     517                mask = 1;
     518                while (mask & 0177) {
    660519                    if (mask & ascval)
    661520                        bits++; /* count "1" bits */
    662                 cp->parity |= ((bits & 1) ? 1 : 2);
     521                    mask <<= 1;
     522                }
     523                /* ... |= 2 - even, 1 - odd */
     524                cp->parity |= 2 - (bits & 1);
    663525            }
     526
    664527            /* Do erase, kill and end-of-line processing. */
    665 
    666528            switch (ascval) {
    667529            case CR:
    668530            case NL:
    669                 *bp = 0;                /* terminate logname */
     531                *bp = '\0';             /* terminate logname */
    670532                cp->eol = ascval;       /* set end-of-line char */
    671533                break;
     
    675537                cp->erase = ascval;     /* set erase character */
    676538                if (bp > logname) {
    677                     (void) write(1, erase[cp->parity], 3);
     539                    write(1, erase[cp->parity], 3);
    678540                    bp--;
    679541                }
     
    683545                cp->kill = ascval;      /* set kill character */
    684546                while (bp > logname) {
    685                     (void) write(1, erase[cp->parity], 3);
     547                    write(1, erase[cp->parity], 3);
    686548                    bp--;
    687549                }
     
    691553            default:
    692554                if (!isascii(ascval) || !isprint(ascval)) {
    693                     /* ignore garbage characters */ ;
    694                 } else if (bp - logname >= sizeof(logname) - 1) {
    695                     error("%s: input overrun", op->tty);
     555                    /* ignore garbage characters */
     556                } else if (bp - logname >= size_logname - 1) {
     557                    bb_error_msg_and_die("%s: input overrun", op->tty);
    696558                } else {
    697                     (void) write(1, &c, 1); /* echo the character */
     559                    write(1, &c, 1); /* echo the character */
    698560                    *bp++ = ascval; /* and store it */
    699561                }
     
    704566    /* Handle names with upper case and no lower case. */
    705567
    706     if ((cp->capslock = caps_lock(logname))) {
     568#ifdef HANDLE_ALLCAPS
     569    cp->capslock = caps_lock(logname);
     570    if (cp->capslock) {
    707571        for (bp = logname; *bp; bp++)
    708572            if (isupper(*bp))
    709573                *bp = tolower(*bp);     /* map name to lower case */
    710574    }
    711     return (logname);
    712 }
    713 
    714 /* termio_final - set the final tty mode bits */
    715 static void termio_final(struct options *op, struct termio *tp, struct chardata *cp)
     575#endif
     576    return logname;
     577}
     578
     579/* termios_final - set the final tty mode bits */
     580static void termios_final(struct options *op, struct termios *tp, struct chardata *cp)
    716581{
    717582    /* General terminal-independent stuff. */
     
    754619        break;
    755620    }
     621
    756622    /* Account for upper case without lower case. */
    757 
     623#ifdef HANDLE_ALLCAPS
    758624    if (cp->capslock) {
    759625        tp->c_iflag |= IUCLC;
     
    761627        tp->c_oflag |= OLCUC;
    762628    }
     629#endif
    763630    /* Optionally enable hardware flow control */
    764631
     
    770637    /* Finally, make the new settings effective */
    771638
    772     if (ioctl(0, TCSETA, tp) < 0)
    773         error("%s: ioctl: TCSETA: %m", op->tty);
    774 }
    775 
    776 
    777 #ifdef  SYSV_STYLE
    778 #ifdef CONFIG_FEATURE_UTMP
     639    ioctl_or_perror_and_die(0, TCSETS, tp, "%s: TCSETS", op->tty);
     640}
     641
     642
     643#ifdef SYSV_STYLE
     644#if ENABLE_FEATURE_UTMP
    779645/* update_utmp - update our utmp entry */
    780 static void update_utmp(char *line)
     646static void update_utmp(const char *line)
    781647{
    782648    struct utmp ut;
     
    784650    time_t t;
    785651    int mypid = getpid();
    786 #if ! (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1))
    787     struct flock lock;
    788 #endif
    789652
    790653    /*
     
    802665    setutent();
    803666    while ((utp = getutent())
    804            && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid))  /* nothing */
    805         ;
     667           && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid))
     668        /* nothing */;
    806669
    807670    if (utp) {
     
    812675        safe_strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
    813676    }
    814     /*endutent(); */
     677    /* endutent(); */
    815678
    816679    strcpy(ut.ut_user, "LOGIN");
     
    826689    endutent();
    827690
    828 #ifdef CONFIG_FEATURE_WTMP
     691#if ENABLE_FEATURE_WTMP
    829692    if (access(bb_path_wtmp_file, R_OK|W_OK) == -1)
    830693        close(creat(bb_path_wtmp_file, 0664));
     
    837700
    838701
    839 #undef logname
     702int getty_main(int argc, char **argv);
    840703int getty_main(int argc, char **argv)
    841704{
     705    int nullfd;
    842706    char *logname = NULL;           /* login name, given to /bin/login */
     707    /* Merging these into "struct local" may _seem_ to reduce
     708     * parameter passing, but today's gcc will inline
     709     * statics which are called once anyway, so don't do that */
    843710    struct chardata chardata;       /* set by get_logname() */
    844     struct termio termio;           /* terminal mode bits */
    845     static struct options options = {
     711    struct termios termios;           /* terminal mode bits */
     712    struct options options = {
    846713        0,                      /* show /etc/issue (SYSV_STYLE) */
    847714        0,                      /* no timeout */
     
    857724    };
    858725
     726    /* Already too late because of theoretical
     727     * possibility of getty --help somehow triggered
     728     * inadvertently before we reach this. Oh well. */
     729    logmode = LOGMODE_NONE;
     730    setsid();
     731    nullfd = xopen(bb_dev_null, O_RDWR);
     732    /* dup2(nullfd, 0); - no, because of possible "getty - 9600" */
     733    /* open_tty() will take care of fd# 0 anyway */
     734    dup2(nullfd, 1);
     735    dup2(nullfd, 2);
     736    while (nullfd > 2) close(nullfd--);
     737    /* We want special flavor of error_msg_and_die */
     738    die_sleep = 10;
     739    msg_eol = "\r\n";
     740    openlog(applet_name, LOG_PID, LOG_AUTH);
     741    logmode = LOGMODE_BOTH;
     742
    859743#ifdef DEBUGGING
    860     dbf = bb_xfopen(DEBUGTERM, "w");
     744    dbf = xfopen(DEBUGTERM, "w");
    861745
    862746    {
     
    871755
    872756    /* Parse command-line arguments. */
    873 
    874757    parse_args(argc, argv, &options);
    875758
    876 #ifdef __linux__
    877     setsid();
    878 #endif
    879 
     759#ifdef SYSV_STYLE
     760#if ENABLE_FEATURE_UTMP
    880761    /* Update the utmp file. */
    881 
    882 
    883 #ifdef  SYSV_STYLE
    884 #ifdef CONFIG_FEATURE_UTMP
    885762    update_utmp(options.tty);
    886763#endif
     
    889766    debug("calling open_tty\n");
    890767    /* Open the tty as standard { input, output, error }. */
    891     open_tty(options.tty, &termio, options.flags & F_LOCAL);
     768    open_tty(options.tty, &termios, options.flags & F_LOCAL);
    892769
    893770#ifdef __linux__
     
    899776    }
    900777#endif
    901     /* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */
    902     debug("calling termio_init\n");
    903     termio_init(&termio, options.speeds[FIRST_SPEED], &options);
     778    /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */
     779    debug("calling termios_init\n");
     780    termios_init(&termios, options.speeds[FIRST_SPEED], &options);
    904781
    905782    /* write the modem init string and DON'T flush the buffers */
     
    911788    if (!(options.flags & F_LOCAL)) {
    912789        /* go to blocking write mode unless -L is specified */
    913         fcntl(1, F_SETFL, fcntl(1, F_GETFL, 0) & ~O_NONBLOCK);
     790        ndelay_off(1);
    914791    }
    915792
     
    917794    debug("before autobaud\n");
    918795    if (options.flags & F_PARSE)
    919         auto_baud(&termio);
     796        auto_baud(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), &termios);
    920797
    921798    /* Set the optional timer. */
    922799    if (options.timeout)
    923         (void) alarm((unsigned) options.timeout);
     800        alarm(options.timeout);
    924801
    925802    /* optionally wait for CR or LF before writing /etc/issue */
     
    942819        /* Read the login name. */
    943820        debug("reading login name\n");
    944         /* while ((logname = get_logname(&options, &chardata, &termio)) == 0) */
    945         while ((logname = get_logname(&options, &chardata, &termio)) ==
    946                NULL) next_speed(&termio, &options);
     821        logname = get_logname(bb_common_bufsiz1, sizeof(bb_common_bufsiz1),
     822                &options, &chardata, &termios);
     823        while (logname == NULL)
     824            next_speed(&termios, &options);
    947825    }
    948826
     
    950828
    951829    if (options.timeout)
    952         (void) alarm(0);
    953 
    954     /* Finalize the termio settings. */
    955 
    956     termio_final(&options, &termio, &chardata);
     830        alarm(0);
     831
     832    /* Finalize the termios settings. */
     833
     834    termios_final(&options, &termios, &chardata);
    957835
    958836    /* Now the newline character should be properly written. */
    959837
    960     (void) write(1, "\n", 1);
     838    write(1, "\n", 1);
    961839
    962840    /* Let the login program take care of password validation. */
    963841
    964     (void) execl(options.login, options.login, "--", logname, (char *) 0);
    965     error("%s: can't exec %s: %m", options.tty, options.login);
    966 }
    967 
     842    execl(options.login, options.login, "--", logname, (char *) 0);
     843    bb_error_msg_and_die("%s: can't exec %s", options.tty, options.login);
     844}
Note: See TracChangeset for help on using the changeset viewer.