#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)
{
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;
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 */
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)
{
/* 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
*/
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
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");
(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 */
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. */
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 */
/* 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);
}
#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 */
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");
#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
/* 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. */
/* 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);
}
struct spwd *spwd = NULL;
#endif
- openlog("sulogin", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
+ openlog("sulogin", LOG_PID | LOG_NOWAIT, LOG_AUTH);
+ logmode = LOGMODE_BOTH;
if (argc > 1) {
if (strncmp(argv[1], "-t", 2) == 0) {
if (argv[1][2] == '\0') { /* -t NN */
dup(0);
dup(0);
} else {
- syslog(LOG_WARNING, "cannot open %s\n", device);
- exit(EXIT_FAILURE);
+ /* Well, it will go only to syslog :) */
+ bb_perror_msg_and_die("Cannot open %s", device);
}
}
}
- if (access(bb_path_passwd_file, 0) == -1) {
- syslog(LOG_WARNING, "No password file\n");
- bb_error_msg_and_die("No password file");
- }
if (!isatty(0) || !isatty(1) || !isatty(2)) {
exit(EXIT_FAILURE);
}
-
+ if (access(bb_path_passwd_file, 0) == -1) {
+ bb_error_msg_and_die("No password file");
+ }
/* Clear out anything dangerous from the environment */
for (p = forbid; *p; p++)
unsetenv(*p);
-
signal(SIGALRM, catchalarm);
if (!(pwd = getpwnam(name))) {
- syslog(LOG_WARNING, "No password entry for `root'");
bb_error_msg_and_die("No password entry for `root'");
}
pwent = *pwd;
while (1) {
cp = bb_askpass(timeout, SULOGIN_PROMPT);
if (!cp || !*cp) {
- puts("\n");
+ puts("\n"); /* Why only on error path? */
fflush(stdout);
- syslog(LOG_INFO, "Normal startup\n");
+ /* Why only to syslog? */
+ syslog(LOG_INFO, "Normal startup");
exit(EXIT_SUCCESS);
} else {
safe_strncpy(pass, cp, sizeof(pass));
break;
}
bb_do_delay(FAIL_DELAY);
- puts("Login incorrect");
- fflush(stdout);
- syslog(LOG_WARNING, "Incorrect root password\n");
+ bb_error_msg("Incorrect root password");
}
memset(pass, 0, strlen(pass));
signal(SIGALRM, SIG_DFL);
- puts("Entering System Maintenance Mode\n");
- fflush(stdout);
- syslog(LOG_INFO, "System Maintenance Mode\n");
+ bb_info_msg("Entering System Maintenance Mode");
#if ENABLE_SELINUX
renew_current_security_context();
run_shell(pwent.pw_shell, 1, 0, 0);
- return (0);
+ return 0;
}