string.h stringlist.h strings.h struct.h sysexits.h tar.h time.h \
timeconv.h \
timers.h ttyent.h unistd.h ulimit.h utime.h utmp.h uuid.h vis.h \
- wchar.h wctype.h wordexp.h
+ utmpx.h wchar.h wctype.h wordexp.h
.if defined(WANT_HESIOD)
INCS+= hesiod.h
--- /dev/null
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UTMPX_H_
+#define _UTMPX_H_
+
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#define _PATH_UTMPX "/var/run/utmpx"
+#define _PATH_WTMPX "/var/log/wtmpx"
+#define _PATH_LASTLOGX "/var/log/lastlogx"
+#define _PATH_UTMP_UPDATE "/usr/libexec/utmp_update"
+
+#define _UTX_USERSIZE 32
+#define _UTX_LINESIZE 32
+#define _UTX_IDSIZE 4
+#define _UTX_HOSTSIZE 256
+
+#define UTX_USERSIZE _UTX_USERSIZE
+#define UTX_LINESIZE _UTX_LINESIZE
+#define UTX_IDSIZE _UTX_IDSIZE
+#define UTX_HOSTSIZE _UTX_HOSTSIZE
+
+
+#define EMPTY 0
+#define RUN_LVL 1
+#define BOOT_TIME 2
+#define OLD_TIME 3
+#define NEW_TIME 4
+#define INIT_PROCESS 5
+#define LOGIN_PROCESS 6
+#define USER_PROCESS 7
+#define DEAD_PROCESS 8
+
+#define ACCOUNTING 9
+#define SIGNATURE 10
+#define DOWN_TIME 11
+
+/*
+ * Strings placed in the ut_line field to indicate special type entries
+ */
+#define RUNLVL_MSG "run-level %c"
+#define BOOT_MSG "system boot"
+#define OTIME_MSG "old time"
+#define NTIME_MSG "new time"
+#define DOWN_MSG "system down"
+
+#define ut_user ut_name
+#define ut_xtime ut_tv.tv_sec
+
+struct exit_status
+{
+ uint16_t e_termination; /* termination status */
+ uint16_t e_exit; /* exit status */
+};
+
+struct utmpx {
+ char ut_name[_UTX_USERSIZE]; /* login name */
+ char ut_id[_UTX_IDSIZE]; /* inittab id */
+ char ut_line[_UTX_LINESIZE]; /* tty name */
+ char ut_host[_UTX_HOSTSIZE]; /* host name */
+ uint8_t ut_unused[16]; /* reserved for future use */
+ uint16_t ut_session; /* session id used for windowing */
+ uint16_t ut_type; /* type of this entry */
+ pid_t ut_pid; /* process id creating the entry */
+ struct exit_status ut_exit; /* process termination/exit status */
+ struct sockaddr_storage ut_ss; /* address where entry was made from */
+ struct timeval ut_tv; /* time entry was created */
+ uint8_t ut_unused2[16]; /* reserved for future use */
+};
+
+
+void endutxent(void);
+struct utmpx *getutxent(void);
+struct utmpx *getutxid(const struct utmpx *);
+struct utmpx *getutxline(const struct utmpx *);
+struct utmpx *pututxline(const struct utmpx *);
+void setutxent(void);
+
+/* NON-STANDARD functions, NetBSD specific stuff */
+struct lastlogx {
+ struct timeval ll_tv; /* time entry was created */
+ char ll_line[_UTX_LINESIZE]; /* tty name */
+ char ll_host[_UTX_HOSTSIZE]; /* host name */
+ struct sockaddr_storage ll_ss; /* address where entry was made from */
+};
+
+int updwtmpx(const char *, const struct utmpx *);
+struct lastlogx *getlastlogx(const char *, uid_t, struct lastlogx *);
+int updlastlogx(const char *, uid_t, struct lastlogx *);
+struct utmp;
+void getutmp(const struct utmpx *, struct utmp *);
+void getutmpx(const struct utmp *, struct utmpx *);
+int utmpxname(const char *);
+
+#endif /* _UTMPX_H_ */
+
sysctlnametomib.c syslog.c telldir.c termios.c time.c times.c \
toascii.c tolower.c toupper.c ttyname.c ttyslot.c \
ualarm.c ucontext.c ulimit.c uname.c unvis.c usleep.c utime.c \
+ utmpx.c \
valloc.c vis.c wait.c wait3.c waitpid.c wordexp.c
.if ${LIB} != {c_rtld}
--- /dev/null
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <utmpx.h>
+#include <vis.h>
+
+static FILE *fp;
+static int readonly = 0;
+static struct utmpx ut;
+static char utfile[MAXPATHLEN] = _PATH_UTMPX;
+
+static struct utmpx *utmp_update(const struct utmpx *);
+
+static const char vers[] = "utmpx-2.00";
+
+void
+setutxent()
+{
+
+ (void)memset(&ut, 0, sizeof(ut));
+ if (fp == NULL)
+ return;
+ (void)fseeko(fp, (off_t)sizeof(ut), SEEK_SET);
+}
+
+void
+endutxent()
+{
+
+ (void)memset(&ut, 0, sizeof(ut));
+ if (fp != NULL) {
+ (void)fclose(fp);
+ fp = NULL;
+ readonly = 0;
+ }
+}
+
+struct utmpx *
+getutxent()
+{
+
+ if (fp == NULL) {
+ struct stat st;
+
+ if ((fp = fopen(utfile, "r+")) == NULL)
+ if ((fp = fopen(utfile, "w+")) == NULL) {
+ if ((fp = fopen(utfile, "r")) == NULL)
+ goto fail;
+ else
+ readonly = 1;
+ }
+
+
+ /* get file size in order to check if new file */
+ if (fstat(fileno(fp), &st) == -1)
+ goto failclose;
+
+ if (st.st_size == 0) {
+ /* new file, add signature record */
+ (void)memset(&ut, 0, sizeof(ut));
+ ut.ut_type = SIGNATURE;
+ (void)memcpy(ut.ut_user, vers, sizeof(vers));
+ if (fwrite(&ut, sizeof(ut), 1, fp) != 1)
+ goto failclose;
+ } else {
+ /* old file, read signature record */
+ if (fread(&ut, sizeof(ut), 1, fp) != 1)
+ goto failclose;
+ if (memcmp(ut.ut_user, vers, 5) != 0 ||
+ ut.ut_type != SIGNATURE)
+ goto failclose;
+ }
+ }
+
+ if (fread(&ut, sizeof(ut), 1, fp) != 1)
+ goto fail;
+
+ return &ut;
+failclose:
+ (void)fclose(fp);
+fail:
+ (void)memset(&ut, 0, sizeof(ut));
+ return NULL;
+}
+
+struct utmpx *
+getutxid(const struct utmpx *utx)
+{
+
+ _DIAGASSERT(utx != NULL);
+
+ if (utx->ut_type == EMPTY)
+ return NULL;
+
+ do {
+ if (ut.ut_type == EMPTY)
+ continue;
+ switch (utx->ut_type) {
+ case EMPTY:
+ return NULL;
+ case RUN_LVL:
+ case BOOT_TIME:
+ case OLD_TIME:
+ case NEW_TIME:
+ if (ut.ut_type == utx->ut_type)
+ return &ut;
+ break;
+ case INIT_PROCESS:
+ case LOGIN_PROCESS:
+ case USER_PROCESS:
+ case DEAD_PROCESS:
+ switch (ut.ut_type) {
+ case INIT_PROCESS:
+ case LOGIN_PROCESS:
+ case USER_PROCESS:
+ case DEAD_PROCESS:
+ if (memcmp(ut.ut_id, utx->ut_id,
+ sizeof(ut.ut_id)) == 0)
+ return &ut;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ return NULL;
+ }
+ } while (getutxent() != NULL);
+ return NULL;
+}
+
+struct utmpx *
+getutxline(const struct utmpx *utx)
+{
+
+ _DIAGASSERT(utx != NULL);
+
+ do {
+ switch (ut.ut_type) {
+ case EMPTY:
+ break;
+ case LOGIN_PROCESS:
+ case USER_PROCESS:
+ if (strncmp(ut.ut_line, utx->ut_line,
+ sizeof(ut.ut_line)) == 0)
+ return &ut;
+ break;
+ default:
+ break;
+ }
+ } while (getutxent() != NULL);
+ return NULL;
+}
+
+struct utmpx *
+pututxline(const struct utmpx *utx)
+{
+ struct utmpx temp, *u = NULL;
+ int gotlock = 0;
+
+ _DIAGASSERT(utx != NULL);
+
+ if (utx == NULL)
+ return NULL;
+
+ if (strcmp(_PATH_UTMPX, utfile) == 0)
+ if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
+ return utmp_update(utx);
+
+
+ (void)memcpy(&temp, utx, sizeof(temp));
+
+ if (fp == NULL) {
+ (void)getutxent();
+ if (fp == NULL || readonly)
+ return NULL;
+ }
+
+ if (getutxid(&temp) == NULL) {
+ setutxent();
+ if (getutxid(&temp) == NULL) {
+ if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
+ return NULL;
+ gotlock++;
+ if (fseeko(fp, (off_t)0, SEEK_END) == -1)
+ goto fail;
+ }
+ }
+
+ if (!gotlock) {
+ /* we are not appending */
+ if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
+ return NULL;
+ }
+
+ if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
+ goto fail;
+
+ if (fflush(fp) == -1)
+ goto fail;
+
+ u = memcpy(&ut, &temp, sizeof(ut));
+fail:
+ if (gotlock) {
+ if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
+ return NULL;
+ }
+ return u;
+}
+
+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
+updwtmpx(const char *file, const struct utmpx *utx)
+{
+ int fd;
+ int saved_errno;
+
+ _DIAGASSERT(file != NULL);
+ _DIAGASSERT(utx != NULL);
+
+ fd = open(file, O_WRONLY|O_APPEND|O_SHLOCK);
+
+ if (fd == -1) {
+ 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));
+ if (write(fd, &ut, sizeof(ut)) == -1)
+ goto failed;
+ }
+ if (write(fd, utx, sizeof(*utx)) == -1)
+ goto failed;
+ if (close(fd) == -1)
+ return -1;
+ return 0;
+
+ failed:
+ saved_errno = errno;
+ (void) close(fd);
+ errno = saved_errno;
+ return -1;
+}
+
+int
+utmpxname(const char *fname)
+{
+ size_t len;
+
+ _DIAGASSERT(fname != NULL);
+
+ len = strlen(fname);
+
+ if (len >= sizeof(utfile))
+ return 0;
+
+ /* must end in x! */
+ if (fname[len - 1] != 'x')
+ return 0;
+
+ (void)strlcpy(utfile, fname, sizeof(utfile));
+ endutxent();
+ 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));
+ (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));
+ (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_type = USER_PROCESS;
+ ux->ut_session = 0;
+ ux->ut_exit.e_termination = 0;
+ ux->ut_exit.e_exit = 0;
+}
+
+struct lastlogx *
+getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
+{
+ DBT key, data;
+ DB *db;
+
+ _DIAGASSERT(fname != NULL);
+ _DIAGASSERT(ll != NULL);
+
+ db = dbopen(fname, 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;
+
+ _DIAGASSERT(fname != NULL);
+ _DIAGASSERT(ll != NULL);
+
+ db = dbopen(fname, O_RDWR|O_CREAT|O_EXLOCK, 0644, 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;
+}
SHLIB_MAJOR= 4
CFLAGS+=-DINET6
CFLAGS+=-D_CTYPE_H_DISABLE_MACROS_
-SRCS= flopen.c login.c login_tty.c logout.c logwtmp.c pty.c \
+SRCS= flopen.c login.c login_tty.c logout.c logwtmp.c logwtmpx.c pty.c \
login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
- login_crypt.c _secure_path.c uucplock.c property.c auth.c \
+ login_crypt.c loginx.c logoutx.c _secure_path.c uucplock.c \
+ property.c auth.c \
realhostname.c fparseln.c stub.c pidfile.c trimdomain.c \
dehumanize_number.c humanize_number.c humanize_unsigned.c pw_util.c
INCS= libutil.h login_cap.h
struct termios;
struct winsize;
struct utmp;
+struct utmpx;
struct in_addr;
struct sockaddr;
__BEGIN_DECLS
int flopen(const char *, int, ...);
void login(struct utmp *);
+void loginx(const struct utmpx *);
int login_tty(int);
int logout(const char *);
+int logoutx(const char *, int, int);
void logwtmp(const char *, const char *, const char *);
+void logwtmpx(const char *, const char *, const char *, int, int);
void trimdomain(char *, int);
int openpty(int *, int *, char *, struct termios *, struct winsize *);
int forkpty(int *, char *, struct termios *, struct winsize *);
--- /dev/null
+/* $NetBSD: loginx.c,v 1.2 2003/08/07 16:44:59 agc Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libutil.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+loginx(const struct utmpx *ut)
+{
+ (void)pututxline(ut);
+ (void)updwtmpx(_PATH_WTMPX, ut);
+}
--- /dev/null
+/* $NetBSD: logoutx.c,v 1.2 2003/08/07 16:44:59 agc Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <libutil.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+int
+logoutx(const char *line, int status, int type)
+{
+ struct utmpx *utp, ut;
+ (void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
+ if ((utp = getutxline(&ut)) == NULL) {
+ endutxent();
+ return 0;
+ }
+ utp->ut_type = type;
+ if (WIFEXITED(status))
+ utp->ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ utp->ut_exit.e_termination = (uint16_t)WTERMSIG(status);
+ (void)gettimeofday(&utp->ut_tv, NULL);
+ (void)pututxline(utp);
+ endutxent();
+ return 1;
+}
--- /dev/null
+/* $NetBSD: logwtmpx.c,v 1.2 2003/08/07 16:44:59 agc Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <utmpx.h>
+#include <libutil.h>
+
+void
+logwtmpx(const char *line, const char *name, const char *host, int status,
+ int type)
+{
+ struct utmpx ut;
+
+ _DIAGASSERT(line != NULL);
+ _DIAGASSERT(name != NULL);
+ _DIAGASSERT(host != NULL);
+
+ (void)memset(&ut, 0, sizeof(ut));
+ (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+ ut.ut_type = type;
+ if (WIFEXITED(status))
+ ut.ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ ut.ut_exit.e_termination = (uint16_t)WTERMSIG(status);
+ (void)gettimeofday(&ut.ut_tv, NULL);
+ (void)updwtmpx(_PATH_WTMPX, &ut);
+}
+