diff --git a/lib/libc/gen/utmpx.c b/lib/libc/gen/utmpx.c index b73d7af416be..6edf37951343 100644 --- a/lib/libc/gen/utmpx.c +++ b/lib/libc/gen/utmpx.c @@ -1,4 +1,4 @@ -/* $NetBSD: utmpx.c,v 1.8 2002/07/27 15:44:45 christos Exp $ */ +/* $NetBSD: utmpx.c,v 1.9 2002/07/27 19:38:29 christos Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: utmpx.c,v 1.8 2002/07/27 15:44:45 christos Exp $"); +__RCSID("$NetBSD: utmpx.c,v 1.9 2002/07/27 19:38:29 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include @@ -56,10 +56,13 @@ __RCSID("$NetBSD: utmpx.c,v 1.8 2002/07/27 15:44:45 christos Exp $"); #include #include #include +#include +#include static FILE *fp; static struct utmpx ut; static char utfile[MAXPATHLEN] = _PATH_UTMPX; +static char llfile[MAXPATHLEN] = _PATH_LASTLOGX; static struct utmpx *utmp_update(const struct utmpx *); @@ -280,14 +283,14 @@ utmp_update(const struct utmpx *utx) } -void +int updwtmpx(const char *file, const struct utmpx *utx) { - int fd = open(file, O_WRONLY | O_APPEND); + int fd = open(file, O_WRONLY|O_APPEND|O_EXLOCK); if (fd == -1) { - if ((fd = open(file, O_CREAT | O_WRONLY, 0644)) == -1) - return; + if ((fd = open(file, O_CREAT|O_WRONLY|O_EXLOCK, 0644)) == -1) + return -1; (void)memset(&ut, 0, sizeof(ut)); ut.ut_type = SIGNATURE; (void)memcpy(ut.ut_user, vers, sizeof(vers)); @@ -295,6 +298,7 @@ updwtmpx(const char *file, const struct utmpx *utx) } (void)write(fd, utx, sizeof(*utx)); (void)close(fd); + return 0; } @@ -345,3 +349,73 @@ getutmpx(const struct utmp *u, struct utmpx *ux) ux->ut_exit.e_termination = 0; ux->ut_exit.e_exit = 0; } + +int +lastlogxname(const char *fname) +{ + size_t len = strlen(fname); + + if (len >= sizeof(llfile)) + return 0; + + /* must end in x! */ + if (fname[len - 1] != 'x') + return 0; + + (void)strcpy(llfile, fname); + return 1; +} + +struct lastlogx * +getlastlogx(uid_t uid, struct lastlogx *ll) +{ + DBT key, data; + DB *db = dbopen(llfile, O_RDONLY|O_SHLOCK, 0, DB_HASH, NULL); + + if (db == NULL) + return NULL; + + key.data = &uid; + key.size = sizeof(uid); + + if ((db->get)(db, &key, &data, 0) != 0) + goto error; + + if (data.size != sizeof(*ll)) { + errno = EFTYPE; + goto error; + } + + if (ll == NULL) + if ((ll = malloc(sizeof(*ll))) == NULL) + goto done; + + (void)memcpy(ll, data.data, sizeof(*ll)); + goto done; +error: + ll = NULL; +done: + (db->close)(db); + return ll; +} + +int +updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll) +{ + DBT key, data; + int error = 0; + DB *db = dbopen(llfile, O_RDWR|O_CREAT|O_EXLOCK, 0, DB_HASH, NULL); + + if (db == NULL) + return -1; + + key.data = &uid; + key.size = sizeof(uid); + data.data = ll; + data.size = sizeof(*ll); + if ((db->put)(db, &key, &data, 0) != 0) + error = -1; + + (db->close)(db); + return error; +}