aboutsummaryrefslogtreecommitdiff
path: root/loginutils/getty.c
diff options
context:
space:
mode:
Diffstat (limited to 'loginutils/getty.c')
-rw-r--r--loginutils/getty.c144
1 files changed, 59 insertions, 85 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 3da7c560a..71f6b2458 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -223,51 +223,6 @@ FILE *dbf;
#endif
-/*
- * output error messages
- */
-static void error(const char *fmt, ...) ATTRIBUTE_NORETURN;
-static void error(const char *fmt, ...)
-{
- va_list va_alist;
- char buf[256];
-
-#ifdef CONFIG_SYSLOGD
- va_start(va_alist, fmt);
- vsnprintf(buf, sizeof(buf), fmt, va_alist);
- openlog(bb_applet_name, 0, LOG_AUTH);
- syslog(LOG_ERR, "%s", buf);
- closelog();
-#else
- int fd;
- size_t l;
-
- snprintf(buf, sizeof(buf), "%s: ", bb_applet_name);
- l = strlen(buf);
- va_start(va_alist, fmt);
- vsnprintf(buf + l, sizeof(buf) - l, fmt, va_alist);
- l = strlen(buf);
- /* truncate if need */
- if((l + 3) > sizeof(buf))
- l = sizeof(buf) - 3;
- /* add \r\n always */
- buf[l++] = '\r';
- buf[l++] = '\n';
- buf[l] = 0;
- if ((fd = open("/dev/console", 1)) >= 0) {
- write(fd, buf, l);
- close(fd);
- }
-#endif
-
- va_end(va_alist);
-
- (void) sleep((unsigned) 10); /* be kind to init(8) */
- exit(1);
-}
-
-
-
/* bcode - convert speed string to speed code; return 0 on failure */
static int bcode(const char *s)
{
@@ -291,15 +246,15 @@ static void parse_speeds(struct options *op, char *arg)
debug("entered parse_speeds\n");
for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) {
if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0)
- error("bad speed: %s", cp);
+ bb_error_msg_and_die("bad speed: %s", cp);
if (op->numspeed > MAX_SPEED)
- error("too many alternate speeds");
+ bb_error_msg_and_die("too many alternate speeds");
}
debug("exiting parsespeeds\n");
}
-/* parse-args - parse command-line arguments */
+/* parse_args - parse command-line arguments */
static void parse_args(int argc, char **argv, struct options *op)
{
char *ts;
@@ -327,7 +282,7 @@ static void parse_args(int argc, char **argv, struct options *op)
op->flags ^= F_ISSUE; /* revert flag show /etc/issue */
if(op->flags & F_TIMEOUT) {
if ((op->timeout = atoi(ts)) <= 0)
- error("bad timeout value: %s", ts);
+ bb_error_msg_and_die("bad timeout value: %s", ts);
}
debug("after getopt loop\n");
if (argc < optind + 2) /* check parameter count */
@@ -350,6 +305,12 @@ static void parse_args(int argc, char **argv, struct options *op)
debug("exiting parseargs\n");
}
+static void xdup2(int srcfd, int dstfd, const char *tty)
+{
+ if(dup2(srcfd, dstfd) == -1)
+ bb_perror_msg_and_die("%s: dup", tty);
+}
+
/* open_tty - set up tty as standard { input, output, error } */
static void open_tty(char *tty, struct termio *tp, int local)
{
@@ -363,37 +324,34 @@ static void open_tty(char *tty, struct termio *tp, int local)
/* Sanity checks... */
- if (chdir("/dev"))
- error("/dev: chdir() failed: %m");
+ xchdir("/dev");
chdir_to_root = 1;
- if (stat(tty, &st) < 0)
- error("/dev/%s: %m", tty);
+ xstat(tty, &st);
if ((st.st_mode & S_IFMT) != S_IFCHR)
- error("/dev/%s: not a character device", tty);
+ bb_error_msg_and_die("%s: not a character device", tty);
/* Open the tty as standard input. */
- close(0);
debug("open(2)\n");
- fd = open(tty, O_RDWR | O_NONBLOCK, 0);
- if (fd != 0)
- error("/dev/%s: cannot open as standard input: %m", tty);
+ fd = xopen(tty, O_RDWR | O_NONBLOCK);
+ if(fd) {
+ xdup2(fd, 0, tty);
+ close(fd);
+ }
} else {
-
/*
* Standard input should already be connected to an open port. Make
* sure it is open for read/write.
*/
if ((fcntl(0, F_GETFL, 0) & O_RDWR) != O_RDWR)
- error("%s: not open for read/write", tty);
+ bb_error_msg_and_die("%s: not open for read/write", tty);
}
/* Replace current standard output/error fd's with new ones */
debug("duping\n");
- if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 ||
- dup2(STDIN_FILENO, STDERR_FILENO) == -1)
- error("%s: dup problem: %m", tty); /* we have a problem */
+ xdup2(0, 1, tty);
+ xdup2(0, 2, tty);
/*
* The following ioctl will fail if stdin is not a tty, but also when
@@ -405,7 +363,7 @@ static void open_tty(char *tty, struct termio *tp, int local)
*/
if (ioctl(0, TCGETA, tp) < 0)
- error("%s: ioctl: %m", tty);
+ bb_perror_msg_and_die("%s: ioctl(TCGETA)", tty);
/*
* It seems to be a terminal. Set proper protections and ownership. Mode
@@ -428,10 +386,8 @@ static void open_tty(char *tty, struct termio *tp, int local)
if (!strncmp(tty, "tty", 3) && isdigit(tty[3])) {
char *vcs, *vcsa;
- if (!(vcs = strdup(tty)))
- error("Can't malloc for vcs");
- if (!(vcsa = malloc(strlen(tty) + 2)))
- error("Can't malloc for vcsa");
+ vcs = xstrdup(tty);
+ vcsa = xmalloc(strlen(tty) + 2);
strcpy(vcs, "vcs");
strcpy(vcs + 3, tty + 3);
strcpy(vcsa, "vcsa");
@@ -451,8 +407,8 @@ static void open_tty(char *tty, struct termio *tp, int local)
(void) chown(tty, 0, 0); /* root, sys */
(void) chmod(tty, 0622); /* crw--w--w- */
#endif
- if(chdir_to_root && chdir("/"))
- error("chdir to / failed: %m");
+ if (chdir_to_root)
+ xchdir("/");
}
/* termio_init - initialize termio settings */
@@ -634,7 +590,7 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio
if (read(0, &c, 1) < 1) {
if (errno == EINTR || errno == EIO)
exit(0);
- error("%s: read: %m", op->tty);
+ bb_perror_msg_and_die("%s: read", op->tty);
}
/* Do BREAK handling elsewhere. */
@@ -681,7 +637,7 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio
if (!isascii(ascval) || !isprint(ascval)) {
/* ignore garbage characters */ ;
} else if (bp - logname >= sizeof(logname) - 1) {
- error("%s: input overrun", op->tty);
+ bb_error_msg_and_die("%s: input overrun", op->tty);
} else {
(void) write(1, &c, 1); /* echo the character */
*bp++ = ascval; /* and store it */
@@ -759,7 +715,7 @@ static void termio_final(struct options *op, struct termio *tp, struct chardata
/* Finally, make the new settings effective */
if (ioctl(0, TCSETA, tp) < 0)
- error("%s: ioctl: TCSETA: %m", op->tty);
+ bb_perror_msg_and_die("%s: ioctl(TCSETA)", op->tty);
}
@@ -828,6 +784,7 @@ static void update_utmp(char *line)
#undef logname
int getty_main(int argc, char **argv)
{
+ int nullfd;
char *logname = NULL; /* login name, given to /bin/login */
struct chardata chardata; /* set by get_logname() */
struct termio termio; /* terminal mode bits */
@@ -845,6 +802,29 @@ int getty_main(int argc, char **argv)
0, /* no baud rates known yet */
};
+ /* Already too late because of theoretical
+ * possibility of getty --help somehow triggered
+ * inadvertently before we reach this. Oh well. */
+ close(0);
+ close(1);
+ close(2);
+#ifdef __linux__
+ setsid();
+#endif
+ /* We want special flavor of error_msg_and_die */
+ die_sleep = 10;
+ msg_eol = "\r\n";
+ /* Was "/dev/console". Why should we spam *system console*
+ * if there is a problem with getty on /dev/ttyS15?... */
+ nullfd = xopen(bb_dev_null, O_RDWR);
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ if(nullfd > 2)
+ close(nullfd);
+ openlog(bb_applet_name, LOG_PID, LOG_AUTH);
+ logmode = LOGMODE_BOTH;
+
#ifdef DEBUGGING
dbf = xfopen(DEBUGTERM, "w");
@@ -859,18 +839,11 @@ int getty_main(int argc, char **argv)
#endif
/* Parse command-line arguments. */
-
parse_args(argc, argv, &options);
-#ifdef __linux__
- setsid();
-#endif
-
- /* Update the utmp file. */
-
-
-#ifdef SYSV_STYLE
+#ifdef SYSV_STYLE
#ifdef CONFIG_FEATURE_UTMP
+ /* Update the utmp file. */
update_utmp(options.tty);
#endif
#endif
@@ -931,8 +904,9 @@ int getty_main(int argc, char **argv)
/* Read the login name. */
debug("reading login name\n");
/* while ((logname = get_logname(&options, &chardata, &termio)) == 0) */
- while ((logname = get_logname(&options, &chardata, &termio)) ==
- NULL) next_speed(&termio, &options);
+ logname = get_logname(&options, &chardata, &termio);
+ while (logname == NULL)
+ next_speed(&termio, &options);
}
/* Disable timer. */
@@ -951,6 +925,6 @@ int getty_main(int argc, char **argv)
/* Let the login program take care of password validation. */
(void) execl(options.login, options.login, "--", logname, (char *) 0);
- error("%s: can't exec %s: %m", options.tty, options.login);
+ bb_error_msg_and_die("%s: can't exec %s", options.tty, options.login);
}