1 /* vi: set sw=4 ts=4: */
3 * utmp/wtmp support routines.
5 * Copyright (C) 2010 Denys Vlasenko
7 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
12 static void touch(const char *filename)
14 if (access(filename, R_OK | W_OK) == -1)
15 close(open(filename, O_WRONLY | O_CREAT, 0664));
19 * Read "man utmp" to make sense out of it.
21 void FAST_FUNC update_utmp(int new_type, const char *short_tty, const char *username, const char *opt_host)
32 /* Did init/getty/telnetd/sshd/... create an entry for us?
33 * It should be (new_type-1), but we'd also reuse
34 * any other potentially stale xxx_PROCESS entry */
35 while ((ut = getutent()) != NULL) {
38 && ut->ut_id[0] /* must have nonzero id */
39 && ( ut->ut_type == INIT_PROCESS
40 || ut->ut_type == LOGIN_PROCESS
41 || ut->ut_type == USER_PROCESS
42 || ut->ut_type == DEAD_PROCESS
45 utent = *ut; /* struct copy */
46 if (ut->ut_type >= new_type) {
47 /* Stale record. Nuke hostname */
48 memset(utent.ut_host, 0, sizeof(utent.ut_host));
50 /* NB: pututline (see later) searches for matching utent
51 * using getutid(utent) - we must not change ut_id
52 * if we want *exactly this* record to be overwritten!
60 /* Didn't find anything, create new one */
61 memset(&utent, 0, sizeof(utent));
63 /* Invent our own ut_id. ut_id is only 4 chars wide.
64 * Try to fit something remotely meaningful... */
65 if (short_tty[0] == 'p') {
66 /* if "ptyXXX", map to "pXXX" */
67 /* if "pts/XX", map to "p/XX" */
69 strncpy(utent.ut_id + 1, short_tty + 3, sizeof(utent.ut_id)-1);
71 /* assuming it's "ttyXXXX", map to "XXXX" */
72 strncpy(utent.ut_id, short_tty + 3, sizeof(utent.ut_id));
76 utent.ut_type = new_type;
77 safe_strncpy(utent.ut_line, short_tty, sizeof(utent.ut_line));
78 safe_strncpy(utent.ut_user, username, sizeof(utent.ut_user));
80 safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
81 utent.ut_tv.tv_sec = time(NULL);
83 /* Update, or append new one */
88 #if ENABLE_FEATURE_WTMP
89 touch(bb_path_wtmp_file);
90 updwtmp(bb_path_wtmp_file, &utent);