+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 */
+
+static void die_if_nologin_and_non_root(int amroot)
+{
+ FILE *fp;
+ int c;
+
+ if (access(bb_path_nologin_file, F_OK))
+ return;
+
+ fp = fopen(bb_path_nologin_file, "r");
+ if (fp) {
+ while ((c = getc(fp)) != EOF)
+ putchar((c=='\n') ? '\r' : c);
+ fflush(stdout);
+ fclose(fp);
+ } else
+ puts("\r\nSystem closed for routine maintenance\r");
+ if (!amroot)
+ exit(1);
+ puts("\r\n[Disconnect bypassed -- root login allowed.]\r");
+}
+
+#if ENABLE_FEATURE_SECURETTY
+static int check_securetty(void)
+{
+ FILE *fp;
+ int i;
+ char buf[BUFSIZ];