~ubuntu-branches/ubuntu/gutsy/splitvt/gutsy

« back to all changes in this revision

Viewing changes to utmp.c

  • Committer: Bazaar Package Importer
  • Author(s): Joey Hess
  • Date: 2001-10-05 20:09:25 UTC
  • Revision ID: james.westby@ubuntu.com-20011005200925-1crvu3veaaofavdb
Tags: upstream-1.6.5
ImportĀ upstreamĀ versionĀ 1.6.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*  utmp.c    Shareware Copyright by Sam Lantinga       10/6/93 */
 
3
 
 
4
#include        <sys/types.h>
 
5
#include        <sys/stat.h>
 
6
#include        <fcntl.h>
 
7
#include        <utmp.h>
 
8
#include        <stdio.h>
 
9
 
 
10
#ifdef DEBUG_UTMP
 
11
#undef  UTMP_FILE
 
12
#define UTMP_FILE  "/tmp/utmp"
 
13
#else
 
14
#ifndef UTMP_FILE
 
15
#define UTMP_FILE  "/etc/utmp"
 
16
#endif /* UTMP_FILE */
 
17
#endif /* DEBUG_UTMP */
 
18
 
 
19
 
 
20
/* Remove us from the utmp file, saving our entry to replace later */
 
21
 
 
22
static struct utmp saved_utmp;
 
23
static int utmp_saved=0;
 
24
static char saved_tty[128];
 
25
 
 
26
int remove_me()
 
27
{
 
28
        struct utmp ut;
 
29
        char *tty;
 
30
        time_t now;
 
31
 
 
32
        if ( ! isatty(0) )
 
33
                return(-1);
 
34
 
 
35
        tty=(char *)ttyname(0);
 
36
        if ( tty == NULL || strlen(tty)+1 > sizeof(saved_tty) )
 
37
                return(-1);
 
38
 
 
39
        /* Retrieve our utmp record */
 
40
        (void) time(&now);
 
41
        if ( get_utmp(tty, &ut) == 0 ) {
 
42
                /* Save the utmp entry and tty pathname */
 
43
                utmp_saved=1;
 
44
                d_copy((char *)&ut, (char *)&saved_utmp, sizeof(ut));
 
45
                strcpy(saved_tty, tty);
 
46
 
 
47
                /* Clean out the entry and return */
 
48
                ut.ut_name[0]='\0';
 
49
                ut.ut_time=now;
 
50
#ifdef USER_PROCESS
 
51
                ut.ut_type = DEAD_PROCESS;
 
52
#endif
 
53
#ifdef HAVE_UTHOST
 
54
                ut.ut_host[0]='\0';
 
55
#endif
 
56
                return(set_utmp(tty, &ut));
 
57
        }
 
58
        /* Nothing to clean out, good. */
 
59
        return(0);
 
60
}
 
61
 
 
62
 
 
63
int replace_me()
 
64
{
 
65
        if ( utmp_saved )
 
66
                return(set_utmp(saved_tty, &saved_utmp));
 
67
        return(0);
 
68
}
 
69
        
 
70
int get_utmp(tty, save)
 
71
char *tty;
 
72
struct utmp *save;
 
73
{
 
74
        int fd;
 
75
        char *ttyptr;
 
76
        struct utmp ut;
 
77
 
 
78
        /* See if we can open the utmp file */
 
79
        if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
 
80
                return(-1);
 
81
 
 
82
        /* Get the ttyxy form of the tty pathname if possible. */
 
83
        if ( *tty == '/' ) {
 
84
                for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
 
85
                        if ( *ttyptr == '/' )
 
86
                                break;
 
87
                }
 
88
                if ( *ttyptr == '/' )
 
89
                        ++ttyptr;
 
90
        } else
 
91
                ttyptr=tty;
 
92
 
 
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! */
 
96
                        if ( save )
 
97
                                d_copy((char *)&ut, save, sizeof(ut));
 
98
                        close(fd);
 
99
                        return(0);
 
100
                }
 
101
        }
 
102
        /* We never found an entry for our tty */
 
103
        close(fd);
 
104
        return(-1);
 
105
}
 
106
 
 
107
int set_utmp(tty, save)
 
108
char *tty;
 
109
struct utmp *save;
 
110
{
 
111
        int fd, found=0;
 
112
        char *ttyptr;
 
113
        struct utmp ut;
 
114
 
 
115
        /* See if we can open the utmp file */
 
116
        if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
 
117
                return(-1);
 
118
 
 
119
        /* Get the ttyxy form of the tty pathname if possible. */
 
120
        if ( *tty == '/' ) {
 
121
                for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
 
122
                        if ( *ttyptr == '/' )
 
123
                                break;
 
124
                }
 
125
                if ( *ttyptr == '/' )
 
126
                        ++ttyptr;
 
127
        } else
 
128
                ttyptr=tty;
 
129
 
 
130
        while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
 
131
                if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
 
132
                        found=1;
 
133
                        lseek(fd, -(long)sizeof(struct utmp), 1);
 
134
                        break;
 
135
                }
 
136
        }
 
137
 
 
138
        /* Add a new entry to the utmp file if we can't find our entry */
 
139
        if ( ! found )
 
140
        { /* Reopen to avoid a race with other end-of-utmp entries. */
 
141
                (void) close(fd);
 
142
                if ( (fd=open(UTMP_FILE, (O_RDWR|O_APPEND))) < 0 )
 
143
                        return -1;
 
144
        }
 
145
 
 
146
        if (write(fd, (char *)save, sizeof(*save)) != sizeof(*save)) {
 
147
                (void) close(fd);
 
148
                return -1;
 
149
        }
 
150
        return(close(fd));
 
151
}
 
152
 
 
153
        
 
154
/* Set up a utmp entry and tty for a user */
 
155
 
 
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 */
 
160
{
 
161
        struct stat sb;
 
162
        struct utmp ut;
 
163
        char *ttyptr;
 
164
 
 
165
        /* Retrieve any existing utmp entry */
 
166
        d_zero((char *)&ut, sizeof(ut));
 
167
        (void) get_utmp(tty, &ut);
 
168
 
 
169
        /* Get the ttyxy form of the tty pathname if possible. */
 
170
        if ( *tty == '/' ) {
 
171
                for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
 
172
                        if ( *ttyptr == '/' )
 
173
                                break;
 
174
                }
 
175
                if ( *ttyptr == '/' )
 
176
                        ++ttyptr;
 
177
        } else
 
178
                ttyptr=tty;
 
179
 
 
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';
 
185
#ifdef USER_PROCESS
 
186
        ut.ut_type=USER_PROCESS;
 
187
        ut.ut_pid=getpid();
 
188
#endif
 
189
#if defined(HAVE_UTHOST)
 
190
        /* remove_me() should be called before this function */
 
191
        if ( utmp_saved ) {
 
192
                strncpy(ut.ut_host, saved_utmp.ut_host, sizeof(ut.ut_host)-1);
 
193
                ut.ut_host[sizeof(ut.ut_host)-1]='\0';
 
194
        }
 
195
#endif
 
196
        (void) time(&ut.ut_time);
 
197
 
 
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);
 
204
        }
 
205
#endif
 
206
        return(set_utmp(tty, &ut));
 
207
}
 
208
        
 
209
 
 
210
/* End a utmp entry and tty for a user and a tty */
 
211
 
 
212
int delutmp(user, tty)
 
213
char *user;
 
214
char *tty;              /* /dev/ttyxx */
 
215
{
 
216
        struct stat sb;
 
217
        struct utmp ut;
 
218
        int retval=0;
 
219
 
 
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 */
 
224
                ut.ut_name[0]='\0';
 
225
#ifdef USER_PROCESS
 
226
                ut.ut_type=DEAD_PROCESS;
 
227
#endif
 
228
#if defined(HAVE_UTHOST)
 
229
                ut.ut_host[0]='\0';
 
230
#endif
 
231
                (void) time(&ut.ut_time);
 
232
                retval=set_utmp(tty, &ut);
 
233
        }
 
234
 
 
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);
 
241
        }
 
242
#endif
 
243
        return(retval);
 
244
}
 
245
 
 
246