Ahem: add new faq entry to list at top of FAQ.html
[oweals/busybox.git] / loginutils / getty.c
index b211733eed34bd69e6646c12b387d052907f245b..9bad008c60bbabe7c0f40cda71d57730ab017841 100644 (file)
 #include <fcntl.h>
 #include <stdarg.h>
 #include <ctype.h>
-#include <utmp.h>
 #include <getopt.h>
 #include <termios.h>
 #include "busybox.h"
 
+#ifdef CONFIG_FEATURE_UTMP
+#include <utmp.h>
+#endif
+
 #define _PATH_LOGIN     "/bin/login"
 
  /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */
@@ -47,7 +50,7 @@
 
 #ifdef LOGIN_PROCESS                   /* defined in System V utmp.h */
 #define        SYSV_STYLE                              /* select System V style getty */
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_WTMP
 extern void updwtmp(const char *filename, const struct utmp *ut);
 #endif
 #endif  /* LOGIN_PROCESS */
@@ -55,21 +58,22 @@ extern void updwtmp(const char *filename, const struct utmp *ut);
  /*
   * Things you may want to modify.
   *
-  * If ISSUE is not defined, agetty will never display the contents of the
-  * /etc/issue file. You will not want to spit out large "issue" files at the
-  * wrong baud rate. Relevant for System V only.
-  *
   * You may disagree with the default line-editing etc. characters defined
   * below. Note, however, that DEL cannot be used for interrupt generation
   * and for line editing at the same time.
   */
 
 #ifdef SYSV_STYLE
-#define        ISSUE "/etc/issue"              /* displayed before the login prompt */
 #include <sys/utsname.h>
 #include <time.h>
 #endif
 
+ /* If ISSUE is not defined, agetty will never display the contents of the
+  * /etc/issue file. You will not want to spit out large "issue" files at the
+  * wrong baud rate.
+  */
+#define        ISSUE "/etc/issue"              /* displayed before the login prompt */
+
 /* Some shorthands for control characters. */
 
 #define CTL(x)         (x ^ 0100)      /* Assumes ASCII dialect */
@@ -85,7 +89,7 @@ extern void updwtmp(const char *filename, const struct utmp *ut);
 #define DEF_QUIT       CTL('\\')       /* default quit char */
 #define DEF_KILL       CTL('U')        /* default kill char */
 #define DEF_EOF                CTL('D')        /* default EOF char */
-#define DEF_EOL                0
+#define DEF_EOL                '\n'
 #define DEF_SWITCH     0                       /* default switch char */
 
  /*
@@ -161,7 +165,7 @@ struct chardata {
 
 /* Initial values for the above. */
 
-struct chardata init_chardata = {
+static struct chardata init_chardata = {
        DEF_ERASE,                                      /* default erase character */
        DEF_KILL,                                       /* default kill character */
        13,                                                     /* default eol char */
@@ -228,12 +232,14 @@ static void termio_final(struct options *op, struct termio *tp,
 
                                  struct chardata *cp);
 static int caps_lock(const char *s);
-static int bcode(const char *s);
+static int bcode(char *s);
 static void error(const char *fmt, ...) __attribute__ ((noreturn));
 
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef SYSV_STYLE
+#ifdef CONFIG_FEATURE_UTMP
 static void update_utmp(char *line);
 #endif
+#endif
 
 /* The following is used for understandable diagnostics. */
 
@@ -260,7 +266,11 @@ int getty_main(int argc, char **argv)
                _PATH_LOGIN,                    /* default login program */
                "tty1",                                 /* default tty line */
                "",                                             /* modem init string */
+#ifdef ISSUE
                ISSUE,                                  /* default issue file */
+#else
+               NULL,
+#endif
                0,                                              /* no baud rates known yet */
        };
 
@@ -289,7 +299,7 @@ int getty_main(int argc, char **argv)
 
 
 #ifdef SYSV_STYLE
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
        update_utmp(options.tty);
 #endif
 #endif
@@ -482,7 +492,7 @@ static void parse_speeds(struct options *op, char *arg)
 }
 
 #ifdef SYSV_STYLE
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
 
 /* update_utmp - update our utmp entry */
 static void update_utmp(char *line)
@@ -503,6 +513,9 @@ static void update_utmp(char *line)
         * utmp file can be opened for update, and if we are able to find our
         * entry in the utmp file.
         */
+       if (access(_PATH_UTMP, R_OK|W_OK) == -1) {
+               close(creat(_PATH_UTMP, 0664));
+       }
        utmpname(_PATH_UTMP);
        setutent();
        while ((utp = getutent())
@@ -530,27 +543,24 @@ static void update_utmp(char *line)
        pututline(&ut);
        endutent();
 
-       {
-               updwtmp(_PATH_WTMP, &ut);
-       }
+#ifdef CONFIG_FEATURE_WTMP
+       if (access(_PATH_WTMP, R_OK|W_OK) == -1) 
+               close(creat(_PATH_WTMP, 0664));
+       updwtmp(_PATH_WTMP, &ut);
+#endif
 }
 
-#endif /* CONFIG_FEATURE_U_W_TMP */
+#endif /* CONFIG_FEATURE_UTMP */
 #endif /* SYSV_STYLE */
 
 /* open_tty - set up tty as standard { input, output, error } */
 static void open_tty(char *tty, struct termio *tp, int local)
 {
-       /* Get rid of the present standard { output, error} if any. */
-
-       (void) close(1);
-       (void) close(2);
-       errno = 0;                                      /* ignore above errors */
-
        /* Set up new standard input, unless we are given an already opened port. */
 
        if (strcmp(tty, "-")) {
                struct stat st;
+               int fd;
 
                /* Sanity checks... */
 
@@ -563,12 +573,11 @@ static void open_tty(char *tty, struct termio *tp, int local)
 
                /* Open the tty as standard input. */
 
-               (void) close(0);
-               errno = 0;                              /* ignore close(2) errors */
-
                debug("open(2)\n");
-               if (open(tty, O_RDWR | O_NONBLOCK, 0) != 0)
+               fd = open(tty, O_RDWR | O_NONBLOCK, 0);
+               if (dup2(fd, STDIN_FILENO) == -1)
                        error("/dev/%s: cannot open as standard input: %m", tty);
+               close(fd);
 
        } else {
 
@@ -581,9 +590,10 @@ static void open_tty(char *tty, struct termio *tp, int local)
                        error("%s: not open for read/write", tty);
        }
 
-       /* Set up standard output and standard error file descriptors. */
+       /* Replace current standard output/error fd's with new ones */
        debug("duping\n");
-       if (dup(0) != 1 || dup(0) != 2) /* set up stdout and stderr */
+       if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 ||
+           dup2(STDIN_FILENO, STDERR_FILENO) == -1)
                error("%s: dup problem: %m", tty);      /* we have a problem */
 
        /*
@@ -953,7 +963,7 @@ static int caps_lock(const char *s)
 }
 
 /* bcode - convert speed string to speed code; return 0 on failure */
-static int bcode(const char *s)
+static int bcode(char *s)
 {
        int r;
        unsigned long value;