1 --- utmpx.c.orig 2008-07-17 11:34:16.000000000 -0700
2 +++ utmpx.c 2008-07-17 12:05:58.000000000 -0700
3 @@ -49,34 +49,29 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09
15 +#ifdef LEGACY_UTMP_APIS
17 -/* don't define earlier, has side effects in fcntl.h */
18 -#define __LIBC12_SOURCE__
19 +#endif /* LEGACY_UTMP_APIS */
21 +#include <utmpx-darwin.h>
25 -__warn_references(getlastlogx,
26 - "warning: reference to compatibility getlastlogx(); include <utmpx.h> for correct reference")
27 -__warn_references(lastlogxname,
28 - "warning: reference to deprecated lastlogxname()")
32 static int readonly = 0;
33 static struct utmpx ut;
34 static char utfile[MAXPATHLEN] = _PATH_UTMPX;
35 -static char llfile[MAXPATHLEN] = _PATH_LASTLOGX;
36 +__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */
38 -static struct utmpx *utmp_update(const struct utmpx *);
39 +static struct utmpx *_getutxid(const struct utmpx *);
41 -static const char vers[] = "utmpx-1.00";
42 +__private_extern__ const char _utmpx_vers[] = "utmpx-1.00";
46 @@ -85,7 +80,11 @@ setutxent()
47 (void)memset(&ut, 0, sizeof(ut));
51 + (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET);
53 (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET);
54 +#endif /* __LP64__ */
58 @@ -105,6 +104,9 @@ endutxent()
63 + struct utmpx32 ut32;
64 +#endif /* __LP64__ */
68 @@ -124,42 +126,80 @@ getutxent()
70 if (st.st_size == 0) {
71 /* new file, add signature record */
73 + (void)memset(&ut32, 0, sizeof(ut32));
74 + ut32.ut_type = SIGNATURE;
75 + (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
76 + if (fwrite(&ut32, sizeof(ut32), 1, fp) != 1)
78 (void)memset(&ut, 0, sizeof(ut));
79 ut.ut_type = SIGNATURE;
80 - (void)memcpy(ut.ut_user, vers, sizeof(vers));
81 + (void)memcpy(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
82 if (fwrite(&ut, sizeof(ut), 1, fp) != 1)
83 +#endif /* __LP64__ */
86 /* old file, read signature record */
88 + if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
90 if (fread(&ut, sizeof(ut), 1, fp) != 1)
91 +#endif /* __LP64__ */
93 - if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 ||
95 + if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
96 + ut32.ut_type != SIGNATURE)
98 + if (memcmp(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
99 ut.ut_type != SIGNATURE)
100 +#endif /* __LP64__ */
106 + if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
107 +#else /* __LP64__ */
108 if (fread(&ut, sizeof(ut), 1, fp) != 1)
109 +#endif /* __LP64__ */
113 + _utmpx32_64(&ut32, &ut);
114 +#endif /* __LP64__ */
120 (void)memset(&ut, 0, sizeof(ut));
126 getutxid(const struct utmpx *utx)
129 + const struct utmpx *ux;
131 _DIAGASSERT(utx != NULL);
133 if (utx->ut_type == EMPTY)
136 + /* make a copy as needed, and auto-fill if requested */
137 + ux = _utmpx_working_copy(utx, &temp, 1);
141 + return _getutxid(ux);
145 +static struct utmpx *
146 +_getutxid(const struct utmpx *utx)
150 if (ut.ut_type == EMPTY)
152 @@ -225,30 +265,68 @@ getutxline(const struct utmpx *utx)
154 pututxline(const struct utmpx *utx)
156 - struct utmpx temp, *u = NULL;
160 _DIAGASSERT(utx != NULL);
168 - if (strcmp(_PATH_UTMPX, utfile) == 0)
169 - if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
170 - return utmp_update(utx);
171 + if ((ux = _pututxline(utx)) != NULL && utfile_system) {
172 + _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */
174 + _write_utmp_compat(ux);
175 +#endif /* UTMP_COMPAT */
180 +__private_extern__ struct utmpx *
181 +_pututxline(const struct utmpx *utx)
183 + struct utmpx temp, *u = NULL, *x;
184 + const struct utmpx *ux;
186 + struct utmpx32 ut32;
187 +#endif /* __LP64__ */
190 - (void)memcpy(&temp, utx, sizeof(temp));
192 + if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) {
199 - if (fp == NULL || readonly)
200 + if (fp == NULL || readonly) {
206 - if (getutxid(&temp) == NULL) {
207 + /* make a copy as needed, and auto-fill if requested */
208 + ux = _utmpx_working_copy(utx, &temp, 0);
212 + if ((x = _getutxid(ux)) == NULL) {
214 - if (getutxid(&temp) == NULL) {
215 + if ((x = _getutxid(ux)) == NULL) {
217 + * utx->ut_type has any original mask bits, while
218 + * ux->ut_type has those mask bits removed. If we
219 + * are trying to record a dead process, and
220 + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since
221 + * there is no matching entry, we return NULL.
223 + if (ux->ut_type == DEAD_PROCESS &&
224 + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) {
228 if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
231 @@ -258,99 +336,66 @@ pututxline(const struct utmpx *utx)
236 + * utx->ut_type has any original mask bits, while
237 + * ux->ut_type has those mask bits removed. If we
238 + * are trying to record a dead process, if
239 + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found
240 + * entry is not a (matching) USER_PROCESS, then return NULL.
242 + if (ux->ut_type == DEAD_PROCESS &&
243 + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) &&
244 + x->ut_type != USER_PROCESS) {
248 /* we are not appending */
250 + if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1)
251 +#else /* __LP64__ */
252 if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
253 +#endif /* __LP64__ */
257 - if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
259 + _utmpx64_32(ux, &ut32);
260 + if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1)
261 +#else /* __LP64__ */
262 + if (fwrite(ux, sizeof (*ux), 1, fp) != 1)
263 +#endif /* __LP64__ */
266 if (fflush(fp) == -1)
269 - u = memcpy(&ut, &temp, sizeof(ut));
270 + u = memcpy(&ut, ux, sizeof(ut));
271 + notify_post(UTMPX_CHANGE_NOTIFICATION);
275 if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
283 -static struct utmpx *
284 -utmp_update(const struct utmpx *utx)
286 - char buf[sizeof(*utx) * 4 + 1];
290 - _DIAGASSERT(utx != NULL);
292 - (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx),
294 - switch (pid = fork()) {
296 - (void)execl(_PATH_UTMP_UPDATE,
297 - strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL);
303 - if (waitpid(pid, &status, 0) == -1)
305 - if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
306 - return memcpy(&ut, utx, sizeof(ut));
313 * The following are extensions and not part of the X/Open spec.
316 -updwtmpx(const char *file, const struct utmpx *utx)
321 - _DIAGASSERT(file != NULL);
322 - _DIAGASSERT(utx != NULL);
324 - fd = open(file, O_WRONLY|O_APPEND|O_SHLOCK);
327 - if ((fd = open(file, O_CREAT|O_WRONLY|O_EXLOCK, 0644)) == -1)
329 - (void)memset(&ut, 0, sizeof(ut));
330 - ut.ut_type = SIGNATURE;
331 - (void)memcpy(ut.ut_user, vers, sizeof(vers));
332 - if (write(fd, &ut, sizeof(ut)) == -1)
335 - if (write(fd, utx, sizeof(*utx)) == -1)
337 - if (close(fd) == -1)
342 - saved_errno = errno;
344 - errno = saved_errno;
350 utmpxname(const char *fname)
354 - _DIAGASSERT(fname != NULL);
355 + if (fname == NULL) {
356 + strcpy(utfile, _PATH_UTMPX);
364 @@ -363,18 +408,17 @@ utmpxname(const char *fname)
366 (void)strlcpy(utfile, fname, sizeof(utfile));
373 +#ifdef LEGACY_UTMP_APIS
375 getutmp(const struct utmpx *ux, struct utmp *u)
378 - _DIAGASSERT(ux != NULL);
379 - _DIAGASSERT(u != NULL);
381 - (void)memcpy(u->ut_name, ux->ut_name, sizeof(u->ut_name));
382 + bzero(u, sizeof(*u));
383 + (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name));
384 (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
385 (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
386 u->ut_time = ux->ut_tv.tv_sec;
387 @@ -384,109 +428,16 @@ void
388 getutmpx(const struct utmp *u, struct utmpx *ux)
391 - _DIAGASSERT(ux != NULL);
392 - _DIAGASSERT(u != NULL);
394 - (void)memcpy(ux->ut_name, u->ut_name, sizeof(u->ut_name));
395 + bzero(ux, sizeof(*ux));
396 + (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name));
397 + ux->ut_user[sizeof(u->ut_name)] = 0;
398 (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line));
399 + ux->ut_line[sizeof(u->ut_line)] = 0;
400 (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host));
401 + ux->ut_host[sizeof(u->ut_host)] = 0;
402 ux->ut_tv.tv_sec = u->ut_time;
403 ux->ut_tv.tv_usec = 0;
404 - (void)memset(&ux->ut_ss, 0, sizeof(ux->ut_ss));
406 + ux->ut_pid = getpid();
407 ux->ut_type = USER_PROCESS;
408 - ux->ut_session = 0;
409 - ux->ut_exit.e_termination = 0;
410 - ux->ut_exit.e_exit = 0;
414 -lastlogxname(const char *fname)
418 - _DIAGASSERT(fname != NULL);
420 - len = strlen(fname);
422 - if (len >= sizeof(llfile))
425 - /* must end in x! */
426 - if (fname[len - 1] != 'x')
429 - (void)strlcpy(llfile, fname, sizeof(llfile));
434 -getlastlogx(uid_t uid, struct lastlogx *ll)
437 - return __getlastlogx13(_PATH_LASTLOGX, uid, ll);
441 -__getlastlogx13(const char *fname, uid_t uid, struct lastlogx *ll)
446 - _DIAGASSERT(fname != NULL);
447 - _DIAGASSERT(ll != NULL);
449 - db = dbopen(fname, O_RDONLY|O_SHLOCK, 0, DB_HASH, NULL);
455 - key.size = sizeof(uid);
457 - if ((db->get)(db, &key, &data, 0) != 0)
460 - if (data.size != sizeof(*ll)) {
466 - if ((ll = malloc(sizeof(*ll))) == NULL)
469 - (void)memcpy(ll, data.data, sizeof(*ll));
479 -updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
485 - _DIAGASSERT(fname != NULL);
486 - _DIAGASSERT(ll != NULL);
488 - db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0, DB_HASH, NULL);
494 - key.size = sizeof(uid);
496 - data.size = sizeof(*ll);
497 - if ((db->put)(db, &key, &data, 0) != 0)
503 +#endif /* LEGACY_UTMP_APIS */