+static char* short_tty;
+
+#if ENABLE_FEATURE_UTMP
+/* vv Taken from tinylogin utmp.c vv */
+/*
+ * read_or_build_utent - see if utmp file is correct for this process
+ *
+ * System V is very picky about the contents of the utmp file
+ * and requires that a slot for the current process exist.
+ * The utmp file is scanned for an entry with the same process
+ * ID. If no entry exists the process exits with a message.
+ *
+ * The "picky" flag is for network and other logins that may
+ * use special flags. It allows the pid checks to be overridden.
+ * This means that getty should never invoke login with any
+ * command line flags.
+ */
+
+static void read_or_build_utent(struct utmp *utptr, int picky)
+{
+ struct utmp *ut;
+ pid_t pid = getpid();
+
+ setutent();
+
+ /* First, try to find a valid utmp entry for this process. */
+ while ((ut = getutent()))
+ if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
+ (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS))
+ break;
+
+ /* If there is one, just use it, otherwise create a new one. */
+ if (ut) {
+ *utptr = *ut;
+ } else {
+ if (picky)
+ bb_error_msg_and_die("no utmp entry found");
+
+ memset(utptr, 0, sizeof(*utptr));
+ utptr->ut_type = LOGIN_PROCESS;
+ utptr->ut_pid = pid;
+ strncpy(utptr->ut_line, short_tty, sizeof(utptr->ut_line));
+ /* This one is only 4 chars wide. Try to fit something
+ * remotely meaningful by skipping "tty"... */
+ strncpy(utptr->ut_id, short_tty + 3, sizeof(utptr->ut_id));
+ strncpy(utptr->ut_user, "LOGIN", sizeof(utptr->ut_user));
+ utptr->ut_time = time(NULL);
+ }
+ if (!picky) /* root login */
+ memset(utptr->ut_host, 0, sizeof(utptr->ut_host));
+}
+
+/*
+ * write_utent - put a USER_PROCESS entry in the utmp file
+ *
+ * write_utent changes the type of the current utmp entry to
+ * USER_PROCESS. the wtmp file will be updated as well.
+ */
+static void write_utent(struct utmp *utptr, const char *username)
+{
+ utptr->ut_type = USER_PROCESS;
+ strncpy(utptr->ut_user, username, sizeof(utptr->ut_user));
+ utptr->ut_time = time(NULL);
+ /* other fields already filled in by read_or_build_utent above */
+ setutent();
+ pututline(utptr);
+ endutent();
+#if ENABLE_FEATURE_WTMP
+ if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
+ close(creat(bb_path_wtmp_file, 0664));
+ }
+ updwtmp(bb_path_wtmp_file, utptr);
+#endif
+}
+#else /* !ENABLE_FEATURE_UTMP */
+#define read_or_build_utent(utptr, picky) ((void)0)
+#define write_utent(utptr, username) ((void)0)
+#endif /* !ENABLE_FEATURE_UTMP */
+
+#if ENABLE_FEATURE_NOLOGIN
+static void die_if_nologin(void)
+{
+ FILE *fp;
+ int c;
+
+ if (access("/etc/nologin", F_OK))
+ return;
+
+ fp = fopen("/etc/nologin", "r");
+ if (fp) {
+ while ((c = getc(fp)) != EOF)
+ bb_putchar((c=='\n') ? '\r' : c);
+ fflush(stdout);
+ fclose(fp);
+ } else
+ puts("\r\nSystem closed for routine maintenance\r");
+ exit(1);
+}
+#else
+static ALWAYS_INLINE void die_if_nologin(void) {}
+#endif
+
+#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
+static int check_securetty(void)
+{
+ FILE *fp;
+ int i;
+ char buf[256];