Loading...
--- Libc/Libc-583/gen/NetBSD/utmpx.c.patch
+++ Libc/Libc-391/gen/NetBSD/utmpx.c.patch
@@ -1,434 +1,53 @@
---- utmpx.c.orig 2009-04-01 04:01:12.000000000 -0700
-+++ utmpx.c 2009-04-01 04:09:50.000000000 -0700
-@@ -49,48 +49,57 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09
- #include <sys/time.h>
+--- utmpx.c.orig 2004-07-13 13:02:37.000000000 -0700
++++ utmpx.c 2004-08-05 15:25:10.000000000 -0700
+@@ -50,7 +50,6 @@
#include <sys/wait.h>
--#include <assert.h>
+ #include <assert.h>
-#include <db.h>
--#include <errno.h>
+ #include <errno.h>
#include <fcntl.h>
#include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-+#ifdef LEGACY_UTMP_APIS
- #include <utmp.h>
--/* don't define earlier, has side effects in fcntl.h */
--#define __LIBC12_SOURCE__
-+#endif /* LEGACY_UTMP_APIS */
+@@ -63,6 +62,13 @@
#include <utmpx.h>
-+#include <utmpx-darwin.h>
-+#include <errno.h>
#include <vis.h>
--
--__warn_references(getlastlogx,
-- "warning: reference to compatibility getlastlogx(); include <utmpx.h> for correct reference")
--__warn_references(lastlogxname,
-- "warning: reference to deprecated lastlogxname()")
-+#include <notify.h>
-
- static FILE *fp;
+
++#ifdef UTMP_COMPAT
++#include <utmp.h>
++#include <ttyent.h>
++
++static void _utmp_compat(const struct utmpx *);
++#endif /* UTMP_COMPAT */
++
+ __warn_references(getlastlogx,
+ "warning: reference to compatibility getlastlogx(); include <utmpx.h> for correct reference")
+ __warn_references(lastlogxname,
+@@ -72,7 +78,6 @@
static int readonly = 0;
static struct utmpx ut;
static char utfile[MAXPATHLEN] = _PATH_UTMPX;
-static char llfile[MAXPATHLEN] = _PATH_LASTLOGX;
-+__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */
-+__private_extern__ pthread_mutex_t utmpx_mutex = PTHREAD_MUTEX_INITIALIZER;
-
--static struct utmpx *utmp_update(const struct utmpx *);
-+static struct utmpx *_getutxid(const struct utmpx *);
-
--static const char vers[] = "utmpx-1.00";
-+__private_extern__ const char _utmpx_vers[] = "utmpx-1.00";
-
--void
--setutxent()
-+__private_extern__ void
-+_setutxent()
- {
-
- (void)memset(&ut, 0, sizeof(ut));
- if (fp == NULL)
- return;
-+#ifdef __LP64__
-+ (void)fseeko(fp, (off_t)sizeof(struct utmpx32), SEEK_SET);
-+#else /* __LP64__ */
- (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET);
-+#endif /* __LP64__ */
- }
-
-
- void
--endutxent()
-+setutxent()
-+{
-+ UTMPX_LOCK;
-+ _setutxent();
-+ UTMPX_UNLOCK;
-+}
-+
-+
-+__private_extern__ void
-+_endutxent()
- {
-
- (void)memset(&ut, 0, sizeof(ut));
-@@ -102,9 +111,21 @@ endutxent()
- }
-
-
--struct utmpx *
--getutxent()
-+void
-+endutxent()
- {
-+ UTMPX_LOCK;
-+ _endutxent();
-+ UTMPX_UNLOCK;
-+}
-+
-+
-+static struct utmpx *
-+_getutxent()
-+{
-+#ifdef __LP64__
-+ struct utmpx32 ut32;
-+#endif /* __LP64__ */
-
- if (fp == NULL) {
- struct stat st;
-@@ -116,7 +137,8 @@ getutxent()
- else
- readonly = 1;
- }
--
-+
-+ fcntl(fileno(fp), F_SETFD, 1); /* set close-on-exec flag */
-
- /* get file size in order to check if new file */
- if (fstat(fileno(fp), &st) == -1)
-@@ -124,27 +146,51 @@ getutxent()
-
- if (st.st_size == 0) {
- /* new file, add signature record */
-+#ifdef __LP64__
-+ (void)memset(&ut32, 0, sizeof(ut32));
-+ ut32.ut_type = SIGNATURE;
-+ (void)memcpy(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
-+ if (fwrite(&ut32, sizeof(ut32), 1, fp) != 1)
-+#else /* __LP64__ */
- (void)memset(&ut, 0, sizeof(ut));
- ut.ut_type = SIGNATURE;
-- (void)memcpy(ut.ut_user, vers, sizeof(vers));
-+ (void)memcpy(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers));
- if (fwrite(&ut, sizeof(ut), 1, fp) != 1)
-+#endif /* __LP64__ */
- goto failclose;
- } else {
- /* old file, read signature record */
-+#ifdef __LP64__
-+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
-+#else /* __LP64__ */
- if (fread(&ut, sizeof(ut), 1, fp) != 1)
-+#endif /* __LP64__ */
- goto failclose;
-- if (memcmp(ut.ut_user, vers, sizeof(vers)) != 0 ||
-+#ifdef __LP64__
-+ if (memcmp(ut32.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
-+ ut32.ut_type != SIGNATURE)
-+#else /* __LP64__ */
-+ if (memcmp(ut.ut_user, _utmpx_vers, sizeof(_utmpx_vers)) != 0 ||
- ut.ut_type != SIGNATURE)
-+#endif /* __LP64__ */
- goto failclose;
- }
- }
-
-+#ifdef __LP64__
-+ if (fread(&ut32, sizeof(ut32), 1, fp) != 1)
-+#else /* __LP64__ */
- if (fread(&ut, sizeof(ut), 1, fp) != 1)
-+#endif /* __LP64__ */
+
+ static struct utmpx *utmp_update(const struct utmpx *);
+
+@@ -270,6 +275,9 @@
goto fail;
-+#ifdef __LP64__
-+ _utmpx32_64(&ut32, &ut);
-+#endif /* __LP64__ */
- return &ut;
- failclose:
- (void)fclose(fp);
-+ fp = NULL;
- fail:
- (void)memset(&ut, 0, sizeof(ut));
- return NULL;
-@@ -152,14 +198,45 @@ fail:
-
-
- struct utmpx *
-+getutxent()
-+{
-+ struct utmpx *ret;
-+ UTMPX_LOCK;
-+ ret = _getutxent();
-+ UTMPX_UNLOCK;
-+ return ret;
-+}
-+
-+struct utmpx *
- getutxid(const struct utmpx *utx)
- {
-+ struct utmpx temp;
-+ const struct utmpx *ux;
-+ struct utmpx *ret;
-
- _DIAGASSERT(utx != NULL);
-
- if (utx->ut_type == EMPTY)
- return NULL;
-
-+ UTMPX_LOCK;
-+ /* make a copy as needed, and auto-fill if requested */
-+ ux = _utmpx_working_copy(utx, &temp, 1);
-+ if (!ux) {
-+ UTMPX_UNLOCK;
-+ return NULL;
-+ }
-+
-+ ret = _getutxid(ux);
-+ UTMPX_UNLOCK;
-+ return ret;
-+}
-+
-+
-+static struct utmpx *
-+_getutxid(const struct utmpx *utx)
-+{
-+
- do {
- if (ut.ut_type == EMPTY)
- continue;
-@@ -193,7 +270,7 @@ getutxid(const struct utmpx *utx)
- default:
- return NULL;
- }
-- } while (getutxent() != NULL);
-+ } while (_getutxent() != NULL);
- return NULL;
- }
-
-@@ -204,6 +281,7 @@ getutxline(const struct utmpx *utx)
-
- _DIAGASSERT(utx != NULL);
-
-+ UTMPX_LOCK;
- do {
- switch (ut.ut_type) {
- case EMPTY:
-@@ -211,13 +289,16 @@ getutxline(const struct utmpx *utx)
- case LOGIN_PROCESS:
- case USER_PROCESS:
- if (strncmp(ut.ut_line, utx->ut_line,
-- sizeof(ut.ut_line)) == 0)
-+ sizeof(ut.ut_line)) == 0) {
-+ UTMPX_UNLOCK;
- return &ut;
-+ }
- break;
- default:
- break;
- }
-- } while (getutxent() != NULL);
-+ } while (_getutxent() != NULL);
-+ UTMPX_UNLOCK;
- return NULL;
- }
-
-@@ -225,156 +306,180 @@ getutxline(const struct utmpx *utx)
- struct utmpx *
- pututxline(const struct utmpx *utx)
- {
-- struct utmpx temp, *u = NULL;
-- int gotlock = 0;
-+ struct utmpx *ux;
-
- _DIAGASSERT(utx != NULL);
-
-- if (utx == NULL)
-+ if (utx == NULL) {
-+ errno = EINVAL;
- return NULL;
-+ }
-
-- if (strcmp(_PATH_UTMPX, utfile) == 0)
-- if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
-- return utmp_update(utx);
--
-+ UTMPX_LOCK;
-+ if ((ux = _pututxline(utx)) != NULL && utfile_system) {
-+ _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */
+ u = memcpy(&ut, &temp, sizeof(ut));
+#ifdef UTMP_COMPAT
-+ _write_utmp_compat(ux);
++ _utmp_compat(u);
+#endif /* UTMP_COMPAT */
-+ }
-+ UTMPX_UNLOCK;
-+ return ux;
-+}
-
-- (void)memcpy(&temp, utx, sizeof(temp));
-+__private_extern__ struct utmpx *
-+_pututxline(const struct utmpx *utx)
-+{
-+ struct utmpx temp, *u = NULL, *x;
-+ const struct utmpx *ux;
-+#ifdef __LP64__
-+ struct utmpx32 ut32;
-+#endif /* __LP64__ */
-+ struct flock fl;
-+#define gotlock (fl.l_start >= 0)
-+
-+ fl.l_start = -1; /* also means we haven't locked */
-+ if (utfile_system)
-+ if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) {
-+ errno = EPERM;
-+ return NULL;
-+ }
-
- if (fp == NULL) {
-- (void)getutxent();
-- if (fp == NULL || readonly)
-+ (void)_getutxent();
-+ if (fp == NULL || readonly) {
-+ errno = EPERM;
- return NULL;
-+ }
- }
-
-- if (getutxid(&temp) == NULL) {
-- setutxent();
-- if (getutxid(&temp) == NULL) {
-- if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
-+ /* make a copy as needed, and auto-fill if requested */
-+ ux = _utmpx_working_copy(utx, &temp, 0);
-+ if (!ux)
-+ return NULL;
-+
-+ if ((x = _getutxid(ux)) == NULL) {
-+ _setutxent();
-+ if ((x = _getutxid(ux)) == NULL) {
-+ /*
-+ * utx->ut_type has any original mask bits, while
-+ * ux->ut_type has those mask bits removed. If we
-+ * are trying to record a dead process, and
-+ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, then since
-+ * there is no matching entry, we return NULL.
-+ */
-+ if (ux->ut_type == DEAD_PROCESS &&
-+ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK)) {
-+ errno = EINVAL;
-+ return NULL;
-+ }
-+ /*
-+ * Replace lockf() with fcntl() and a fixed start
-+ * value. We should already be at EOF.
-+ */
-+ if ((fl.l_start = lseek(fileno(fp), 0, SEEK_CUR)) < 0)
-+ return NULL;
-+ fl.l_len = 0;
-+ fl.l_whence = SEEK_SET;
-+ fl.l_type = F_WRLCK;
-+ if (fcntl(fileno(fp), F_SETLKW, &fl) == -1)
- return NULL;
-- gotlock++;
- if (fseeko(fp, (off_t)0, SEEK_END) == -1)
- goto fail;
- }
- }
-
- if (!gotlock) {
-+ /*
-+ * utx->ut_type has any original mask bits, while
-+ * ux->ut_type has those mask bits removed. If we
-+ * are trying to record a dead process, if
-+ * UTMPX_DEAD_IF_CORRESPONDING_MASK is set, but the found
-+ * entry is not a (matching) USER_PROCESS, then return NULL.
-+ */
-+ if (ux->ut_type == DEAD_PROCESS &&
-+ (utx->ut_type & UTMPX_DEAD_IF_CORRESPONDING_MASK) &&
-+ x->ut_type != USER_PROCESS) {
-+ errno = EINVAL;
-+ return NULL;
-+ }
- /* we are not appending */
-+#ifdef __LP64__
-+ if (fseeko(fp, -(off_t)sizeof(ut32), SEEK_CUR) == -1)
-+#else /* __LP64__ */
- if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
-+#endif /* __LP64__ */
- return NULL;
- }
-
-- if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
-+#ifdef __LP64__
-+ _utmpx64_32(ux, &ut32);
-+ if (fwrite(&ut32, sizeof (ut32), 1, fp) != 1)
-+#else /* __LP64__ */
-+ if (fwrite(ux, sizeof (*ux), 1, fp) != 1)
-+#endif /* __LP64__ */
- goto fail;
-
- if (fflush(fp) == -1)
- goto fail;
-
-- u = memcpy(&ut, &temp, sizeof(ut));
-+ u = memcpy(&ut, ux, sizeof(ut));
-+ notify_post(UTMPX_CHANGE_NOTIFICATION);
fail:
if (gotlock) {
-- if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
-+ int save = errno;
-+ fl.l_type = F_UNLCK;
-+ if (fcntl(fileno(fp), F_SETLK, &fl) == -1)
- return NULL;
-+ errno = save;
- }
- return u;
+ if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
+@@ -308,185 +316,50 @@
+
}
-
--static struct utmpx *
--utmp_update(const struct utmpx *utx)
--{
-- char buf[sizeof(*utx) * 4 + 1];
-- pid_t pid;
-- int status;
--
-- _DIAGASSERT(utx != NULL);
--
-- (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx),
-- VIS_WHITE);
-- switch (pid = fork()) {
-- case 0:
-- (void)execl(_PATH_UTMP_UPDATE,
-- strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL);
-- exit(1);
-- /*NOTREACHED*/
-- case -1:
-- return NULL;
-- default:
-- if (waitpid(pid, &status, 0) == -1)
-- return NULL;
-- if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
-- return memcpy(&ut, utx, sizeof(ut));
-- return NULL;
-- }
--
--}
--
- /*
- * The following are extensions and not part of the X/Open spec.
- */
- int
+-/*
+- * The following are extensions and not part of the X/Open spec.
+- */
+-int
-updwtmpx(const char *file, const struct utmpx *utx)
-{
- int fd;
@@ -447,7 +66,25 @@
- (void)memcpy(ut.ut_user, vers, sizeof(vers));
- if (write(fd, &ut, sizeof(ut)) == -1)
- goto failed;
-- }
++#ifdef UTMP_COMPAT
++static void
++_utmp_compat(const struct utmpx *ux)
++{
++ struct utmp u;
++ int fd, slot;
++ struct ttyent *ttyp;
++
++ switch (ux->ut_type) {
++ case INIT_PROCESS:
++ case LOGIN_PROCESS:
++ case USER_PROCESS:
++ break;
++ case DEAD_PROCESS:
++ logout(ux->ut_line);
++ return;
++ default:
++ return;
+ }
- if (write(fd, utx, sizeof(*utx)) == -1)
- goto failed;
- if (close(fd) == -1)
@@ -463,79 +100,55 @@
-
-
-int
- utmpxname(const char *fname)
- {
- size_t len;
-
-- _DIAGASSERT(fname != NULL);
-+ UTMPX_LOCK;
-+ if (fname == NULL) {
-+ strcpy(utfile, _PATH_UTMPX);
-+ utfile_system = 1;
-+ _endutxent();
-+ UTMPX_UNLOCK;
-+ return 1;
-+ }
-
- len = strlen(fname);
-
+-utmpxname(const char *fname)
+-{
+- size_t len;
+-
+- _DIAGASSERT(fname != NULL);
+-
+- len = strlen(fname);
+-
- if (len >= sizeof(utfile))
-+ if (len >= sizeof(utfile)) {
-+ UTMPX_UNLOCK;
- return 0;
-+ }
-
- /* must end in x! */
+- return 0;
+-
+- /* must end in x! */
- if (fname[len - 1] != 'x')
-+ if (fname[len - 1] != 'x') {
-+ UTMPX_UNLOCK;
- return 0;
-+ }
-
- (void)strlcpy(utfile, fname, sizeof(utfile));
+- return 0;
+-
+- (void)strlcpy(utfile, fname, sizeof(utfile));
- endutxent();
-+ _endutxent();
-+ utfile_system = 0;
-+ UTMPX_UNLOCK;
- return 1;
- }
-
--
-+#ifdef LEGACY_UTMP_APIS
- void
- getutmp(const struct utmpx *ux, struct utmp *u)
- {
-
+- return 1;
+-}
+-
+-
+-void
+-getutmp(const struct utmpx *ux, struct utmp *u)
+-{
+-
- _DIAGASSERT(ux != NULL);
- _DIAGASSERT(u != NULL);
-
- (void)memcpy(u->ut_name, ux->ut_name, sizeof(u->ut_name));
-+ bzero(u, sizeof(*u));
-+ (void)memcpy(u->ut_name, ux->ut_user, sizeof(u->ut_name));
- (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
- (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
- u->ut_time = ux->ut_tv.tv_sec;
-@@ -384,109 +489,16 @@ void
- getutmpx(const struct utmp *u, struct utmpx *ux)
- {
-
+- (void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
+- (void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
+- u->ut_time = ux->ut_tv.tv_sec;
+-}
+-
+-void
+-getutmpx(const struct utmp *u, struct utmpx *ux)
+-{
+-
- _DIAGASSERT(ux != NULL);
- _DIAGASSERT(u != NULL);
-
- (void)memcpy(ux->ut_name, u->ut_name, sizeof(u->ut_name));
-+ bzero(ux, sizeof(*ux));
-+ (void)memcpy(ux->ut_user, u->ut_name, sizeof(u->ut_name));
-+ ux->ut_user[sizeof(u->ut_name)] = 0;
- (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line));
-+ ux->ut_line[sizeof(u->ut_line)] = 0;
- (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host));
-+ ux->ut_host[sizeof(u->ut_host)] = 0;
- ux->ut_tv.tv_sec = u->ut_time;
- ux->ut_tv.tv_usec = 0;
+- (void)memcpy(ux->ut_line, u->ut_line, sizeof(u->ut_line));
+- (void)memcpy(ux->ut_host, u->ut_host, sizeof(u->ut_host));
+- ux->ut_tv.tv_sec = u->ut_time;
+- ux->ut_tv.tv_usec = 0;
- (void)memset(&ux->ut_ss, 0, sizeof(ux->ut_ss));
- ux->ut_pid = 0;
-+ ux->ut_pid = getpid();
- ux->ut_type = USER_PROCESS;
+- ux->ut_type = USER_PROCESS;
- ux->ut_session = 0;
- ux->ut_exit.e_termination = 0;
- ux->ut_exit.e_exit = 0;
@@ -591,8 +204,21 @@
- if (data.size != sizeof(*ll)) {
- errno = EFTYPE;
- goto error;
-- }
--
++ /* do equivalent of ttyslot(), but using ux->ut_slot */
++ setttyent();
++ slot = 1;
++ for(;;) {
++ if ((ttyp = getttyent()) == NULL) {
++ endttyent();
++ return;
++ }
++ if (!strcmp(ttyp->ty_name, ux->ut_line)) {
++ endttyent();
++ break;
++ }
++ slot++;
+ }
+
- if (ll == NULL)
- if ((ll = malloc(sizeof(*ll))) == NULL)
- goto done;
@@ -630,5 +256,16 @@
-
- (db->close)(db);
- return error;
++ /* now write utmp */
++ (void)memset(&u, 0, sizeof(u));
++ strncpy(u.ut_line, ux->ut_line, UT_LINESIZE);
++ strncpy(u.ut_name, ux->ut_user, UT_NAMESIZE);
++ strncpy(u.ut_host, ux->ut_host, UT_HOSTSIZE);
++ u.ut_time = ux->ut_tv.tv_sec;
++ if ((fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) {
++ (void)lseek(fd, (off_t)(slot * sizeof(struct utmp)), L_SET);
++ (void)write(fd, &u, sizeof(struct utmp));
++ (void)close(fd);
++ }
}
-+#endif /* LEGACY_UTMP_APIS */
++#endif /* UTMP_COMPAT */