]> git.saurik.com Git - apple/libc.git/blob - gen/NetBSD/utmpx.c.patch
Libc-763.12.tar.gz
[apple/libc.git] / gen / NetBSD / utmpx.c.patch
1 --- utmpx.c.orig 2010-06-24 19:43:32.000000000 -0700
2 +++ utmpx.c 2010-06-29 11:25:57.000000000 -0700
3 @@ -42,111 +42,240 @@ __RCSID("$NetBSD: utmpx.c,v 1.25 2008/04
4 #include <sys/time.h>
5 #include <sys/wait.h>
6
7 -#include <assert.h>
8 -#include <db.h>
9 -#include <errno.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 +#ifdef UNIFDEF_LEGACY_UTMP_APIS
16 #include <utmp.h>
17 +#endif /* UNIFDEF_LEGACY_UTMP_APIS */
18 #include <utmpx.h>
19 +#include <utmpx-darwin.h>
20 +#include <errno.h>
21 #include <vis.h>
22 +#include <notify.h>
23
24 -static FILE *fp;
25 -static int readonly = 0;
26 -static struct utmpx ut;
27 -static char utfile[MAXPATHLEN] = _PATH_UTMPX;
28 +/* This is the default struct _utmpx shared by the POSIX APIs */
29 +__private_extern__
30 +struct _utmpx __utx__ = {
31 + __UTX_MAGIC__, /* magic */
32 + {}, /* ut */
33 + PTHREAD_MUTEX_INITIALIZER, /* utmpx_mutex */
34 + _PATH_UTMPX, /* utfile */
35 + NULL, /* fp */
36 + 1, /* utfile_system */
37 + 0, /* readonly */
38 +};
39 +
40 +static struct utmpx *__getutxid(struct _utmpx *, const struct utmpx *);
41
42 -static struct utmpx *utmp_update(const struct utmpx *);
43 +__private_extern__ const char _utmpx_vers[] = "utmpx-1.00";
44
45 -static const char vers[] = "utmpx-1.00";
46 +__private_extern__ void
47 +__setutxent(struct _utmpx *U)
48 +{
49 +
50 + (void)memset(&U->ut, 0, sizeof(U->ut));
51 + if (U->fp == NULL)
52 + return;
53 +#ifdef __LP64__
54 + (void)fseeko(U->fp, (off_t)sizeof(struct utmpx32), SEEK_SET);
55 +#else /* __LP64__ */
56 + (void)fseeko(U->fp, (off_t)sizeof(U->ut), SEEK_SET);
57 +#endif /* __LP64__ */
58 +}
59
60 void
61 -setutxent()
62 +_setutxent(struct _utmpx *U)
63 {
64
65 - (void)memset(&ut, 0, sizeof(ut));
66 - if (fp == NULL)
67 - return;
68 - (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET);
69 + TEST_UTMPX_T("_setutxent", U);
70 + UTMPX_LOCK(U);
71 + __setutxent(U);
72 + UTMPX_UNLOCK(U);
73 }
74
75
76 void
77 -endutxent()
78 +setutxent()
79 {
80 + _setutxent(&__utx__);
81 +}
82 +
83
84 - (void)memset(&ut, 0, sizeof(ut));
85 - if (fp != NULL) {
86 - (void)fclose(fp);
87 - fp = NULL;
88 - readonly = 0;
89 +__private_extern__ void
90 +__endutxent(struct _utmpx *U)
91 +{
92 + (void)memset(&U->ut, 0, sizeof(U->ut));
93 + if (U->fp != NULL) {
94 + int saveerrno = errno;
95 + (void)fclose(U->fp);
96 + errno = saveerrno;
97 + U->fp = NULL;
98 + U->readonly = 0;
99 }
100 }
101
102
103 -struct utmpx *
104 -getutxent()
105 +void
106 +_endutxent(struct _utmpx *U)
107 {
108 + TEST_UTMPX_T("_endutxent", U);
109 + UTMPX_LOCK(U);
110 + __endutxent(U);
111 + UTMPX_UNLOCK(U);
112 +}
113
114 - if (fp == NULL) {
115 +
116 +void
117 +endutxent()
118 +{
119 + _endutxent(&__utx__);
120 +}
121 +
122 +
123 +__private_extern__ struct utmpx *
124 +__getutxent(struct _utmpx *U)
125 +{
126 + int saveerrno;
127 +#ifdef __LP64__
128 + struct utmpx32 ut32;
129 +#endif /* __LP64__ */
130 +
131 + if (U->fp == NULL) {
132 struct stat st;
133
134 - if ((fp = fopen(utfile, "r+")) == NULL)
135 - if ((fp = fopen(utfile, "w+")) == NULL) {
136 - if ((fp = fopen(utfile, "r")) == NULL)
137 + if ((U->fp = fopen(U->utfile, "r+")) == NULL)
138 + if ((U->fp = fopen(U->utfile, "w+")) == NULL) {
139 + if ((U->fp = fopen(U->utfile, "r")) == NULL)
140 goto fail;
141 else
142 - readonly = 1;
143 + U->readonly = 1;
144 }
145 -
146 +
147 + fcntl(fileno(U->fp), F_SETFD, 1); /* set close-on-exec flag */
148
149 /* get file size in order to check if new file */
150 - if (fstat(fileno(fp), &st) == -1)
151 + if (fstat(fileno(U->fp), &st) == -1)
152 goto failclose;
153
154 if (st.st_size == 0) {
155 /* new file, add signature record */
156 - (void)memset(&ut, 0, sizeof(ut));
157 - ut.ut_type = SIGNATURE;
158 - (void)memcpy(ut.ut_user, vers, sizeof(vers));
159 - if (fwrite(&ut, sizeof(ut), 1, fp) != 1)
160 +#ifdef __LP64__
161 + (void)memset(&ut32, 0, sizeof(ut32));
162 + ut32.ut_type = SIGNATURE;
163 + (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
164 + if (fwrite(&ut32, sizeof(ut32), 1, U->fp) != 1)
165 +#else /* __LP64__ */
166 + (void)memset(&U->ut, 0, sizeof(U->ut));
167 + U->ut.ut_type = SIGNATURE;
168 + (void)memcpy(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
169 + if (fwrite(&U->ut, sizeof(U->ut), 1, U->fp) != 1)
170 +#endif /* __LP64__ */
171 goto failclose;
172 } else {
173 /* old file, read signature record */
174 - if (fread(&ut, sizeof(ut), 1, fp) != 1)
175 +#ifdef __LP64__
176 + if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1)
177 +#else /* __LP64__ */
178 + if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1)
179 +#endif /* __LP64__ */
180 goto failclose;
181 - if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 ||
182 - ut.ut_type != SIGNATURE)
183 +#ifdef __LP64__
184 + if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
185 + ut32.ut_type != SIGNATURE)
186 +#else /* __LP64__ */
187 + if (memcmp(U->ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
188 + U->ut.ut_type != SIGNATURE)
189 +#endif /* __LP64__ */
190 + {
191 + errno = EINVAL;
192 goto failclose;
193 + }
194 }
195 }
196
197 - if (fread(&ut, sizeof(ut), 1, fp) != 1)
198 +#ifdef __LP64__
199 + if (fread(&ut32, sizeof(ut32), 1, U->fp) != 1)
200 +#else /* __LP64__ */
201 + if (fread(&U->ut, sizeof(U->ut), 1, U->fp) != 1)
202 +#endif /* __LP64__ */
203 goto fail;
204
205 - return &ut;
206 +#ifdef __LP64__
207 + _utmpx32_64(&ut32, &U->ut);
208 +#endif /* __LP64__ */
209 + return &U->ut;
210 failclose:
211 - (void)fclose(fp);
212 + saveerrno = errno;
213 + (void)fclose(U->fp);
214 + errno = saveerrno;
215 + U->fp = NULL;
216 fail:
217 - (void)memset(&ut, 0, sizeof(ut));
218 + (void)memset(&U->ut, 0, sizeof(U->ut));
219 return NULL;
220 }
221
222
223 struct utmpx *
224 -getutxid(const struct utmpx *utx)
225 +_getutxent(struct _utmpx *U)
226 {
227 + struct utmpx *ret;
228 +
229 + TEST_UTMPX_T("_getutxent", U);
230 + UTMPX_LOCK(U);
231 + ret = __getutxent(U);
232 + UTMPX_UNLOCK(U);
233 + return ret;
234 +}
235 +
236 +
237 +struct utmpx *
238 +getutxent()
239 +{
240 + return _getutxent(&__utx__);
241 +}
242
243 - _DIAGASSERT(utx != NULL);
244 +
245 +struct utmpx *
246 +_getutxid(struct _utmpx *U, const struct utmpx *utx)
247 +{
248 + struct utmpx temp;
249 + const struct utmpx *ux;
250 + struct utmpx *ret;
251
252 if (utx->ut_type == EMPTY)
253 return NULL;
254
255 + TEST_UTMPX_T("_getutxid", U);
256 + UTMPX_LOCK(U);
257 + /* make a copy as needed, and auto-fill if requested */
258 + ux = _utmpx_working_copy(utx, &temp, 1);
259 + if (!ux) {
260 + UTMPX_UNLOCK(U);
261 + return NULL;
262 + }
263 +
264 + ret = __getutxid(U, ux);
265 + UTMPX_UNLOCK(U);
266 + return ret;
267 +}
268 +
269 +
270 +struct utmpx *
271 +getutxid(const struct utmpx *utx)
272 +{
273 + return _getutxid(&__utx__, utx);
274 +}
275 +
276 +
277 +static struct utmpx *
278 +__getutxid(struct _utmpx *U, const struct utmpx *utx)
279 +{
280 +
281 do {
282 - if (ut.ut_type == EMPTY)
283 + if (U->ut.ut_type == EMPTY)
284 continue;
285 switch (utx->ut_type) {
286 case EMPTY:
287 @@ -155,21 +284,21 @@ getutxid(const struct utmpx *utx)
288 case BOOT_TIME:
289 case OLD_TIME:
290 case NEW_TIME:
291 - if (ut.ut_type == utx->ut_type)
292 - return &ut;
293 + if (U->ut.ut_type == utx->ut_type)
294 + return &U->ut;
295 break;
296 case INIT_PROCESS:
297 case LOGIN_PROCESS:
298 case USER_PROCESS:
299 case DEAD_PROCESS:
300 - switch (ut.ut_type) {
301 + switch (U->ut.ut_type) {
302 case INIT_PROCESS:
303 case LOGIN_PROCESS:
304 case USER_PROCESS:
305 case DEAD_PROCESS:
306 - if (memcmp(ut.ut_id, utx->ut_id,
307 - sizeof(ut.ut_id)) == 0)
308 - return &ut;
309 + if (memcmp(U->ut.ut_id, utx->ut_id,
310 + sizeof(U->ut.ut_id)) == 0)
311 + return &U->ut;
312 break;
313 default:
314 break;
315 @@ -178,188 +307,253 @@ getutxid(const struct utmpx *utx)
316 default:
317 return NULL;
318 }
319 - } while (getutxent() != NULL);
320 + } while (__getutxent(U) != NULL);
321 return NULL;
322 }
323
324
325 -struct utmpx *
326 -getutxline(const struct utmpx *utx)
327 +static struct utmpx *
328 +__getutxline(struct _utmpx *U, const struct utmpx *utx)
329 {
330 -
331 - _DIAGASSERT(utx != NULL);
332 -
333 do {
334 - switch (ut.ut_type) {
335 + switch (U->ut.ut_type) {
336 case EMPTY:
337 break;
338 case LOGIN_PROCESS:
339 case USER_PROCESS:
340 - if (strncmp(ut.ut_line, utx->ut_line,
341 - sizeof(ut.ut_line)) == 0)
342 - return &ut;
343 + if (strncmp(U->ut.ut_line, utx->ut_line,
344 + sizeof(U->ut.ut_line)) == 0)
345 + return &U->ut;
346 break;
347 default:
348 break;
349 }
350 - } while (getutxent() != NULL);
351 + } while (__getutxent(U) != NULL);
352 return NULL;
353 }
354
355
356 struct utmpx *
357 -pututxline(const struct utmpx *utx)
358 +_getutxline(struct _utmpx *U, const struct utmpx *utx)
359 +{
360 + struct utmpx *ret;
361 +
362 + TEST_UTMPX_T("_getutxline", U);
363 + UTMPX_LOCK(U);
364 + ret = __getutxline(U, utx);
365 + UTMPX_UNLOCK(U);
366 + return ret;
367 +}
368 +
369 +
370 +struct utmpx *
371 +getutxline(const struct utmpx *utx)
372 {
373 - struct utmpx temp, *u = NULL;
374 - int gotlock = 0;
375 + return _getutxline(&__utx__, utx);
376 +}
377
378 - _DIAGASSERT(utx != NULL);
379
380 - if (utx == NULL)
381 +struct utmpx *
382 +_pututxline(struct _utmpx *U, const struct utmpx *utx)
383 +{
384 + struct utmpx *ux;
385 +
386 + if (utx == NULL) {
387 + errno = EINVAL;
388 return NULL;
389 + }
390
391 - if (strcmp(_PATH_UTMPX, utfile) == 0)
392 - if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
393 - return utmp_update(utx);
394 + TEST_UTMPX_T("_pututxline", U);
395 + UTMPX_LOCK(U);
396 + if ((ux = __pututxline(&__utx__, utx)) != NULL && __utx__.utfile_system) {
397 + _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */
398 +#ifdef UTMP_COMPAT
399 + _write_utmp_compat(ux);
400 +#endif /* UTMP_COMPAT */
401 + }
402 + UTMPX_UNLOCK(U);
403 + return ux;
404 +}
405
406
407 - (void)memcpy(&temp, utx, sizeof(temp));
408 +struct utmpx *
409 +pututxline(const struct utmpx *utx)
410 +{
411 + return _pututxline(&__utx__, utx);
412 +}
413 +
414 +__private_extern__ struct utmpx *
415 +__pututxline(struct _utmpx *U, const struct utmpx *utx)
416 +{
417 + struct utmpx temp, *u = NULL, *x;
418 + const struct utmpx *ux;
419 +#ifdef __LP64__
420 + struct utmpx32 ut32;
421 +#endif /* __LP64__ */
422 + struct flock fl;
423 +#define gotlock (fl.l_start >= 0)
424 +
425 + fl.l_start = -1; /* also means we haven't locked */
426 + if (U->utfile_system)
427 + if ((U->fp != NULL && U->readonly) || (U->fp == NULL && geteuid() != 0)) {
428 + errno = EPERM;
429 + return NULL;
430 + }
431
432 - if (fp == NULL) {
433 - (void)getutxent();
434 - if (fp == NULL || readonly)
435 + if (U->fp == NULL) {
436 + (void)__getutxent(U);
437 + if (U->fp == NULL || U->readonly) {
438 + errno = EPERM;
439 return NULL;
440 + }
441 }
442
443 - if (getutxid(&temp) == NULL) {
444 - setutxent();
445 - if (getutxid(&temp) == NULL) {
446 - if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
447 + /* make a copy as needed, and auto-fill if requested */
448 + ux = _utmpx_working_copy(utx, &temp, 0);
449 + if (!ux)
450 + return NULL;
451 +
452 + if ((x = __getutxid(U, ux)) == NULL) {
453 + __setutxent(U);
454 + if ((x = __getutxid(U, ux)) == NULL) {
455 + /*
456 + * utx->ut_type has any original mask bits, while
457 + * ux->ut_type has those mask bits removed. If we
458 + * are trying to record a dead process, and
459 + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since
460 + * there is no matching entry, we return NULL.
461 + */
462 + if (ux->ut_type == DEAD_PROCESS &&
463 + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) {
464 + errno = EINVAL;
465 return NULL;
466 - gotlock++;
467 - if (fseeko(fp, (off_t)0, SEEK_END) == -1)
468 + }
469 + /*
470 + * Replace lockf() with fcntl() and a fixed start
471 + * value. We should already be at EOF.
472 + */
473 + if ((fl.l_start = lseek(fileno(U->fp), 0, SEEK_CUR)) < 0)
474 + return NULL;
475 + fl.l_len = 0;
476 + fl.l_whence = SEEK_SET;
477 + fl.l_type = F_WRLCK;
478 + if (fcntl(fileno(U->fp), F_SETLKW, &fl) == -1)
479 + return NULL;
480 + if (fseeko(U->fp, (off_t)0, SEEK_END) == -1)
481 goto fail;
482 }
483 }
484
485 if (!gotlock) {
486 + /*
487 + * utx->ut_type has any original mask bits, while
488 + * ux->ut_type has those mask bits removed. If we
489 + * are trying to record a dead process, if
490 + * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found
491 + * entry is not a (matching) USER_PROCESS, then return NULL.
492 + */
493 + if (ux->ut_type == DEAD_PROCESS &&
494 + (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) &&
495 + x->ut_type != USER_PROCESS) {
496 + errno = EINVAL;
497 + return NULL;
498 + }
499 /* we are not appending */
500 - if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
501 +#ifdef __LP64__
502 + if (fseeko(U->fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1)
503 +#else /* __LP64__ */
504 + if (fseeko(U->fp, -(off_t)sizeof(U->ut), SEEK_CUR) == -1)
505 +#endif /* __LP64__ */
506 return NULL;
507 }
508
509 - if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
510 +#ifdef __LP64__
511 + _utmpx64_32(ux, &ut32);
512 + if (fwrite(&ut32, sizeof (ut32), 1, U->fp) != 1)
513 +#else /* __LP64__ */
514 + if (fwrite(ux, sizeof (*ux), 1, U->fp) != 1)
515 +#endif /* __LP64__ */
516 goto fail;
517
518 - if (fflush(fp) == -1)
519 + if (fflush(U->fp) == -1)
520 goto fail;
521
522 - u = memcpy(&ut, &temp, sizeof(ut));
523 + u = memcpy(&U->ut, ux, sizeof(U->ut));
524 + notify_post(UTMPX_CHANGE_NOTIFICATION);
525 fail:
526 if (gotlock) {
527 - if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
528 + int save = errno;
529 + fl.l_type = F_UNLCK;
530 + if (fcntl(fileno(U->fp), F_SETLK, &fl) == -1)
531 return NULL;
532 + errno = save;
533 }
534 return u;
535 }
536
537
538 -static struct utmpx *
539 -utmp_update(const struct utmpx *utx)
540 -{
541 - char buf[sizeof(*utx) * 4 + 1];
542 - pid_t pid;
543 - int status;
544 -
545 - _DIAGASSERT(utx != NULL);
546 -
547 - (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx),
548 - VIS_WHITE);
549 - switch (pid = fork()) {
550 - case 0:
551 - (void)execl(_PATH_UTMP_UPDATE,
552 - strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL);
553 - _exit(1);
554 - /*NOTREACHED*/
555 - case -1:
556 - return NULL;
557 - default:
558 - if (waitpid(pid, &status, 0) == -1)
559 - return NULL;
560 - if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
561 - return memcpy(&ut, utx, sizeof(ut));
562 - return NULL;
563 - }
564 -
565 -}
566 -
567 /*
568 * The following are extensions and not part of the X/Open spec.
569 */
570 -int
571 -updwtmpx(const char *file, const struct utmpx *utx)
572 -{
573 - int fd;
574 - int saved_errno;
575 -
576 - _DIAGASSERT(file != NULL);
577 - _DIAGASSERT(utx != NULL);
578 -
579 - fd = open(file, O_WRONLY|O_APPEND|O_SHLOCK);
580 -
581 - if (fd == -1) {
582 - if ((fd = open(file, O_CREAT|O_WRONLY|O_EXLOCK, 0644)) == -1)
583 - return -1;
584 - (void)memset(&ut, 0, sizeof(ut));
585 - ut.ut_type = SIGNATURE;
586 - (void)memcpy(ut.ut_user, vers, sizeof(vers));
587 - if (write(fd, &ut, sizeof(ut)) == -1)
588 - goto failed;
589 - }
590 - if (write(fd, utx, sizeof(*utx)) == -1)
591 - goto failed;
592 - if (close(fd) == -1)
593 - return -1;
594 - return 0;
595 -
596 - failed:
597 - saved_errno = errno;
598 - (void) close(fd);
599 - errno = saved_errno;
600 - return -1;
601 -}
602 -
603 -
604 -int
605 -utmpxname(const char *fname)
606 +__private_extern__ int
607 +__utmpxname(struct _utmpx *U, const char *fname)
608 {
609 size_t len;
610
611 - _DIAGASSERT(fname != NULL);
612 + if (fname == NULL) {
613 + if(!U->utfile_system)
614 + free(U->utfile);
615 + U->utfile = _PATH_UTMPX;
616 + U->utfile_system = 1;
617 + __endutxent(U);
618 + return 1;
619 + }
620
621 len = strlen(fname);
622
623 - if (len >= sizeof(utfile))
624 + if (len >= MAXPATHLEN)
625 return 0;
626
627 /* must end in x! */
628 if (fname[len - 1] != 'x')
629 return 0;
630
631 - (void)strlcpy(utfile, fname, sizeof(utfile));
632 - endutxent();
633 + if (U->utfile_system)
634 + U->utfile = NULL;
635 + U->utfile_system = 0;
636 + if ((U->utfile = reallocf(U->utfile, len + 1)) == NULL)
637 + return 0;
638 +
639 + (void)strcpy(U->utfile, fname);
640 + __endutxent(U);
641 return 1;
642 }
643
644 +int
645 +_utmpxname(struct _utmpx *U, const char *fname)
646 +{
647 + int ret;
648 +
649 + TEST_UTMPX_T("_utmpxname", U);
650 + UTMPX_LOCK(U);
651 + ret = __utmpxname(U, fname);
652 + UTMPX_UNLOCK(U);
653 + return ret;
654 +}
655 +
656 +int
657 +utmpxname(const char *fname)
658 +{
659 + return _utmpxname(&__utx__, fname);
660 +}
661
662 +#ifdef UNIFDEF_LEGACY_UTMP_APIS
663 void
664 getutmp(const struct utmpx *ux, struct utmp *u)
665 {
666
667 - _DIAGASSERT(ux != NULL);
668 - _DIAGASSERT(u != NULL);
669 -
670 - (void)memcpy(u->ut_name, ux->ut_name, sizeof(u->ut_name));
671 + bzero(u, sizeof(*u));
672 + (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name));
673 (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
674 (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
675 u->ut_time = ux->ut_tv.tv_sec;
676 @@ -369,82 +563,16 @@ void
677 getutmpx(const struct utmp *u, struct utmpx *ux)
678 {
679
680 - _DIAGASSERT(ux != NULL);
681 - _DIAGASSERT(u != NULL);
682 -
683 - (void)memcpy(ux->ut_name, u->ut_name, sizeof(u->ut_name));
684 + bzero(ux, sizeof(*ux));
685 + (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name));
686 + ux->ut_user[sizeof(u->ut_name)] = 0;
687 (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line));
688 + ux->ut_line[sizeof(u->ut_line)] = 0;
689 (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host));
690 + ux->ut_host[sizeof(u->ut_host)] = 0;
691 ux->ut_tv.tv_sec = u->ut_time;
692 ux->ut_tv.tv_usec = 0;
693 - (void)memset(&ux->ut_ss, 0, sizeof(ux->ut_ss));
694 - ux->ut_pid = 0;
695 + ux->ut_pid = getpid();
696 ux->ut_type = USER_PROCESS;
697 - ux->ut_session = 0;
698 - ux->ut_exit.e_termination = 0;
699 - ux->ut_exit.e_exit = 0;
700 -}
701 -
702 -struct lastlogx *
703 -getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
704 -{
705 - DBT key, data;
706 - DB *db;
707 -
708 - _DIAGASSERT(fname != NULL);
709 - _DIAGASSERT(ll != NULL);
710 -
711 - db = dbopen(fname, O_RDONLY|O_SHLOCK, 0, DB_HASH, NULL);
712 -
713 - if (db == NULL)
714 - return NULL;
715 -
716 - key.data = &uid;
717 - key.size = sizeof(uid);
718 -
719 - if ((db->get)(db, &key, &data, 0) != 0)
720 - goto error;
721 -
722 - if (data.size != sizeof(*ll)) {
723 - errno = EFTYPE;
724 - goto error;
725 - }
726 -
727 - if (ll == NULL)
728 - if ((ll = malloc(sizeof(*ll))) == NULL)
729 - goto done;
730 -
731 - (void)memcpy(ll, data.data, sizeof(*ll));
732 - goto done;
733 -error:
734 - ll = NULL;
735 -done:
736 - (db->close)(db);
737 - return ll;
738 -}
739 -
740 -int
741 -updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
742 -{
743 - DBT key, data;
744 - int error = 0;
745 - DB *db;
746 -
747 - _DIAGASSERT(fname != NULL);
748 - _DIAGASSERT(ll != NULL);
749 -
750 - db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0644, DB_HASH, NULL);
751 -
752 - if (db == NULL)
753 - return -1;
754 -
755 - key.data = &uid;
756 - key.size = sizeof(uid);
757 - data.data = ll;
758 - data.size = sizeof(*ll);
759 - if ((db->put)(db, &key, &data, 0) != 0)
760 - error = -1;
761 -
762 - (db->close)(db);
763 - return error;
764 }
765 +#endif /* UNIFDEF_LEGACY_UTMP_APIS */