source: MondoRescue/branches/3.3/mindi-busybox/libbb/utmp.c@ 3906

Last change on this file since 3906 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 4.1 KB
RevLine 
[2725]1/* vi: set sw=4 ts=4: */
2/*
3 * utmp/wtmp support routines.
4 *
5 * Copyright (C) 2010 Denys Vlasenko
6 *
7 * Licensed under GPLv2, see file LICENSE in this source tree.
8 */
9#include "libbb.h"
10
11static void touch(const char *filename)
12{
13 if (access(filename, R_OK | W_OK) == -1)
14 close(open(filename, O_WRONLY | O_CREAT, 0664));
15}
16
17void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname)
18{
[3621]19 struct utmpx utent;
[2725]20 char *id;
21 unsigned width;
22
23 memset(&utent, 0, sizeof(utent));
24 utent.ut_pid = pid;
25 utent.ut_type = new_type;
26 tty_name = skip_dev_pfx(tty_name);
27 safe_strncpy(utent.ut_line, tty_name, sizeof(utent.ut_line));
28 if (username)
29 safe_strncpy(utent.ut_user, username, sizeof(utent.ut_user));
30 if (hostname)
31 safe_strncpy(utent.ut_host, hostname, sizeof(utent.ut_host));
32 utent.ut_tv.tv_sec = time(NULL);
33
34 /* Invent our own ut_id. ut_id is only 4 chars wide.
35 * Try to fit something remotely meaningful... */
36 id = utent.ut_id;
37 width = sizeof(utent.ut_id);
38 if (tty_name[0] == 'p') {
39 /* if "ptyXXX", map to "pXXX" */
40 /* if "pts/XX", map to "p/XX" */
41 *id++ = 'p';
42 width--;
43 } /* else: usually it's "ttyXXXX", map to "XXXX" */
44 if (strlen(tty_name) > 3)
45 tty_name += 3;
46 strncpy(id, tty_name, width);
47
[3621]48 touch(_PATH_UTMPX);
49 //utmpxname(_PATH_UTMPX);
50 setutxent();
[2725]51 /* Append new one (hopefully, unless we collide on ut_id) */
[3621]52 pututxline(&utent);
53 endutxent();
[2725]54
55#if ENABLE_FEATURE_WTMP
56 /* "man utmp" says wtmp file should *not* be created automagically */
57 /*touch(bb_path_wtmp_file);*/
[3621]58 updwtmpx(bb_path_wtmp_file, &utent);
[2725]59#endif
60}
61
62/*
63 * Read "man utmp" to make sense out of it.
64 */
65void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname)
66{
[3621]67 struct utmpx utent;
68 struct utmpx *utp;
[2725]69
[3621]70 touch(_PATH_UTMPX);
71 //utmpxname(_PATH_UTMPX);
72 setutxent();
[2725]73
74 /* Did init/getty/telnetd/sshd/... create an entry for us?
75 * It should be (new_type-1), but we'd also reuse
76 * any other potentially stale xxx_PROCESS entry */
[3621]77 while ((utp = getutxent()) != NULL) {
[2725]78 if (utp->ut_pid == pid
79 // && ut->ut_line[0]
80 && utp->ut_id[0] /* must have nonzero id */
81 && ( utp->ut_type == INIT_PROCESS
82 || utp->ut_type == LOGIN_PROCESS
83 || utp->ut_type == USER_PROCESS
84 || utp->ut_type == DEAD_PROCESS
85 )
86 ) {
87 if (utp->ut_type >= new_type) {
88 /* Stale record. Nuke hostname */
89 memset(utp->ut_host, 0, sizeof(utp->ut_host));
90 }
[3621]91 /* NB: pututxline (see later) searches for matching utxent
92 * using getutxid(utent) - we must not change ut_id
[2725]93 * if we want *exactly this* record to be overwritten!
94 */
95 break;
96 }
97 }
[3621]98 //endutxent(); - no need, pututxline can deal with (and actually likes)
[2725]99 //the situation when utmp file is positioned on found record
100
101 if (!utp) {
102 if (new_type != DEAD_PROCESS)
103 write_new_utmp(pid, new_type, tty_name, username, hostname);
104 else
[3621]105 endutxent();
[2725]106 return;
107 }
108
[3621]109 /* Make a copy. We can't use *utp, pututxline's internal getutxid
[2725]110 * will overwrite it before it is used! */
111 utent = *utp;
112
113 utent.ut_type = new_type;
114 if (tty_name)
115 safe_strncpy(utent.ut_line, skip_dev_pfx(tty_name), sizeof(utent.ut_line));
116 if (username)
117 safe_strncpy(utent.ut_user, username, sizeof(utent.ut_user));
118 if (hostname)
119 safe_strncpy(utent.ut_host, hostname, sizeof(utent.ut_host));
120 utent.ut_tv.tv_sec = time(NULL);
121
122 /* Update, or append new one */
[3621]123 //setutxent();
124 pututxline(&utent);
125 endutxent();
[2725]126
127#if ENABLE_FEATURE_WTMP
128 /* "man utmp" says wtmp file should *not* be created automagically */
129 /*touch(bb_path_wtmp_file);*/
[3621]130 updwtmpx(bb_path_wtmp_file, &utent);
[2725]131#endif
132}
[3621]133
134/* man utmp:
135 * When init(8) finds that a process has exited, it locates its utmp entry
136 * by ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host
137 * and ut_time with null bytes.
138 * [same applies to other processes which maintain utmp entries, like telnetd]
139 *
140 * We do not bother actually clearing fields:
141 * it might be interesting to know who was logged in and from where
142 */
143void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid)
144{
145 update_utmp(pid, DEAD_PROCESS, NULL, NULL, NULL);
146}
Note: See TracBrowser for help on using the repository browser.