]> git.saurik.com Git - apple/libc.git/blame - gen/NetBSD/utmpx.c.patch
Libc-498.tar.gz
[apple/libc.git] / gen / NetBSD / utmpx.c.patch
CommitLineData
224c7076
A
1--- utmpx.c.orig 2006-02-06 00:43:57.000000000 -0800
2+++ utmpx.c 2006-02-06 00:51:52.000000000 -0800
3@@ -49,34 +49,27 @@
4 #include <sys/time.h>
3d9156a7
A
5 #include <sys/wait.h>
6
224c7076 7-#include <assert.h>
3d9156a7 8-#include <db.h>
224c7076 9-#include <errno.h>
3d9156a7
A
10 #include <fcntl.h>
11 #include <stdio.h>
224c7076
A
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <utmp.h>
16-/* don't define earlier, has side effects in fcntl.h */
17-#define __LIBC12_SOURCE__
3d9156a7 18 #include <utmpx.h>
224c7076
A
19+#include <utmpx-darwin.h>
20+#include <errno.h>
3d9156a7 21 #include <vis.h>
224c7076
A
22-
23-__warn_references(getlastlogx,
24- "warning: reference to compatibility getlastlogx(); include <utmpx.h> for correct reference")
25-__warn_references(lastlogxname,
26- "warning: reference to deprecated lastlogxname()")
27+#include <notify.h>
3d9156a7 28
224c7076 29 static FILE *fp;
3d9156a7
A
30 static int readonly = 0;
31 static struct utmpx ut;
32 static char utfile[MAXPATHLEN] = _PATH_UTMPX;
33-static char llfile[MAXPATHLEN] = _PATH_LASTLOGX;
224c7076
A
34+__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */
35
36-static struct utmpx *utmp_update(const struct utmpx *);
37+static struct utmpx *_getutxid(const struct utmpx *);
38
39-static const char vers[] = "utmpx-1.00";
40+__private_extern__ const char _utmpx_vers[] = "utmpx-1.00";
3d9156a7 41
224c7076
A
42 void
43 setutxent()
44@@ -85,7 +78,11 @@
45 (void)memset(&ut, 0, sizeof(ut));
46 if (fp == NULL)
47 return;
48+#ifdef __LP64__
49+ (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET);
50+#else /* __LP64__ */
51 (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET);
52+#endif /* __LP64__ */
53 }
54
55
56@@ -105,6 +102,9 @@
57 struct utmpx *
58 getutxent()
59 {
60+#ifdef __LP64__
61+ struct utmpx32 ut32;
62+#endif /* __LP64__ */
63
64 if (fp == NULL) {
65 struct stat st;
66@@ -124,42 +124,80 @@
67
68 if (st.st_size == 0) {
69 /* new file, add signature record */
70+#ifdef __LP64__
71+ (void)memset(&ut32, 0, sizeof(ut32));
72+ ut32.ut_type = SIGNATURE;
73+ (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
74+ if (fwrite(&ut32, sizeof(ut32), 1, fp) != 1)
75+#else /* __LP64__ */
76 (void)memset(&ut, 0, sizeof(ut));
77 ut.ut_type = SIGNATURE;
78- (void)memcpy(ut.ut_user, vers, sizeof(vers));
79+ (void)memcpy(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
80 if (fwrite(&ut, sizeof(ut), 1, fp) != 1)
81+#endif /* __LP64__ */
82 goto failclose;
83 } else {
84 /* old file, read signature record */
85+#ifdef __LP64__
86+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
87+#else /* __LP64__ */
88 if (fread(&ut, sizeof(ut), 1, fp) != 1)
89+#endif /* __LP64__ */
90 goto failclose;
91- if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 ||
92+#ifdef __LP64__
93+ if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
94+ ut32.ut_type != SIGNATURE)
95+#else /* __LP64__ */
96+ if (memcmp(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
97 ut.ut_type != SIGNATURE)
98+#endif /* __LP64__ */
99 goto failclose;
100 }
101 }
3d9156a7 102
224c7076
A
103+#ifdef __LP64__
104+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
105+#else /* __LP64__ */
106 if (fread(&ut, sizeof(ut), 1, fp) != 1)
107+#endif /* __LP64__ */
3d9156a7
A
108 goto fail;
109
224c7076
A
110+#ifdef __LP64__
111+ _utmpx32_64(&ut32, &ut);
112+#endif /* __LP64__ */
113 return &ut;
114 failclose:
115 (void)fclose(fp);
116+ fp = NULL;
117 fail:
118 (void)memset(&ut, 0, sizeof(ut));
119 return NULL;
120 }
121
122-
123 struct utmpx *
124 getutxid(const struct utmpx *utx)
125 {
126+ struct utmpx temp;
127+ const struct utmpx *ux;
128
129 _DIAGASSERT(utx != NULL);
130
131 if (utx->ut_type == EMPTY)
132 return NULL;
133
134+ /* make a copy as needed, and auto-fill if requested */
135+ ux = _utmpx_working_copy(utx, &temp, 1);
136+ if (!ux)
137+ return NULL;
138+
139+ return _getutxid(ux);
140+}
141+
142+
143+static struct utmpx *
144+_getutxid(const struct utmpx *utx)
145+{
146+
147 do {
148 if (ut.ut_type == EMPTY)
149 continue;
150@@ -225,30 +263,68 @@
151 struct utmpx *
152 pututxline(const struct utmpx *utx)
153 {
154- struct utmpx temp, *u = NULL;
155- int gotlock = 0;
156+ struct utmpx *ux;
157
158 _DIAGASSERT(utx != NULL);
159
160- if (utx == NULL)
161+ if (utx == NULL) {
162+ errno = EINVAL;
163 return NULL;
164+ }
165
166- if (strcmp(_PATH_UTMPX, utfile) == 0)
167- if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
168- return utmp_update(utx);
169+ if ((ux = _pututxline(utx)) != NULL && utfile_system) {
170+ _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */
3d9156a7 171+#ifdef UTMP_COMPAT
224c7076 172+ _write_utmp_compat(ux);
3d9156a7 173+#endif /* UTMP_COMPAT */
224c7076
A
174+ }
175+ return ux;
176+}
177
178+__private_extern__ struct utmpx *
179+_pututxline(const struct utmpx *utx)
180+{
181+ struct utmpx temp, *u = NULL, *x;
182+ const struct utmpx *ux;
183+#ifdef __LP64__
184+ struct utmpx32 ut32;
185+#endif /* __LP64__ */
186+ int gotlock = 0;
187
188- (void)memcpy(&temp, utx, sizeof(temp));
189+ if (utfile_system)
190+ if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) {
191+ errno = EPERM;
192+ return NULL;
193+ }
194
195 if (fp == NULL) {
196 (void)getutxent();
197- if (fp == NULL || readonly)
198+ if (fp == NULL || readonly) {
199+ errno = EPERM;
200 return NULL;
201+ }
202 }
203
204- if (getutxid(&temp) == NULL) {
205+ /* make a copy as needed, and auto-fill if requested */
206+ ux = _utmpx_working_copy(utx, &temp, 0);
207+ if (!ux)
208+ return NULL;
209+
210+ if ((x = _getutxid(ux)) == NULL) {
211 setutxent();
212- if (getutxid(&temp) == NULL) {
213+ if ((x = _getutxid(ux)) == NULL) {
214+ /*
215+ * utx->ut_type has any original mask bits, while
216+ * ux->ut_type has those mask bits removed. If we
217+ * are trying to record a dead process, and
218+ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since
219+ * there is no matching entry, we return NULL.
220+ */
221+ if (ux->ut_type == DEAD_PROCESS &&
222+ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) {
223+ errno = EINVAL;
224+ return NULL;
225+ }
226 if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
227 return NULL;
228 gotlock++;
229@@ -258,99 +334,66 @@
230 }
231
232 if (!gotlock) {
233+ /*
234+ * utx->ut_type has any original mask bits, while
235+ * ux->ut_type has those mask bits removed. If we
236+ * are trying to record a dead process, if
237+ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found
238+ * entry is not a (matching) USER_PROCESS, then return NULL.
239+ */
240+ if (ux->ut_type == DEAD_PROCESS &&
241+ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) &&
242+ x->ut_type != USER_PROCESS) {
243+ errno = EINVAL;
244+ return NULL;
245+ }
246 /* we are not appending */
247+#ifdef __LP64__
248+ if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1)
249+#else /* __LP64__ */
250 if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
251+#endif /* __LP64__ */
252 return NULL;
253 }
254
255- if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
256+#ifdef __LP64__
257+ _utmpx64_32(ux, &ut32);
258+ if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1)
259+#else /* __LP64__ */
260+ if (fwrite(ux, sizeof (*ux), 1, fp) != 1)
261+#endif /* __LP64__ */
262 goto fail;
263
264 if (fflush(fp) == -1)
265 goto fail;
266
267- u = memcpy(&ut, &temp, sizeof(ut));
268+ u = memcpy(&ut, ux, sizeof(ut));
269+ notify_post(UTMPX_CHANGE_NOTIFICATION);
3d9156a7
A
270 fail:
271 if (gotlock) {
224c7076 272+ int save = errno;
3d9156a7 273 if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
224c7076
A
274 return NULL;
275+ errno = save;
276 }
277 return u;
3d9156a7
A
278 }
279
224c7076
A
280
281-static struct utmpx *
282-utmp_update(const struct utmpx *utx)
283-{
284- char buf[sizeof(*utx) * 4 + 1];
285- pid_t pid;
286- int status;
287-
288- _DIAGASSERT(utx != NULL);
289-
290- (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx),
291- VIS_WHITE);
292- switch (pid = fork()) {
293- case 0:
294- (void)execl(_PATH_UTMP_UPDATE,
295- strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL);
296- exit(1);
297- /*NOTREACHED*/
298- case -1:
299- return NULL;
300- default:
301- if (waitpid(pid, &status, 0) == -1)
302- return NULL;
303- if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
304- return memcpy(&ut, utx, sizeof(ut));
305- return NULL;
306- }
307-
308-}
309-
310 /*
311 * The following are extensions and not part of the X/Open spec.
312 */
313 int
3d9156a7
A
314-updwtmpx(const char *file, const struct utmpx *utx)
315-{
316- int fd;
317- int saved_errno;
318-
319- _DIAGASSERT(file != NULL);
320- _DIAGASSERT(utx != NULL);
321-
322- fd = open(file, O_WRONLY|O_APPEND|O_SHLOCK);
323-
324- if (fd == -1) {
325- if ((fd = open(file, O_CREAT|O_WRONLY|O_EXLOCK, 0644)) == -1)
326- return -1;
327- (void)memset(&ut, 0, sizeof(ut));
328- ut.ut_type = SIGNATURE;
329- (void)memcpy(ut.ut_user, vers, sizeof(vers));
330- if (write(fd, &ut, sizeof(ut)) == -1)
331- goto failed;
224c7076 332- }
3d9156a7
A
333- if (write(fd, utx, sizeof(*utx)) == -1)
334- goto failed;
335- if (close(fd) == -1)
336- return -1;
337- return 0;
338-
339- failed:
340- saved_errno = errno;
341- (void) close(fd);
342- errno = saved_errno;
343- return -1;
344-}
345-
346-
347-int
224c7076
A
348 utmpxname(const char *fname)
349 {
350 size_t len;
351
3d9156a7 352- _DIAGASSERT(fname != NULL);
224c7076
A
353+ if (fname == NULL) {
354+ strcpy(utfile, _PATH_UTMPX);
355+ utfile_system = 1;
356+ endutxent();
357+ return 1;
358+ }
359
360 len = strlen(fname);
361
362@@ -363,6 +406,7 @@
363
364 (void)strlcpy(utfile, fname, sizeof(utfile));
365 endutxent();
366+ utfile_system = 0;
367 return 1;
368 }
369
370@@ -371,10 +415,8 @@
371 getutmp(const struct utmpx *ux, struct utmp *u)
372 {
373
3d9156a7
A
374- _DIAGASSERT(ux != NULL);
375- _DIAGASSERT(u != NULL);
376-
377- (void)memcpy(u->ut_name, ux->ut_name, sizeof(u->ut_name));
224c7076
A
378+ bzero(u, sizeof(*u));
379+ (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name));
380 (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
381 (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
382 u->ut_time = ux->ut_tv.tv_sec;
383@@ -384,109 +426,15 @@
384 getutmpx(const struct utmp *u, struct utmpx *ux)
385 {
386
3d9156a7
A
387- _DIAGASSERT(ux != NULL);
388- _DIAGASSERT(u != NULL);
389-
390- (void)memcpy(ux->ut_name, u->ut_name, sizeof(u->ut_name));
224c7076
A
391+ bzero(ux, sizeof(*ux));
392+ (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name));
393+ ux->ut_user[sizeof(u->ut_name)] = 0;
394 (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line));
395+ ux->ut_line[sizeof(u->ut_line)] = 0;
396 (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host));
397+ ux->ut_host[sizeof(u->ut_host)] = 0;
398 ux->ut_tv.tv_sec = u->ut_time;
399 ux->ut_tv.tv_usec = 0;
3d9156a7
A
400- (void)memset(&ux->ut_ss, 0, sizeof(ux->ut_ss));
401- ux->ut_pid = 0;
224c7076
A
402+ ux->ut_pid = getpid();
403 ux->ut_type = USER_PROCESS;
3d9156a7
A
404- ux->ut_session = 0;
405- ux->ut_exit.e_termination = 0;
406- ux->ut_exit.e_exit = 0;
407-}
408-
409-int
410-lastlogxname(const char *fname)
411-{
412- size_t len;
413-
414- _DIAGASSERT(fname != NULL);
415-
416- len = strlen(fname);
417-
418- if (len >= sizeof(llfile))
419- return 0;
420-
421- /* must end in x! */
422- if (fname[len - 1] != 'x')
423- return 0;
424-
425- (void)strlcpy(llfile, fname, sizeof(llfile));
426- return 1;
427-}
428-
429-struct lastlogx *
430-getlastlogx(uid_t uid, struct lastlogx *ll)
431-{
432-
433- return __getlastlogx13(_PATH_LASTLOGX, uid, ll);
434-}
435-
436-struct lastlogx *
437-__getlastlogx13(const char *fname, uid_t uid, struct lastlogx *ll)
438-{
439- DBT key, data;
440- DB *db;
441-
442- _DIAGASSERT(fname != NULL);
443- _DIAGASSERT(ll != NULL);
444-
445- db = dbopen(fname, O_RDONLY|O_SHLOCK, 0, DB_HASH, NULL);
446-
447- if (db == NULL)
448- return NULL;
449-
450- key.data = &uid;
451- key.size = sizeof(uid);
452-
453- if ((db->get)(db, &key, &data, 0) != 0)
454- goto error;
455-
456- if (data.size != sizeof(*ll)) {
457- errno = EFTYPE;
458- goto error;
224c7076
A
459- }
460-
3d9156a7
A
461- if (ll == NULL)
462- if ((ll = malloc(sizeof(*ll))) == NULL)
463- goto done;
464-
465- (void)memcpy(ll, data.data, sizeof(*ll));
466- goto done;
467-error:
468- ll = NULL;
469-done:
470- (db->close)(db);
471- return ll;
472-}
473-
474-int
475-updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
476-{
477- DBT key, data;
478- int error = 0;
479- DB *db;
480-
481- _DIAGASSERT(fname != NULL);
482- _DIAGASSERT(ll != NULL);
483-
484- db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0, DB_HASH, NULL);
485-
486- if (db == NULL)
487- return -1;
488-
489- key.data = &uid;
490- key.size = sizeof(uid);
491- data.data = ll;
492- data.size = sizeof(*ll);
493- if ((db->put)(db, &key, &data, 0) != 0)
494- error = -1;
495-
496- (db->close)(db);
497- return error;
3d9156a7 498 }