2
/* utmp.c Shareware Copyright by Sam Lantinga 10/6/93 */
12
#define UTMP_FILE "/tmp/utmp"
15
#define UTMP_FILE "/etc/utmp"
16
#endif /* UTMP_FILE */
17
#endif /* DEBUG_UTMP */
20
/* Remove us from the utmp file, saving our entry to replace later */
22
static struct utmp saved_utmp;
23
static int utmp_saved=0;
24
static char saved_tty[128];
35
tty=(char *)ttyname(0);
36
if ( tty == NULL || strlen(tty)+1 > sizeof(saved_tty) )
39
/* Retrieve our utmp record */
41
if ( get_utmp(tty, &ut) == 0 ) {
42
/* Save the utmp entry and tty pathname */
44
d_copy((char *)&ut, (char *)&saved_utmp, sizeof(ut));
45
strcpy(saved_tty, tty);
47
/* Clean out the entry and return */
51
ut.ut_type = DEAD_PROCESS;
56
return(set_utmp(tty, &ut));
58
/* Nothing to clean out, good. */
66
return(set_utmp(saved_tty, &saved_utmp));
70
int get_utmp(tty, save)
78
/* See if we can open the utmp file */
79
if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
82
/* Get the ttyxy form of the tty pathname if possible. */
84
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
93
while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
94
if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
95
/* Break out; we've found our entry! */
97
d_copy((char *)&ut, save, sizeof(ut));
102
/* We never found an entry for our tty */
107
int set_utmp(tty, save)
115
/* See if we can open the utmp file */
116
if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
119
/* Get the ttyxy form of the tty pathname if possible. */
121
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
122
if ( *ttyptr == '/' )
125
if ( *ttyptr == '/' )
130
while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
131
if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
133
lseek(fd, -(long)sizeof(struct utmp), 1);
138
/* Add a new entry to the utmp file if we can't find our entry */
140
{ /* Reopen to avoid a race with other end-of-utmp entries. */
142
if ( (fd=open(UTMP_FILE, (O_RDWR|O_APPEND))) < 0 )
146
if (write(fd, (char *)save, sizeof(*save)) != sizeof(*save)) {
154
/* Set up a utmp entry and tty for a user */
156
int addutmp(user, uid, tty)
157
char *user; /* The user to add to the utmp file */
158
int uid; /* The uid corresponding to user */
159
char *tty; /* /dev/ttyxx */
165
/* Retrieve any existing utmp entry */
166
d_zero((char *)&ut, sizeof(ut));
167
(void) get_utmp(tty, &ut);
169
/* Get the ttyxy form of the tty pathname if possible. */
171
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
172
if ( *ttyptr == '/' )
175
if ( *ttyptr == '/' )
180
/* Customize the utmp entry */
181
strncpy(ut.ut_name, user, sizeof(ut.ut_name)-1);
182
ut.ut_name[sizeof(ut.ut_name)-1]='\0';
183
strncpy(ut.ut_line, ttyptr, sizeof(ut.ut_line)-1);
184
ut.ut_line[sizeof(ut.ut_line)-1]='\0';
186
ut.ut_type=USER_PROCESS;
189
#if defined(HAVE_UTHOST)
190
/* remove_me() should be called before this function */
192
strncpy(ut.ut_host, saved_utmp.ut_host, sizeof(ut.ut_host)-1);
193
ut.ut_host[sizeof(ut.ut_host)-1]='\0';
196
(void) time(&ut.ut_time);
198
#if !defined(SOLARIS) && !defined(IRIX)
199
/* Solaris and Irix machines do this automatically */
200
/* Change the ownership and mode of the tty */
201
if ( stat(tty, &sb) == 0 ) {
202
(void) chmod(tty, 0620); /* crw--w---- */
203
(void) chown(tty, uid, sb.st_gid);
206
return(set_utmp(tty, &ut));
210
/* End a utmp entry and tty for a user and a tty */
212
int delutmp(user, tty)
214
char *tty; /* /dev/ttyxx */
220
/* Retrieve any existing utmp entry */
221
d_zero((char *)&ut, sizeof(ut));
222
if ( get_utmp(tty, &ut) == 0 ) {
223
/* Clear the utmp entry */
226
ut.ut_type=DEAD_PROCESS;
228
#if defined(HAVE_UTHOST)
231
(void) time(&ut.ut_time);
232
retval=set_utmp(tty, &ut);
235
#if !defined(SOLARIS) && !defined(IRIX)
236
/* Solaris and Irix machines do this automatically */
237
/* Reset the owner and mode of the tty */
238
if ( stat(tty, &sb) == 0 ) {
239
(void) chmod(tty, 0666); /* crw-rw-rw- */
240
(void) chown(tty, 0, sb.st_gid);