2
/* utmp.c Shareware Copyright by Sam Lantinga 10/6/93 */
13
#define UTMP_FILE "/tmp/utmp"
16
#define UTMP_FILE "/etc/utmp"
17
#endif /* UTMP_FILE */
18
#endif /* DEBUG_UTMP */
21
/* Remove us from the utmp file, saving our entry to replace later */
23
static struct utmp saved_utmp;
24
static int utmp_saved=0;
25
static char saved_tty[128];
36
tty=(char *)ttyname(0);
37
if ( tty == NULL || strlen(tty)+1 > sizeof(saved_tty) )
40
/* Retrieve our utmp record */
42
if ( get_utmp(tty, &ut) == 0 ) {
43
/* Save the utmp entry and tty pathname */
45
d_copy((char *)&ut, (char *)&saved_utmp, sizeof(ut));
46
strcpy(saved_tty, tty);
48
/* Clean out the entry and return */
52
ut.ut_type = DEAD_PROCESS;
57
return(set_utmp(tty, &ut));
59
/* Nothing to clean out, good. */
67
return(set_utmp(saved_tty, &saved_utmp));
71
int get_utmp(tty, save)
79
/* See if we can open the utmp file */
80
if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
83
/* Get the ttyxy form of the tty pathname if possible. */
85
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
94
while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
95
if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
96
/* Break out; we've found our entry! */
98
d_copy((char *)&ut, save, sizeof(ut));
103
/* We never found an entry for our tty */
108
int set_utmp(tty, save)
116
/* See if we can open the utmp file */
117
if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
120
/* Get the ttyxy form of the tty pathname if possible. */
122
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
123
if ( *ttyptr == '/' )
126
if ( *ttyptr == '/' )
131
while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
132
if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
134
lseek(fd, -(long)sizeof(struct utmp), 1);
139
/* Add a new entry to the utmp file if we can't find our entry */
141
{ /* Reopen to avoid a race with other end-of-utmp entries. */
143
if ( (fd=open(UTMP_FILE, (O_RDWR|O_APPEND))) < 0 )
147
if (write(fd, (char *)save, sizeof(*save)) != sizeof(*save)) {
155
/* Set up a utmp entry and tty for a user */
157
int addutmp(user, uid, tty)
158
char *user; /* The user to add to the utmp file */
159
int uid; /* The uid corresponding to user */
160
char *tty; /* /dev/ttyxx */
166
/* Retrieve any existing utmp entry */
167
d_zero((char *)&ut, sizeof(ut));
168
(void) get_utmp(tty, &ut);
170
/* Get the ttyxy form of the tty pathname if possible. */
172
for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
173
if ( *ttyptr == '/' )
176
if ( *ttyptr == '/' )
181
/* Customize the utmp entry */
182
strncpy(ut.ut_name, user, sizeof(ut.ut_name)-1);
183
ut.ut_name[sizeof(ut.ut_name)-1]='\0';
184
strncpy(ut.ut_line, ttyptr, sizeof(ut.ut_line)-1);
185
ut.ut_line[sizeof(ut.ut_line)-1]='\0';
187
ut.ut_type=USER_PROCESS;
190
#if defined(HAVE_UTHOST)
191
/* remove_me() should be called before this function */
193
strncpy(ut.ut_host, saved_utmp.ut_host, sizeof(ut.ut_host)-1);
194
ut.ut_host[sizeof(ut.ut_host)-1]='\0';
197
(void) time(&ut.ut_time);
199
#if !defined(SOLARIS) && !defined(IRIX)
200
/* Solaris and Irix machines do this automatically */
201
/* Change the ownership and mode of the tty */
202
if ( stat(tty, &sb) == 0 ) {
203
(void) chmod(tty, 0620); /* crw--w---- */
204
(void) chown(tty, uid, sb.st_gid);
207
return(set_utmp(tty, &ut));
211
/* End a utmp entry and tty for a user and a tty */
213
int delutmp(user, tty)
215
char *tty; /* /dev/ttyxx */
221
/* Retrieve any existing utmp entry */
222
d_zero((char *)&ut, sizeof(ut));
223
if ( get_utmp(tty, &ut) == 0 ) {
224
/* Clear the utmp entry */
227
ut.ut_type=DEAD_PROCESS;
229
#if defined(HAVE_UTHOST)
232
(void) time(&ut.ut_time);
233
retval=set_utmp(tty, &ut);
236
#if !defined(SOLARIS) && !defined(IRIX)
237
/* Solaris and Irix machines do this automatically */
238
/* Reset the owner and mode of the tty */
239
if ( stat(tty, &sb) == 0 ) {
240
(void) chmod(tty, 0666); /* crw-rw-rw- */
241
(void) chown(tty, 0, sb.st_gid);