From 61fff62c2a1f35398ae93b333a963c73580d2189 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Fri, 6 Sep 2019 17:35:47 +0200
Subject: [PATCH] WIP utmp removal 20190906

---
 Makefile_upgrade.inc                          |  10 +
 bin/csh/csh/config.h                          |  10 +-
 bin/date/Makefile                             |   1 -
 bin/date/date.c                               |  12 -
 include/Makefile                              |   2 +-
 include/unistd.h                              |   1 -
 include/utmp.h                                |  72 ---
 include/utmpx.h                               |   3 +-
 lib/libc/Versions.def                         |   6 +-
 lib/libc/gen/Makefile.inc                     |   8 +-
 lib/libc/gen/Symbol.map                       |  13 +-
 lib/libc/gen/endutxent.3                      |  14 +
 lib/libc/gen/getlastlogx.3                    |  25 -
 lib/libc/gen/getttyent.3                      |   1 -
 lib/libc/gen/ttyname.3                        |  23 +-
 lib/libc/gen/ttyslot.c                        |  32 +-
 lib/libc/gen/utmp.c                           |  64 +--
 lib/libc/gen/utmpx.c                          |  51 +-
 lib/libpam/modules/pam_lastlog/pam_lastlog.c  |  89 ---
 lib/libssh/config.h                           |  30 +-
 lib/libutil/Makefile                          |   4 +-
 lib/libutil/libutil.h                         |   3 -
 lib/libutil/login.3                           |  65 ---
 lib/libutil/logout.3                          |  67 ---
 lib/libutil/logout.c                          |  67 ---
 lib/libutil/logwtmp.3                         |  71 ---
 lib/libutil/logwtmp.c                         |  98 ----
 libexec/comsat/Makefile                       |   2 +-
 libexec/comsat/comsat.8                       |   7 +-
 libexec/comsat/comsat.c                       | 130 ++---
 libexec/ftpd/logwtmp.c                        |  60 +-
 libexec/getty/ttys.5                          |   1 -
 .../login.c => libexec/rpc.rusersd/extern.h   |  35 +-
 libexec/rpc.rusersd/rpc.rusersd.8             |   5 +-
 libexec/rpc.rusersd/rusers_proc.c             | 216 +++-----
 libexec/rpc.rusersd/rusersd.c                 |  32 +-
 libexec/talkd/Makefile                        |   2 +-
 libexec/telnetd/Makefile                      |   3 +-
 libexec/telnetd/sys_term.c                    |   8 -
 libexec/telnetd/telnetd.8                     |  18 +-
 libexec/telnetd/telnetd.c                     |  24 -
 sbin/init/Makefile                            |   1 -
 sbin/init/init.c                              |  30 -
 sbin/reboot/Makefile                          |   1 -
 sbin/reboot/reboot.c                          |   7 -
 share/man/man5/Makefile                       |   3 -
 share/man/man5/utmp.5                         | 267 ---------
 share/man/man5/utmpx.5                        |   1 +
 sys/sys/param.h                               |   6 +-
 usr.bin/Makefile                              |   1 +
 usr.bin/finger/Makefile                       |   2 +-
 usr.bin/finger/lprint.c                       |   2 -
 usr.bin/finger/net.c                          |   1 -
 usr.bin/finger/sprint.c                       |   7 +-
 usr.bin/finger/util.c                         |  47 +-
 usr.bin/last/Makefile                         |   2 +-
 usr.bin/last/last.c                           | 263 ++++++---
 usr.bin/last/want.c                           | 223 --------
 usr.bin/systat/Makefile                       |   2 +-
 usr.bin/users/Makefile                        |   2 +-
 usr.bin/w/Makefile                            |   1 -
 usr.bin/w/w.c                                 |  80 +--
 usr.bin/wall/Makefile                         |   2 +-
 usr.bin/who/Makefile                          |   4 -
 usr.bin/who/utmpentry.c                       | 131 -----
 usr.bin/who/utmpentry.h                       |  17 +-
 usr.bin/who/who.c                             |   7 -
 usr.bin/write/Makefile                        |   2 +-
 usr.bin/wtmpcvt/Makefile                      |   5 +
 usr.bin/wtmpcvt/wtmpcvt.1                     |  66 +++
 usr.bin/wtmpcvt/wtmpcvt.c                     | 139 +++++
 usr.sbin/ac/Makefile                          |   2 +-
 usr.sbin/ac/ac.8                              |  54 +-
 usr.sbin/ac/ac.c                              | 513 +++++++++---------
 usr.sbin/adduser/adduser.8                    |   8 -
 usr.sbin/lastlogin/lastlogin.c                |  60 +-
 usr.sbin/ppp/id.c                             |  36 +-
 usr.sbin/ppp/id.h                             |  23 +-
 usr.sbin/ppp/physical.c                       |  27 +-
 usr.sbin/rwhod/rwhod.c                        |  82 +--
 usr.sbin/sshd/Makefile                        |   2 +-
 81 files changed, 1061 insertions(+), 2453 deletions(-)
 delete mode 100644 include/utmp.h
 delete mode 100644 lib/libutil/login.3
 delete mode 100644 lib/libutil/logout.3
 delete mode 100644 lib/libutil/logout.c
 delete mode 100644 lib/libutil/logwtmp.3
 delete mode 100644 lib/libutil/logwtmp.c
 rename lib/libutil/login.c => libexec/rpc.rusersd/extern.h (67%)
 delete mode 100644 share/man/man5/utmp.5
 delete mode 100644 usr.bin/last/want.c
 create mode 100644 usr.bin/wtmpcvt/Makefile
 create mode 100644 usr.bin/wtmpcvt/wtmpcvt.1
 create mode 100644 usr.bin/wtmpcvt/wtmpcvt.c

diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc
index 218ecc8510..0be7fcb258 100644
--- a/Makefile_upgrade.inc
+++ b/Makefile_upgrade.inc
@@ -3756,6 +3756,16 @@ TO_REMOVE+=/usr/sbin/rdate
 TO_REMOVE+=/usr/share/man/man8/rdate.8.gz
 TO_REMOVE+=/entropy
 TO_REMOVE+=/usr/share/man/man9/kmalloc_cachealign.9.gz
+TO_REMOVE+=/usr/include/utmp.h
+TO_REMOVE+=/usr/share/man/man3/getutmp.3.gz
+TO_REMOVE+=/usr/share/man/man3/getutmpx.3.gz
+TO_REMOVE+=/usr/share/man/man3/login.3.gz
+TO_REMOVE+=/usr/share/man/man3/logout.3.gz
+TO_REMOVE+=/usr/share/man/man3/logwtmp.3.gz
+TO_REMOVE+=/usr/share/man/man5/lastlog.5.gz
+TO_REMOVE+=/usr/share/man/man5/utmp.5.gz
+TO_REMOVE+=/usr/share/man/man5/wtmp.5.gz
+TO_REMOVE+=/usr/share/man/man3/ttyslot.3.gz
 
 .if !defined(WANT_INSTALLER)
 TO_REMOVE+=/usr/sbin/dfuibe_installer
diff --git a/bin/csh/csh/config.h b/bin/csh/csh/config.h
index 150e32eb5d..e619bb3ff1 100644
--- a/bin/csh/csh/config.h
+++ b/bin/csh/csh/config.h
@@ -150,16 +150,16 @@
 #define HAVE_STRUCT_UTMPX_UT_XTIME 1
 
 /* Define to 1 if `ut_host' is a member of `struct utmp'. */
-#define HAVE_STRUCT_UTMP_UT_HOST 1
+/* #undef HAVE_STRUCT_UTMP_UT_HOST */
 
 /* Define to 1 if `ut_tv' is a member of `struct utmp'. */
-#define HAVE_STRUCT_UTMP_UT_TV 1
+/* #undef HAVE_STRUCT_UTMP_UT_TV */
 
 /* Define to 1 if `ut_user' is a member of `struct utmp'. */
-#define HAVE_STRUCT_UTMP_UT_USER 1
+/* #undef HAVE_STRUCT_UTMP_UT_USER */
 
 /* Define to 1 if `ut_xtime' is a member of `struct utmp'. */
-#define HAVE_STRUCT_UTMP_UT_XTIME 1
+/* #undef HAVE_STRUCT_UTMP_UT_XTIME */
 
 /* Define to 1 if you have the `sysconf' function. */
 #define HAVE_SYSCONF 1
@@ -185,7 +185,7 @@
 #define HAVE_UTMPX_H 1
 
 /* Define to 1 if you have the <utmp.h> header file. */
-#define HAVE_UTMP_H 1
+/* #undef HAVE_UTMP_H */
 
 /* Define to 1 if you have the <wchar.h> header file. */
 #define HAVE_WCHAR_H 1
diff --git a/bin/date/Makefile b/bin/date/Makefile
index 525eacbd6d..8f51898d23 100644
--- a/bin/date/Makefile
+++ b/bin/date/Makefile
@@ -3,7 +3,6 @@
 
 PROG=	date
 SRCS=	date.c vary.c
-CFLAGS+=-DSUPPORT_UTMP -DSUPPORT_UTMPX
 
 DPADD=	${LIBUTIL}
 LDADD=	-lutil
diff --git a/bin/date/date.c b/bin/date/date.c
index 63384b43b0..5df335228f 100644
--- a/bin/date/date.c
+++ b/bin/date/date.c
@@ -43,9 +43,7 @@
 #include <unistd.h>
 #include <locale.h>
 #include <libutil.h>
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 
 #include "vary.h"
 
@@ -255,22 +253,12 @@ setthetime(const char *fmt, const char *p, int jflag)
 		errx(1, "nonexistent time");
 
 	if (!jflag) {
-#ifdef SUPPORT_UTMP
-		logwtmp("|", "date", "");
-#endif
-#ifdef SUPPORT_UTMPX
 		logwtmpx("|", "date", "", 0, OLD_TIME);
-#endif
 		tv.tv_sec = tval;
 		tv.tv_usec = 0;
 		if (settimeofday(&tv, NULL))
 			err(1, "settimeofday (timeval)");
-#ifdef SUPPORT_UTMP
-		logwtmp("{", "date", "");
-#endif
-#ifdef SUPPORT_UTMPX
 		logwtmpx("{", "date", "", 0, NEW_TIME);
-#endif
 
 		if ((p = getlogin()) == NULL)
 			p = "???";
diff --git a/include/Makefile b/include/Makefile
index 564cf02a73..0fbe3ca861 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -26,7 +26,7 @@ INCS=	a.out.h alloca.h ar.h assert.h bitstring.h cpio.h ctype.h db.h \
 	tar.h termios.h time.h \
 	timeconv.h \
 	timers.h ttyent.h \
-	uchar.h unistd.h ulimit.h utime.h utmp.h utmpx.h \
+	uchar.h unistd.h ulimit.h utime.h utmpx.h \
 	uuid.h vis.h \
 	wchar.h wctype.h wordexp.h xlocale.h
 
diff --git a/include/unistd.h b/include/unistd.h
index 6c6482bf6a..b6e6e81e39 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -596,7 +596,6 @@ int	 swapoff(const char *);
 int	 swapon(const char *);
 int	 syscall(int, ...);
 off_t	 __syscall(quad_t, ...);
-int	 ttyslot(void);
 int	 umtx_sleep(volatile const int *, int , int);
 int	 umtx_wakeup(volatile const int *, int);
 int	 undelete(const char *);
diff --git a/include/utmp.h b/include/utmp.h
deleted file mode 100644
index 3c62130501..0000000000
--- a/include/utmp.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1988, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * 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.
- *
- *	@(#)utmp.h	8.2 (Berkeley) 1/21/94
- * $FreeBSD: src/include/utmp.h,v 1.9 1999/08/27 23:44:53 peter Exp $
- * $DragonFly: src/include/utmp.h,v 1.2 2003/06/17 04:25:56 dillon Exp $
- */
-
-#ifndef	_UTMP_H_
-#define	_UTMP_H_
-
-#include <sys/cdefs.h>
-
-#define	_PATH_UTMP	"/var/run/utmp"
-#define	_PATH_WTMP	"/var/log/wtmp"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
-
-#define	UT_NAMESIZE	16	/* see MAXLOGNAME in <sys/param.h> */
-#define	UT_LINESIZE	8
-#define	UT_HOSTSIZE	16
-
-struct lastlog {
-	time_t	ll_time;
-	char	ll_line[UT_LINESIZE];
-	char	ll_host[UT_HOSTSIZE];
-};
-
-struct utmp {
-	char	ut_line[UT_LINESIZE];
-	char	ut_name[UT_NAMESIZE];
-	char	ut_host[UT_HOSTSIZE];
-	time_t	ut_time;
-};
-
-__BEGIN_DECLS
-int utmpname(const char *);
-void setutent(void);
-struct utmp *getutent(void);
-void endutent(void);
-__END_DECLS
-
-#endif /* !_UTMP_H_ */
diff --git a/include/utmpx.h b/include/utmpx.h
index 836b211e6f..eea46ea69d 100644
--- a/include/utmpx.h
+++ b/include/utmpx.h
@@ -139,9 +139,8 @@ void 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 *);
+struct utmpx *getutxuser(const char *);
 int setutxdb(utx_db_t, const char *);
 #endif
 __END_DECLS
diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def
index c97a1b3327..cce3fc43be 100644
--- a/lib/libc/Versions.def
+++ b/lib/libc/Versions.def
@@ -45,6 +45,10 @@ DF504.0 {
 DF506.0 {
 } DF504.0;
 
+# version for DragonFly 5.7
+DF508.0 {
+} DF506.0;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other DragonFly applications and libraries
 # are listed here.  We use a separate namespace so we can write
@@ -52,4 +56,4 @@ DF506.0 {
 #
 # Please do NOT increment the version of this namespace.
 DFprivate_1.0 {
-} DF506.0;
+} DF508.0;
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 08bdf7cf2a..32176113ba 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -105,6 +105,7 @@ MLINKS+=dlsym.3 dlfunc.3
 MLINKS+=endutxent.3 getutxent.3 \
 	endutxent.3 getutxid.3 \
 	endutxent.3 getutxline.3 \
+	endutxent.3 getutxuser.3 \
 	endutxent.3 pututxline.3 \
 	endutxent.3 setutxdb.3 \
 	endutxent.3 setutxent.3
@@ -169,9 +170,7 @@ MLINKS+=getgrent.3 endgrent.3 \
 	getgrent.3 setgroupent.3
 MLINKS+=gethostid.3 sethostid.3
 MLINKS+=gethostname.3 sethostname.3
-MLINKS+=getlastlogx.3 getutmp.3 \
-	getlastlogx.3 getutmpx.3 \
-	getlastlogx.3 updlastlogx.3 \
+MLINKS+=getlastlogx.3 updlastlogx.3 \
 	getlastlogx.3 _updwtmpx.3 \
 	getlastlogx.3 updwtmpx.3 \
 	getlastlogx.3 utmpxname.3
@@ -284,8 +283,7 @@ MLINKS+=tcsetattr.3 cfgetispeed.3 \
 	tcsetattr.3 cfsetspeed.3 \
 	tcsetattr.3 tcgetattr.3
 MLINKS+=ttyname.3 isatty.3 \
-	ttyname.3 ttyname_r.3 \
-	ttyname.3 ttyslot.3
+	ttyname.3 ttyname_r.3
 MLINKS+=tzset.3 tzsetwall.3
 MLINKS+=unvis.3 strnunvis.3 \
 	unvis.3 strnunvisx.3 \
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 6e305dd3e4..564888885f 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -172,23 +172,17 @@ DF404.0 {
     tcsetattr;
     tcsetpgrp;
 
-	/* utmp(x) */
-    endutent;
+	/* utmpx */
     endutxent;
     getlastlogx;
-    getutent;
-    getutmp;
-    getutmpx;
     getutxent;
     getutxid;
     getutxline;
     pututxline;
-    setutent;
     setutxdb;
     setutxent;
     updlastlogx;
     updwtmpx;
-    utmpname;
     utmpxname;
 
 	/* normal functions */
@@ -430,7 +424,6 @@ DF404.0 {
     times;
     ttyname;
     ttyname_r;
-    ttyslot;
     ualarm;
     ulimit;
     uname;
@@ -496,6 +489,10 @@ DF506.0 {
     dup3;
 };
 
+DF508.0 {
+    getutxuser;
+};
+
 DFprivate_1.0 {
 	/* pthread stubs */
     _pthread_atfork;
diff --git a/lib/libc/gen/endutxent.3 b/lib/libc/gen/endutxent.3
index 6f2264e866..c301dca57b 100644
--- a/lib/libc/gen/endutxent.3
+++ b/lib/libc/gen/endutxent.3
@@ -35,6 +35,7 @@
 .Nm getutxent ,
 .Nm getutxid ,
 .Nm getutxline ,
+.Nm getutxuser ,
 .Nm pututxline ,
 .Nm setutxent ,
 .Nm setutxdb
@@ -52,6 +53,8 @@
 .Ft struct utmpx *
 .Fn getutxline "const struct utmpx *"
 .Ft struct utmpx *
+.Fn getutxuser "const char *user"
+.Ft struct utmpx *
 .Fn pututxline "const struct utmpx *"
 .Ft void
 .Fn setutxent void
@@ -91,6 +94,16 @@ field, or
 .Dv NULL
 if no match is found.
 .Pp
+.Fn getutxuser
+searches for the next entry in the database whose
+.Fa ut_type
+has a value of
+.Dv USER_PROCESS
+and whose
+.Fa ut_user
+is equal to
+.Fa user .
+.Pp
 .Fn pututxline
 adds the argument
 .Xr utmpx 5
@@ -191,6 +204,7 @@ variable
 .Va errno
 is set to indicate the error.
 .Sh SEE ALSO
+.Xr wtmpcvt 1 ,
 .Xr logwtmpx 3 ,
 .Xr utmpx 5
 .Sh STANDARDS
diff --git a/lib/libc/gen/getlastlogx.3 b/lib/libc/gen/getlastlogx.3
index 83096f2b1a..678575b5e0 100644
--- a/lib/libc/gen/getlastlogx.3
+++ b/lib/libc/gen/getlastlogx.3
@@ -32,8 +32,6 @@
 .Os
 .Sh NAME
 .Nm getlastlogx ,
-.Nm getutmp ,
-.Nm getutmpx ,
 .Nm updlastlogx ,
 .Nm updwtmpx ,
 .Nm _updwtmpx ,
@@ -45,10 +43,6 @@
 .In utmpx.h
 .Ft struct lastlogx *
 .Fn getlastlogx "const char *fname" "uid_t uid" "struct lastlogx *ll"
-.Ft void
-.Fn getutmp "const struct utmpx *ux" "struct utmp *u"
-.Ft void
-.Fn getutmpx "const struct utmp *u" "struct utmpx *ux"
 .Ft int
 .Fn updlastlogx "const char *fname" "uid_t uid" "struct lastlogx *ll"
 .Ft void
@@ -79,23 +73,6 @@ and should be
 by the caller.
 .Pp
 The
-.Fn getutmp
-function fills out the entries in the struct utmp
-.Fa u
-with the data provided in the struct utmpx
-.Fa ux .
-.Fn getutmpx
-does the opposite, filling out the entries in the struct utmpx
-.Fa ux
-with the data provided in the struct utmp
-.Fa u ,
-and initializing all the unknown fields to 0.
-The sole exception is the
-.Fa ut_type
-field, which will be initialized to
-.Dv USER_PROCESS .
-.Pp
-The
 .Fn updlastlogx
 function tries to update the information for the user with the user id
 .Fa uid
@@ -164,8 +141,6 @@ could not be opened or the data not written into it.
 .Xr utmpx 5
 .Sh HISTORY
 The functions
-.Fn getutmp ,
-.Fn getutmpx ,
 .Fn updwtmpx ,
 .Fn _updwtmpx
 and
diff --git a/lib/libc/gen/getttyent.3 b/lib/libc/gen/getttyent.3
index 74d65280fd..4d05427130 100644
--- a/lib/libc/gen/getttyent.3
+++ b/lib/libc/gen/getttyent.3
@@ -188,7 +188,6 @@ zero otherwise.
 .El
 .Sh SEE ALSO
 .Xr login 1 ,
-.Xr ttyslot 3 ,
 .Xr gettytab 5 ,
 .Xr termcap 5 ,
 .Xr ttys 5 ,
diff --git a/lib/libc/gen/ttyname.3 b/lib/libc/gen/ttyname.3
index e0113bce59..53b1ebca13 100644
--- a/lib/libc/gen/ttyname.3
+++ b/lib/libc/gen/ttyname.3
@@ -35,8 +35,7 @@
 .Sh NAME
 .Nm ttyname ,
 .Nm ttyname_r ,
-.Nm isatty ,
-.Nm ttyslot
+.Nm isatty
 .Nd get name of associated terminal (tty) from file descriptor
 .Sh LIBRARY
 .Lb libc
@@ -48,8 +47,6 @@
 .Fn ttyname_r "int fd" "char *buf" "size_t len"
 .Ft int
 .Fn isatty "int fd"
-.Ft int
-.Fn ttyslot void
 .Sh DESCRIPTION
 These functions operate on the system file descriptors for terminal
 type devices.
@@ -91,13 +88,6 @@ The
 .Fn ttyname_r
 function
 takes a buffer and length as arguments to avoid this problem.
-.Pp
-The
-.Fn ttyslot
-function
-fetches the current process' control terminal number from the
-.Xr ttys 5
-file entry.
 .Sh RETURN VALUES
 The
 .Fn isatty
@@ -118,12 +108,6 @@ The
 .Fn ttyname_r
 function returns 0 if successful.
 Otherwise an error number is returned.
-.Pp
-The
-.Fn ttyslot
-function
-returns the unit number of the device file if found; otherwise
-the value zero is returned.
 .Sh FILES
 .Bl -tag -width ".Pa /etc/ttys" -compact
 .It Pa /dev/\(**
@@ -157,10 +141,9 @@ is smaller than the length of the string to be returned.
 .Xr ttys 5
 .Sh HISTORY
 The
-.Fn isatty ,
-.Fn ttyname ,
+.Fn isatty
 and
-.Fn ttyslot
+.Fn ttyname
 functions
 appeared in
 .At v7 .
diff --git a/lib/libc/gen/ttyslot.c b/lib/libc/gen/ttyslot.c
index 2aa46b3cf6..c0ee1af23a 100644
--- a/lib/libc/gen/ttyslot.c
+++ b/lib/libc/gen/ttyslot.c
@@ -27,39 +27,13 @@
  * SUCH DAMAGE.
  *
  * @(#)ttyslot.c	8.1 (Berkeley) 6/4/93
- * $DragonFly: src/lib/libc/gen/ttyslot.c,v 1.4 2005/11/13 00:07:42 swildner Exp $
  */
 
-#include <paths.h>
-#include <ttyent.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
+#include <sys/cdefs.h>
 
+__sym_compat(ttyslot, past_ttyslot, DF404.0);
 int
-ttyslot(void)
+past_ttyslot(void)
 {
-	struct ttyent *ttyp;
-	int slot;
-	int cnt;
-	char *name;
-	size_t len = sizeof(_PATH_DEV) - 1;
-
-	setttyent();
-	for (cnt = 0; cnt < 3; ++cnt)
-		if ( (name = ttyname(cnt)) ) {
-			if (strncmp(name, _PATH_DEV, len) != 0)
-				break;
-
-			name += len;
-
-			for (slot = 1; (ttyp = getttyent()); ++slot)
-				if (!strcmp(ttyp->ty_name, name)) {
-					endttyent();
-					return(slot);
-				}
-			break;
-		}
-	endttyent();
 	return(0);
 }
diff --git a/lib/libc/gen/utmp.c b/lib/libc/gen/utmp.c
index 6b24a450eb..09819673e8 100644
--- a/lib/libc/gen/utmp.c
+++ b/lib/libc/gen/utmp.c
@@ -29,74 +29,30 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "namespace.h"
-#include <sys/types.h>
 #include <sys/param.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <utmp.h>
-#include <sys/stat.h>
-#include "un-namespace.h"
-
-static struct utmp utmp;
-static FILE *ut;
-static char utfile[MAXPATHLEN] = _PATH_UTMP;
 
+__sym_compat(setutent, past_setutent, DF404.0);
 void
-setutent(void)
+past_setutent(void)
 {
-	if (ut == NULL)
-		return;
-	(void)fseeko(ut, (off_t)0, SEEK_SET);
 }
 
-struct utmp *
-getutent(void)
+__sym_compat(getutent, past_getutent, DF404.0);
+void *
+past_getutent(void)
 {
-	if (ut == NULL) {
-		struct stat st;
-		off_t numentries;
-		if ((ut = fopen(utfile, "r")) == NULL)
-			return NULL;
-		if (_fstat(fileno(ut), &st) == -1)
-			goto out;
-		/*
-		 * If we have a an old version utmp file bail.
-		 */
-		numentries = st.st_size / sizeof(utmp);
-		if ((off_t)(numentries * sizeof(utmp)) != st.st_size)
-			goto out;
-	}
-	if (fread(&utmp, sizeof(utmp), 1, ut) == 1)
-		return &utmp;
-out:
-	(void)fclose(ut);
 	return NULL;
 }
 
+__sym_compat(endutent, past_endutent, DF404.0);
 void
-endutent(void)
+past_endutent(void)
 {
-	if (ut != NULL) {
-		(void)fclose(ut);
-		ut = NULL;
-	}
 }
 
+__sym_compat(utmpname, past_utmpname, DF404.0);
 int
-utmpname(const char *fname)
+past_utmpname(const char *fname)
 {
-	size_t len = strlen(fname);
-
-	if (len >= sizeof(utfile))
-		return 0;
-
-	/* must not end in x! */
-	if (fname[len - 1] == 'x')
-		return 0;
-
-	(void)strlcpy(utfile, fname, sizeof(utfile));
-	endutent();
-	return 1;
+	return 0;
 }
diff --git a/lib/libc/gen/utmpx.c b/lib/libc/gen/utmpx.c
index 759658e2be..05db6e61a2 100644
--- a/lib/libc/gen/utmpx.c
+++ b/lib/libc/gen/utmpx.c
@@ -44,7 +44,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <pwd.h>
-#include <utmp.h>
 #include <utmpx.h>
 #include <vis.h>
 
@@ -240,6 +239,26 @@ getutxline(const struct utmpx *utx)
 	return NULL;
 }
 
+struct utmpx *
+getutxuser(const char *user)
+{
+	_DIAGASSERT(utx != NULL);
+
+	do {
+		switch (ut.ut_type) {
+		case EMPTY:
+			break;
+		case USER_PROCESS:
+			if (strncmp(ut.ut_user, user, sizeof(ut.ut_user)) == 0)
+				return &ut;
+			break;
+		default:
+			break;
+		}
+	} while (getutxent() != NULL);
+	return NULL;
+}
+
 struct utmpx *
 pututxline(const struct utmpx *utx)
 {
@@ -406,37 +425,17 @@ utmpxname(const char *fname)
 	return 1;
 }
 
+
+__sym_compat(getutmp, past_getutmp, DF404.0);
 void
-getutmp(const struct utmpx *ux, struct utmp *u)
+past_getutmp(void *ux, void *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;
 }
 
+__sym_compat(getutmpx, past_getutmpx, DF404.0);
 void
-getutmpx(const struct utmp *u, struct utmpx *ux)
+past_getutmpx(void *u, void *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 *
diff --git a/lib/libpam/modules/pam_lastlog/pam_lastlog.c b/lib/libpam/modules/pam_lastlog/pam_lastlog.c
index 983807e1e1..cd3561fa6b 100644
--- a/lib/libpam/modules/pam_lastlog/pam_lastlog.c
+++ b/lib/libpam/modules/pam_lastlog/pam_lastlog.c
@@ -64,30 +64,13 @@
 #include <security/pam_modules.h>
 #include <security/pam_mod_misc.h>
 
-#define SUPPORT_UTMP 1
-#define SUPPORT_UTMPX 1
-
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-static void doutmp(const char *, const char *, const char *,
-    const struct timeval *);
-static void dolastlog(pam_handle_t *, int, const struct passwd *, const char *,
-    const char *, const struct timeval *);
-#endif
-
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
 static void doutmpx(const char *, const char *, const char *,
     const struct sockaddr_storage *ss, const struct timeval *);
 static void dolastlogx(pam_handle_t *, int, const struct passwd *, const char *,
     const char *, const struct sockaddr_storage *ss, const struct timeval *);
-#endif
-
-#if defined(SUPPORT_UTMPX) || defined(SUPPORT_UTMP)
 static void domsg(pam_handle_t *, time_t, const char *, size_t, const char *,
     size_t);
-#endif
-
 static void logit(int, const char *, ...) __printflike(2, 3);
 
 static void
@@ -166,15 +149,9 @@ pam_sm_open_session(pam_handle_t *pamh, int flags,
 		quiet = 0;
 #endif
 	}
-#ifdef SUPPORT_UTMPX
 	dolastlogx(pamh, quiet, pwd, rhost, tty, NULL, &now);
 	doutmpx(user, rhost, tty, NULL, &now);
 	quiet = 1;
-#endif
-#ifdef SUPPORT_UTMP
-	doutmp(user, rhost, tty, &now);
-	dolastlog(pamh, quiet, pwd, rhost, tty, &now);
-#endif
 err:
 	if (openpam_get_option(pamh, "no_fail"))
 		return PAM_SUCCESS;
@@ -199,25 +176,15 @@ pam_sm_close_session(pam_handle_t *pamh __unused, int flags __unused,
 	if (*tty == '\0')
 		return PAM_SERVICE_ERR;
 
-#ifdef SUPPORT_UTMPX
 	if (logoutx(tty, 0, DEAD_PROCESS))
 		logwtmpx(tty, "", "", 0, DEAD_PROCESS);
 	else
 		logit(LOG_NOTICE, "%s(): no utmpx record for %s",
 		    __func__, tty);
-#endif
 
-#ifdef SUPPORT_UTMP
-	if (logout(tty))
-		logwtmp(tty, "", "");
-	else
-		logit(LOG_NOTICE, "%s(): no utmp record for %s",
-		    __func__, tty);
-#endif
         return PAM_SUCCESS;
 }
 
-#if defined(SUPPORT_UTMPX) || defined(SUPPORT_UTMP)
 static void
 domsg(pam_handle_t *pamh, time_t t, const char *host, size_t hsize,
     const char *line, size_t lsize)
@@ -237,9 +204,7 @@ domsg(pam_handle_t *pamh, time_t t, const char *host, size_t hsize,
 	if (pam_err == PAM_SUCCESS && promptresp)
 		free(promptresp);
 }
-#endif
 
-#ifdef SUPPORT_UTMPX
 static void
 doutmpx(const char *username, const char *hostname, const char *tty,
     const struct sockaddr_storage *ss, const struct timeval *now)
@@ -304,59 +269,5 @@ dolastlogx(pam_handle_t *pamh, int quiet, const struct passwd *pwd,
 	PAM_LOG("Login recorded in %s", _PATH_LASTLOGX);
 #endif
 }
-#endif
-
-#ifdef SUPPORT_UTMP
-static void
-doutmp(const char *username, const char *hostname, const char *tty,
-    const struct timeval *now)
-{
-	struct utmp utmp;
-
-	(void)memset((void *)&utmp, 0, sizeof(utmp));
-	utmp.ut_time = now->tv_sec;
-	(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
-	if (hostname)
-		(void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
-	(void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
-	login(&utmp);
-}
-
-static void
-dolastlog(pam_handle_t *pamh, int quiet, const struct passwd *pwd,
-    const char *hostname, const char *tty, const struct timeval *now)
-{
-	struct lastlog ll;
-	int fd;
-
-	if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) == -1) {
-		logit(LOG_NOTICE, "Cannot open `%s' %m", _PATH_LASTLOG);
-		return;
-	}
-	(void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)), SEEK_SET);
-
-	if (!quiet) {
-		if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
-		    ll.ll_time != 0)
-			domsg(pamh, ll.ll_time, ll.ll_host,
-			    sizeof(ll.ll_host), ll.ll_line,
-			    sizeof(ll.ll_line));
-		(void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)), SEEK_SET);
-	}
-
-	ll.ll_time = now->tv_sec;
-	(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
-
-	if (hostname)
-		(void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
-	else
-		(void)memset(ll.ll_host, 0, sizeof(ll.ll_host));
-
-	(void)write(fd, &ll, sizeof(ll));
-	(void)close(fd);
-
-	PAM_LOG("Login recorded in %s", _PATH_LASTLOG);
-}
-#endif
 
 PAM_MODULE_ENTRY("pam_lastlog");
diff --git a/lib/libssh/config.h b/lib/libssh/config.h
index f5a154417c..39f4c99214 100644
--- a/lib/libssh/config.h
+++ b/lib/libssh/config.h
@@ -95,13 +95,13 @@
 /* #undef CONF_LASTLOG_FILE */
 
 /* Define if you want to specify the path to your utmp file */
-#define CONF_UTMP_FILE "/var/run/utmp"
+/* #undef CONF_UTMP_FILE */
 
 /* Define if you want to specify the path to your wtmpx file */
-/* #undef CONF_WTMPX_FILE */
+#define CONF_WTMPX_FILE "/var/log/wtmpx"
 
 /* Define if you want to specify the path to your wtmp file */
-#define CONF_WTMP_FILE "/var/log/wtmp"
+/* #undef CONF_WTMP_FILE */
 
 /* Define if your platform needs to skip post auth file descriptor passing */
 /* #undef DISABLE_FD_PASSING */
@@ -110,7 +110,7 @@
 /* #undef DISABLE_LASTLOG */
 
 /* Define if you don't want to use your system's login() call */
-/* #undef DISABLE_LOGIN */
+#define DISABLE_LOGIN 1
 
 /* Define if you don't want to use pututline() etc. to write [uw]tmp */
 /* #undef DISABLE_PUTUTLINE */
@@ -122,16 +122,16 @@
 /* #undef DISABLE_SHADOW */
 
 /* Define if you don't want to use utmp */
-/* #undef DISABLE_UTMP */
+#define DISABLE_UTMP 1
 
 /* Define if you don't want to use utmpx */
 /* #undef DISABLE_UTMPX */
 
 /* Define if you don't want to use wtmp */
-/* #undef DISABLE_WTMP */
+#define DISABLE_WTMP 1
 
 /* Define if you don't want to use wtmpx */
-#define DISABLE_WTMPX 1
+/* #undef DISABLE_WTMPX */
 
 /* Enable for PKCS#11 support */
 /* #undef ENABLE_PKCS11 */
@@ -662,7 +662,7 @@
 #define HAVE_GETTTYENT 1
 
 /* Define to 1 if you have the `getutent' function. */
-#define HAVE_GETUTENT 1
+/* #undef HAVE_GETUTENT */
 
 /* Define to 1 if you have the `getutid' function. */
 /* #undef HAVE_GETUTID */
@@ -680,7 +680,7 @@
 #define HAVE_GETUTXLINE 1
 
 /* Define to 1 if you have the `getutxuser' function. */
-/* #undef HAVE_GETUTXUSER */
+#define HAVE_GETUTXUSER 1
 
 /* Define to 1 if you have the `get_default_context_with_level' function. */
 /* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
@@ -719,7 +719,7 @@
 #define HAVE_HMAC_CTX_INIT 1
 
 /* Define if you have ut_host in utmp.h */
-#define HAVE_HOST_IN_UTMP 1
+/* #undef HAVE_HOST_IN_UTMP */
 
 /* Define if you have ut_host in utmpx.h */
 #define HAVE_HOST_IN_UTMPX 1
@@ -848,7 +848,7 @@
 #define HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the `login' function. */
-#define HAVE_LOGIN 1
+/* #undef HAVE_LOGIN */
 
 /* Define to 1 if you have the <login_cap.h> header file. */
 #define HAVE_LOGIN_CAP_H 1
@@ -863,7 +863,7 @@
 #define HAVE_LOGOUT 1
 
 /* Define to 1 if you have the `logwtmp' function. */
-#define HAVE_LOGWTMP 1
+/* #undef HAVE_LOGWTMP */
 
 /* Define to 1 if the system has the type `long double'. */
 #define HAVE_LONG_DOUBLE 1
@@ -1469,7 +1469,7 @@
 #define HAVE_TIME_H 1
 
 /* Define if you have ut_time in utmp.h */
-#define HAVE_TIME_IN_UTMP 1
+/* #undef HAVE_TIME_IN_UTMP */
 
 /* Define if you have ut_time in utmpx.h */
 /* #undef HAVE_TIME_IN_UTMPX */
@@ -1544,7 +1544,7 @@
 #define HAVE_UTIME_H 1
 
 /* Define to 1 if you have the `utmpname' function. */
-#define HAVE_UTMPNAME 1
+/* #undef HAVE_UTMPNAME */
 
 /* Define to 1 if you have the `utmpxname' function. */
 #define HAVE_UTMPXNAME 1
@@ -1553,7 +1553,7 @@
 #define HAVE_UTMPX_H 1
 
 /* Define to 1 if you have the <utmp.h> header file. */
-#define HAVE_UTMP_H 1
+/* #undef HAVE_UTMP_H */
 
 /* define if you have u_char data type */
 #define HAVE_U_CHAR 1
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index 6736f7fb8a..40c750adbb 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -6,7 +6,7 @@ SHLIB_MAJOR= 4
 SHLIBDIR?= /lib
 CFLAGS+=-DINET6
 CFLAGS+=-D_CTYPE_H_DISABLE_MACROS_ 
-SRCS=	flopen.c login.c login_tty.c logout.c logwtmp.c logwtmpx.c pty.c \
+SRCS=	flopen.c login_tty.c logwtmpx.c pty.c \
 	login_cap.c login_class.c login_auth.c login_times.c login_ok.c \
 	login_crypt.c loginx.c logoutx.c _secure_path.c uucplock.c \
 	property.c auth.c \
@@ -20,7 +20,7 @@ INCSLINKS=libutil.h ${INCLUDEDIR}/util.h
 
 CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../libc/gen/
 
-MAN+=	flopen.3 login.3 loginx.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 \
+MAN+=	flopen.3 loginx.3 login_auth.3 login_tty.3 \
 	pty.3 \
 	login_cap.3 login_class.3 login_times.3 login_ok.3 \
 	_secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index aecac9c338..7cfbbaf4ca 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -67,12 +67,9 @@ struct utmpx;
 
 __BEGIN_DECLS
 char	*auth_getval(const char *_name);
-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	flopen(const char *_path, int _flags, ...);
diff --git a/lib/libutil/login.3 b/lib/libutil/login.3
deleted file mode 100644
index c4247bd3fd..0000000000
--- a/lib/libutil/login.3
+++ /dev/null
@@ -1,65 +0,0 @@
-.\"
-.\" Copyright (c) 1996 Joerg Wunsch
-.\"
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
-.\"
-.\" $FreeBSD: src/lib/libutil/login.3,v 1.5.2.3 2001/12/17 10:08:32 ru Exp $
-.\"
-.Dd December 29, 1996
-.Dt LOGIN 3
-.Os
-.Sh NAME
-.Nm login
-.Nd "log a new login record to the utmp and wtmp files"
-.Sh LIBRARY
-.Lb libutil
-.Sh SYNOPSIS
-.In sys/types.h
-.In utmp.h
-.In libutil.h
-.Ft void
-.Fn login "struct utmp *ut"
-.Sh DESCRIPTION
-The function
-.Fn login
-records the
-.Ar ut
-entry being passed into the appropriate slot of the
-.Xr utmp 5
-file (according to the controlling terminal of the calling process),
-and appends it to the
-.Xr wtmp 5
-file.  The calling process must have permission to write to both files.
-.Sh RETURN VALUES
-None.
-.Sh SEE ALSO
-.Xr logout 3 ,
-.Xr ttyslot 3 ,
-.Xr utmp 5 ,
-.Xr wtmp 5
-.Sh BUGS
-The interface provided by
-.Fn login
-is rather crude.  The caller must know about the details of a
-.Va struct utmp .
-Some better abstraction needs to be worked out.
diff --git a/lib/libutil/logout.3 b/lib/libutil/logout.3
deleted file mode 100644
index 6a5809004f..0000000000
--- a/lib/libutil/logout.3
+++ /dev/null
@@ -1,67 +0,0 @@
-.\"
-.\" Copyright (c) 1996 Joerg Wunsch
-.\"
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
-.\"
-.\" $FreeBSD: src/lib/libutil/logout.3,v 1.6.2.4 2001/12/17 10:08:32 ru Exp $
-.\"
-.Dd December 29, 1996
-.Dt LOGOUT 3
-.Os
-.Sh NAME
-.Nm logout
-.Nd remove an entry from the utmp file
-.Sh LIBRARY
-.Lb libutil
-.Sh SYNOPSIS
-.In sys/types.h
-.In libutil.h
-.Ft int
-.Fn logout "const char *line"
-.Sh DESCRIPTION
-The function
-.Fn logout
-searches the
-.Xr utmp 5
-file for the slot described by
-.Ar line
-(usually a tty name).  If such a slot could be found, it will be updated
-with a record where the
-.Em name
-and
-.Em host
-fields are empty, and the time stamp field is updated to the current time.
-.Sh RETURN VALUES
-.Fn Logout
-returns 1 if the slot described by
-.Ar line
-has been found and updated, 0 otherwise.
-.Sh SEE ALSO
-.Xr login 3 ,
-.Xr utmp 5 ,
-.Xr wtmp 5
-.Sh BUGS
-The calling interface of
-.Fn logout
-is inconsistent with that of
-.Xr login 3 .
diff --git a/lib/libutil/logout.c b/lib/libutil/logout.c
deleted file mode 100644
index 9667cbc3a4..0000000000
--- a/lib/libutil/logout.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * 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.
- *
- * @(#)logout.c	8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libutil/logout.c,v 1.6.2.2 2000/09/20 09:54:16 jkh Exp $
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <fcntl.h>
-#include <utmp.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libutil.h>
-
-typedef struct utmp UTMP;
-
-int
-logout(const char *line)
-{
-	int fd;
-	UTMP ut;
-	int rval;
-
-	if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0)
-		return(0);
-	rval = 0;
-	while (read(fd, &ut, sizeof(UTMP)) == sizeof(UTMP)) {
-		if (!ut.ut_name[0] || strncmp(ut.ut_line, line, UT_LINESIZE))
-			continue;
-		bzero(ut.ut_name, UT_NAMESIZE);
-		bzero(ut.ut_host, UT_HOSTSIZE);
-		(void)time(&ut.ut_time);
-		(void)lseek(fd, -(off_t)sizeof(UTMP), L_INCR);
-		(void)write(fd, &ut, sizeof(UTMP));
-		rval = 1;
-	}
-	(void)close(fd);
-	return(rval);
-}
diff --git a/lib/libutil/logwtmp.3 b/lib/libutil/logwtmp.3
deleted file mode 100644
index 7ec7318402..0000000000
--- a/lib/libutil/logwtmp.3
+++ /dev/null
@@ -1,71 +0,0 @@
-.\"
-.\" Copyright (c) 1996 Joerg Wunsch
-.\"
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
-.\"
-.\" $FreeBSD: src/lib/libutil/logwtmp.3,v 1.7.2.4 2001/12/17 10:08:32 ru Exp $
-.\"
-.Dd December 29, 1996
-.Dt LOGWTMP 3
-.Os
-.Sh NAME
-.Nm logwtmp
-.Nd append a new record to the wtmp file
-.Sh LIBRARY
-.Lb libutil
-.Sh SYNOPSIS
-.In sys/types.h
-.In libutil.h
-.Ft void
-.Fn logwtmp "const char *line" "const char *name" "const char *host"
-.Sh DESCRIPTION
-The function
-.Fn logwtmp
-tries to append a new record to the
-.Xr wtmp 5
-file, using the provided arguments
-.Ar line ,
-.Ar name ,
-and
-.Ar host ,
-and the current time.
-.Pp
-If the length of the hostname string
-.Ar host
-is longer than what would fit into the hostname field of the
-.Xr wtmp 5
-file, it will first be attempted to convert it into a numerical IP
-address using
-.Xr gethostbyname 3 .
-Failing this, the hostname will be recorded as
-.Qq invalid hostname .
-.Pp
-The calling process must have permission to write to the
-.Xr wtmp 5
-file.
-.Sh RETURN VALUES
-None.
-.Sh SEE ALSO
-.Xr gethostbyname 3 ,
-.Xr login 3 ,
-.Xr wtmp 5
diff --git a/lib/libutil/logwtmp.c b/lib/libutil/logwtmp.c
deleted file mode 100644
index a26237ffce..0000000000
--- a/lib/libutil/logwtmp.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * 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.
- *
- * @(#)logwtmp.c	8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libutil/logwtmp.c,v 1.14 2000/01/15 03:26:54 shin Exp $
- */
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <utmp.h>
-#include <libutil.h>
-
-/* wrapper for KAME-special getnameinfo() */
-#ifndef NI_WITHSCOPEID
-#define	NI_WITHSCOPEID	0
-#endif
-
-
-void
-logwtmp(const char *line, const char *name, const char *host)
-{
-	struct utmp ut;
-	struct stat buf;
-	char   fullhost[MAXHOSTNAMELEN];
-	int fd;
-	
-	strncpy(fullhost, host, sizeof(fullhost) - 1);	
-	fullhost[sizeof(fullhost) - 1] = '\0';
-	trimdomain(fullhost, UT_HOSTSIZE);
-	host = fullhost;
-
-	if (strlen(host) > UT_HOSTSIZE) {
-		int error;
-		struct addrinfo hints, *res;
-
-		bzero(&hints, sizeof(struct addrinfo));
-		hints.ai_family = AF_UNSPEC;
-		hints.ai_flags = AI_CANONNAME;
-		error = getaddrinfo(host, NULL, &hints, &res);
-		if (error != 0 || res->ai_addr == NULL)
-			host = "invalid hostname";
-		else {
-			error = getnameinfo(res->ai_addr, res->ai_addrlen,
-					  fullhost, strlen(fullhost), NULL, 0,
-					  NI_NUMERICHOST|NI_WITHSCOPEID);
-			if (error != 0) {
-			  fprintf(stderr, "%d", error);
-				host = "invalid hostname";
-			}
-		}
-	}
-
-	if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
-		return;
-	if (fstat(fd, &buf) == 0) {
-		(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));
-		(void) time(&ut.ut_time);
-		if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
-		    sizeof(struct utmp))
-			(void) ftruncate(fd, buf.st_size);
-	}
-	(void) close(fd);
-}
diff --git a/libexec/comsat/Makefile b/libexec/comsat/Makefile
index a5fe059e4c..151c2edaea 100644
--- a/libexec/comsat/Makefile
+++ b/libexec/comsat/Makefile
@@ -1,5 +1,5 @@
 #	@(#)Makefile	8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/libexec/comsat/Makefile,v 1.6.2.1 2001/04/25 10:40:50 ru Exp $
+# $FreeBSD: head/libexec/comsat/Makefile 74814 2001-03-26 14:22:12Z ru $
 
 PROG=	comsat
 MAN=	comsat.8
diff --git a/libexec/comsat/comsat.8 b/libexec/comsat/comsat.8
index 84e9a99393..0c4d1f8cf5 100644
--- a/libexec/comsat/comsat.8
+++ b/libexec/comsat/comsat.8
@@ -26,10 +26,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)comsat.8	8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/libexec/comsat/comsat.8,v 1.14 2005/02/13 23:45:48 ru Exp $
-.\" $DragonFly: src/libexec/comsat/comsat.8,v 1.3 2006/02/17 19:33:31 swildner Exp $
+.\" $FreeBSD: head/libexec/comsat/comsat.8 262136 2014-02-17 22:27:32Z brueffer $
 .\"
-.Dd August 9, 2002
+.Dd September 3, 2019
 .Dt COMSAT 8
 .Os
 .Sh NAME
@@ -88,7 +87,7 @@ If
 omitted, standard mailbox assumed.
 .Sh FILES
 .Bl -tag -width ".Pa /var/mail/user" -compact
-.It Pa /var/run/utmp
+.It Pa /var/run/utmpx
 to find out who is logged on and on what terminals
 .It Pa /var/mail/user
 standard mailbox
diff --git a/libexec/comsat/comsat.c b/libexec/comsat/comsat.c
index 07ecb9365a..85b8fff3f0 100644
--- a/libexec/comsat/comsat.c
+++ b/libexec/comsat/comsat.c
@@ -1,4 +1,6 @@
-/*
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
  * Copyright (c) 1980, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +29,7 @@
  * SUCH DAMAGE.
  *
  * @(#)comsat.c	8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/libexec/comsat/comsat.c,v 1.17 2005/02/14 17:42:56 stefanf Exp $
+ * $FreeBSD: head/libexec/comsat/comsat.c 326025 2017-11-20 19:49:47Z pfg $
  */
 
 #include <sys/param.h>
@@ -52,26 +54,22 @@
 #include <sysexits.h>
 #include <syslog.h>
 #include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
 
-int	debug = 0;
+static int	debug = 0;
 #define	dsyslog	if (debug) syslog
 
 #define MAXIDLE	120
 
-char	hostname[MAXHOSTNAMELEN];
-struct	utmp *utmp = NULL;
-time_t	lastmsgtime;
-int	nutmp, uf;
+static char	hostname[MAXHOSTNAMELEN];
 
-void jkfprintf (FILE *, const char *, const char *, off_t);
-void mailfor (char *);
-void notify (struct utmp *, char *, off_t, int);
-void onalrm (int);
-void reapchildren (int);
+static void	jkfprintf(FILE *, char[], char[], off_t);
+static void	mailfor(char *);
+static void	notify(struct utmpx *, char[], off_t, int);
+static void	reapchildren(int);
 
 int
-main(int argc __unused, char **argv __unused)
+main(int argc __unused, char *argv[] __unused)
 {
 	struct sockaddr_in from;
 	socklen_t fromlen;
@@ -88,15 +86,7 @@ main(int argc __unused, char **argv __unused)
 		recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
 		exit(1);
 	}
-	if ((uf = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
-		syslog(LOG_ERR, "open: %s: %m", _PATH_UTMP);
-		recv(0, msgbuf, sizeof(msgbuf) - 1, 0);
-		exit(1);
-	}
-	time(&lastmsgtime);
 	gethostname(hostname, sizeof(hostname));
-	onalrm(0);
-	signal(SIGALRM, onalrm);
 	signal(SIGTTOU, SIG_IGN);
 	signal(SIGCHLD, reapchildren);
 	for (;;) {
@@ -107,57 +97,28 @@ main(int argc __unused, char **argv __unused)
 			errno = 0;
 			continue;
 		}
-		if (!nutmp)		/* no one has logged in yet */
-			continue;
-		sigblock(sigmask(SIGALRM));
 		msgbuf[cc] = '\0';
-		time(&lastmsgtime);
 		mailfor(msgbuf);
 		sigsetmask(0L);
 	}
 }
 
-void
+static void
 reapchildren(int signo __unused)
 {
 	while (wait3(NULL, WNOHANG, NULL) > 0);
 }
 
-void
-onalrm(int signo __unused)
-{
-	static u_int utmpsize;		/* last malloced size for utmp */
-	static time_t utmpmtime;	/* last modification time for utmp */
-	struct stat statbf;
-
-	if (time(NULL) - lastmsgtime >= MAXIDLE)
-		exit(EX_OK);
-	alarm((u_int)15);
-	fstat(uf, &statbf);
-	if (statbf.st_mtime > utmpmtime) {
-		utmpmtime = statbf.st_mtime;
-		if (statbf.st_size > utmpsize) {
-			utmpsize = statbf.st_size + 10 * sizeof(struct utmp);
-			if ((utmp = realloc(utmp, utmpsize)) == NULL) {
-				syslog(LOG_ERR, "realloc: %m");
-				exit(1);
-			}
-		}
-		lseek(uf, (off_t)0, SEEK_SET);
-		nutmp = read(uf, utmp, (size_t)statbf.st_size)/sizeof(struct utmp);
-	}
-}
-
-void
+static void
 mailfor(char *name)
 {
-	struct utmp *utp = &utmp[nutmp];
+	struct utmpx *utp;
 	char *cp;
 	char *file;
 	off_t offset;
 	int folder;
-	char buf[sizeof(_PATH_MAILDIR) + sizeof(utmp[0].ut_name) + 1];
-	char buf2[sizeof(_PATH_MAILDIR) + sizeof(utmp[0].ut_name) + 1];
+	char buf[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1];
+	char buf2[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1];
 
 	if (!(cp = strchr(name, '@')))
 		return;
@@ -167,62 +128,71 @@ mailfor(char *name)
 		file = name;
 	else
 		file = cp + 1;
-	sprintf(buf, "%s/%.*s", _PATH_MAILDIR, (int)sizeof(utmp[0].ut_name),
+	sprintf(buf, "%s/%.*s", _PATH_MAILDIR, (int)sizeof(utp->ut_user),
 	    name);
 	if (*file != '/') {
 		sprintf(buf2, "%s/%.*s", _PATH_MAILDIR,
-		    (int)sizeof(utmp[0].ut_name), file);
+		    (int)sizeof(utp->ut_user), file);
 		file = buf2;
 	}
 	folder = strcmp(buf, file);
-	while (--utp >= utmp)
-		if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
+	setutxent();
+	while ((utp = getutxent()) != NULL)
+		if (utp->ut_type == USER_PROCESS && !strcmp(utp->ut_user, name))
 			notify(utp, file, offset, folder);
+	endutxent();
 }
 
 static const char *cr;
 
-void
-notify(struct utmp *utp, char *file, off_t offset, int folder)
+static void
+notify(struct utmpx *utp, char file[], off_t offset, int folder)
 {
 	FILE *tp;
 	struct stat stb;
 	struct termios tio;
-	char tty[20], name[sizeof(utmp[0].ut_name) + 1];
+	char tty[20];
+	const char *s = utp->ut_line;
 
-	snprintf(tty, sizeof(tty), "%s%.*s",
-	    _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
-	if (strchr(tty + sizeof(_PATH_DEV) - 1, '/')) {
+	if (strncmp(s, "pts/", 4) == 0)
+		s += 4;
+	if (strchr(s, '/')) {
 		/* A slash is an attempt to break security... */
-		syslog(LOG_AUTH | LOG_NOTICE, "'/' in \"%s\"", tty);
+		syslog(LOG_AUTH | LOG_NOTICE, "Unexpected `/' in `%s'",
+		    utp->ut_line);
 		return;
 	}
-	if (stat(tty, &stb) || !(stb.st_mode & (S_IXUSR | S_IXGRP))) {
-		dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_name, tty);
+	snprintf(tty, sizeof(tty), "%s%.*s",
+	    _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line);
+	if (stat(tty, &stb) == -1 || !(stb.st_mode & (S_IXUSR | S_IXGRP))) {
+		dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_user, tty);
 		return;
 	}
-	dsyslog(LOG_DEBUG, "notify %s on %s\n", utp->ut_name, tty);
-	if (fork())
+	dsyslog(LOG_DEBUG, "notify %s on %s", utp->ut_user, tty);
+	switch (fork()) {
+	case -1:
+		syslog(LOG_NOTICE, "fork failed (%m)");
 		return;
-	signal(SIGALRM, SIG_DFL);
-	alarm((u_int)30);
+	case 0:
+		break;
+	default:
+		return;
+	}
 	if ((tp = fopen(tty, "w")) == NULL) {
 		dsyslog(LOG_ERR, "%s: %s", tty, strerror(errno));
 		_exit(1);
 	}
 	tcgetattr(fileno(tp), &tio);
 	cr = ((tio.c_oflag & (OPOST|ONLCR)) == (OPOST|ONLCR)) ?  "\n" : "\n\r";
-	strncpy(name, utp->ut_name, sizeof(name) - 1);
-	name[sizeof(name) - 1] = '\0';
 	switch (stb.st_mode & (S_IXUSR | S_IXGRP)) {
 	case S_IXUSR:
 	case (S_IXUSR | S_IXGRP):
 		fprintf(tp, 
 		    "%s\007New mail for %s@%.*s\007 has arrived%s%s%s:%s----%s",
-		    cr, name, (int)sizeof(hostname), hostname,
+		    cr, utp->ut_user, (int)sizeof(hostname), hostname,
 		    folder ? cr : "", folder ? "to " : "", folder ? file : "",
 		    cr, cr);
-		jkfprintf(tp, name, file, offset);
+		jkfprintf(tp, utp->ut_user, file, offset);
 		break;
 	case S_IXGRP:
 		fprintf(tp, "\007");
@@ -237,8 +207,8 @@ notify(struct utmp *utp, char *file, off_t offset, int folder)
 	_exit(EX_OK);
 }
 
-void
-jkfprintf(FILE *tp, const char *user, const char *file, off_t offset)
+static void
+jkfprintf(FILE *tp, char user[], char file[], off_t offset)
 {
 	unsigned char *cp, ch;
 	FILE *fi;
@@ -253,7 +223,7 @@ jkfprintf(FILE *tp, const char *user, const char *file, off_t offset)
 	if ((fi = fopen(file, "r")) == NULL)
 		return;
 
-	fseeko(fi, offset, SEEK_SET);
+	fseeko(fi, offset, SEEK_CUR);
 	/*
 	 * Print the first 7 lines or 560 characters of the new mail
 	 * (whichever comes first).  Skip header crap other than
diff --git a/libexec/ftpd/logwtmp.c b/libexec/ftpd/logwtmp.c
index dd306fbd13..406d9a107a 100644
--- a/libexec/ftpd/logwtmp.c
+++ b/libexec/ftpd/logwtmp.c
@@ -1,4 +1,6 @@
-/*
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +29,7 @@
  * SUCH DAMAGE.
  *
  * @(#)logwtmp.c	8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/libexec/ftpd/logwtmp.c,v 1.9.2.2 2002/08/08 12:24:54 yar Exp $
+ * $FreeBSD: head/libexec/ftpd/logwtmp.c 326025 2017-11-20 19:49:47Z pfg $
  */
 
 #include <sys/types.h>
@@ -36,44 +38,36 @@
 #include <arpa/inet.h>
 #include <sys/socket.h>
 
-#include <fcntl.h>
-#include <time.h>
-#include <netdb.h>
-#include <utmp.h>
-#include <unistd.h>
+#include <libutil.h>
 #include <stdio.h>
 #include <string.h>
-#include <libutil.h>
+#include <unistd.h>
+#include <utmpx.h>
 #include "extern.h"
 
-static int fd = -1;
-
-/*
- * Modified version of logwtmp that holds wtmp file open
- * after first call, for use with ftp (which may chroot
- * after login, but before logout).
- */
 void
-ftpd_logwtmp(char *line, char *name, struct sockaddr *addr)
+ftpd_logwtmp(char *id, char *user, struct sockaddr *addr)
 {
-	struct utmp ut;
-	struct stat buf;
-	char host[UT_HOSTSIZE];
+	struct utmpx ut;
 
-	if (addr == NULL)
-		host[0] = '\0';
-	else
-		realhostname_sa(host, sizeof(host), addr, addr->sa_len);
+	memset(&ut, 0, sizeof(ut));
 
-	if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
-		return;
-	if (fstat(fd, &buf) == 0) {
-		(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));
-		(void)time(&ut.ut_time);
-		if (write(fd, &ut, sizeof(struct utmp)) !=
-		    sizeof(struct utmp))
-			(void)ftruncate(fd, buf.st_size);
+	if (user != NULL) {
+		/* Log in. */
+		ut.ut_type = USER_PROCESS;
+		(void)strncpy(ut.ut_user, user, sizeof(ut.ut_user));
+		if (addr != NULL)
+			realhostname_sa(ut.ut_host, sizeof(ut.ut_host),
+			    addr, addr->sa_len);
+	} else {
+		/* Log out. */
+		ut.ut_type = DEAD_PROCESS;
 	}
+
+	ut.ut_pid = getpid();
+	gettimeofday(&ut.ut_tv, NULL);
+	(void)strncpy(ut.ut_id, id, sizeof(ut.ut_id));
+	(void)strncpy(ut.ut_line, "ftpd", sizeof(ut.ut_line));
+
+	pututxline(&ut);
 }
diff --git a/libexec/getty/ttys.5 b/libexec/getty/ttys.5
index b7927f070a..414d030594 100644
--- a/libexec/getty/ttys.5
+++ b/libexec/getty/ttys.5
@@ -157,7 +157,6 @@ ttyp1	none	network	off	group=pty
 .Sh SEE ALSO
 .Xr login 1 ,
 .Xr getttyent 3 ,
-.Xr ttyslot 3 ,
 .Xr gettytab 5 ,
 .Xr login.conf 5 ,
 .Xr termcap 5 ,
diff --git a/lib/libutil/login.c b/libexec/rpc.rusersd/extern.h
similarity index 67%
rename from lib/libutil/login.c
rename to libexec/rpc.rusersd/extern.h
index 3b65e637f8..3186af03bc 100644
--- a/lib/libutil/login.c
+++ b/libexec/rpc.rusersd/extern.h
@@ -1,6 +1,8 @@
 /*-
- * Copyright (c) 1988, 1993
- *	The Regents of the University of California.  All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1993, John Brezak
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,32 +28,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)login.c	8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libutil/login.c,v 1.6 1999/08/28 00:05:45 peter Exp $
+ * $FreeBSD: head/libexec/rpc.rusersd/extern.h 326025 2017-11-20 19:49:47Z pfg $
  */
 
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <utmp.h>
-#include <libutil.h>
-
-void
-login(struct utmp *ut)
-{
-	int fd;
-	int tty;
+extern int from_inetd;
 
-	tty = ttyslot();
-	if (tty > 0 && (fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) {
-		(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), L_SET);
-		(void)write(fd, ut, sizeof(struct utmp));
-		(void)close(fd);
-	}
-	if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
-		(void)write(fd, ut, sizeof(struct utmp));
-		(void)close(fd);
-	}
-}
+void rusers_service(struct svc_req *, SVCXPRT *);
diff --git a/libexec/rpc.rusersd/rpc.rusersd.8 b/libexec/rpc.rusersd/rpc.rusersd.8
index ab25ee0546..019c39a1d0 100644
--- a/libexec/rpc.rusersd/rpc.rusersd.8
+++ b/libexec/rpc.rusersd/rpc.rusersd.8
@@ -27,10 +27,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/libexec/rpc.rusersd/rpc.rusersd.8,v 1.6.2.2 2001/08/16 10:44:17 ru Exp $
-.\" $DragonFly: src/libexec/rpc.rusersd/rpc.rusersd.8,v 1.2 2003/06/17 04:27:07 dillon Exp $
+.\" $FreeBSD: head/libexec/rpc.rusersd/rpc.rusersd.8 262136 2014-02-17 22:27:32Z brueffer $
 .\"
-.Dd June 7, 1993
+.Dd September 3, 2019
 .Dt RPC.RUSERSD 8
 .Os
 .Sh NAME
diff --git a/libexec/rpc.rusersd/rusers_proc.c b/libexec/rpc.rusersd/rusers_proc.c
index bbce3785d6..adcea32c16 100644
--- a/libexec/rpc.rusersd/rusers_proc.c
+++ b/libexec/rpc.rusersd/rusers_proc.c
@@ -1,4 +1,6 @@
 /*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
  * Copyright (c) 1993, John Brezak
  * All rights reserved.
  *
@@ -26,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/libexec/rpc.rusersd/rusers_proc.c,v 1.10 1999/08/28 00:09:56 peter Exp $
+ * $FreeBSD: head/libexec/rpc.rusersd/rusers_proc.c 326025 2017-11-20 19:49:47Z pfg $
  */
 
 #ifdef DEBUG
@@ -38,61 +40,31 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <syslog.h>
-#include <utmp.h>
+#include <utmpx.h>
 #ifdef XIDLE
 #include <setjmp.h>
 #include <X11/Xlib.h>
 #include <X11/extensions/xidle.h>
 #endif
-#define utmp rutmp
 #include <rpcsvc/rnusers.h>
-#undef utmp
-
-#define	IGNOREUSER	"sleeper"
 
-#ifdef OSF
-#define _PATH_UTMP UTMP_FILE
-#endif
-
-#ifndef _PATH_UTMP
-#define _PATH_UTMP "/etc/utmp"
-#endif
+#include "extern.h"
 
 #ifndef _PATH_DEV
 #define _PATH_DEV "/dev"
 #endif
 
-#ifndef UT_LINESIZE
-#define UT_LINESIZE sizeof(((struct utmp *)0)->ut_line)
-#endif
-#ifndef UT_NAMESIZE
-#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
-#endif
-#ifndef UT_HOSTSIZE
-#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
-#endif
-
-typedef char ut_line_t[UT_LINESIZE+1];
-typedef char ut_name_t[UT_NAMESIZE+1];
-typedef char ut_host_t[UT_HOSTSIZE+1];
-
-utmpidle utmp_idle[MAXUSERS];
-rutmp old_utmp[MAXUSERS];
-ut_line_t line[MAXUSERS];
-ut_name_t name[MAXUSERS];
-ut_host_t host[MAXUSERS];
-
-extern int from_inetd;
-
-FILE *ufp;
+static utmpidle utmp_idle[MAXUSERS];
+static utmp old_utmp[MAXUSERS];
+static struct utmpx utmp_list[MAXUSERS];
 
 #ifdef XIDLE
-Display *dpy;
+static Display *dpy;
 
 static jmp_buf openAbort;
 
 static void
-abortOpen ()
+abortOpen(void)
 {
     longjmp (openAbort, 1);
 }
@@ -114,14 +86,12 @@ XqueryIdle(char *display)
 				syslog(LOG_ERR, "%s: unable to get idle time", display);
 				return(-1);
 			}
-		}
-		else {
+		} else {
 			syslog(LOG_ERR, "%s: Xidle extension not loaded", display);
 			return(-1);
 		}
 		XCloseDisplay(dpy);
-	}
-	else {
+	} else {
 		syslog(LOG_ERR, "%s: server grabbed for over 10 seconds", display);
 		return(-1);
 	}
@@ -134,10 +104,10 @@ XqueryIdle(char *display)
 #endif
 
 static u_int
-getidle(char *tty, char *display)
+getidle(const char *tty, const char *display __unused)
 {
 	struct stat st;
-	char devname[PATH_MAX];
+	char ttyname[PATH_MAX];
 	time_t now;
 	u_long idle;
 
@@ -159,115 +129,87 @@ getidle(char *tty, char *display)
 #endif
 		mouse_idle = getidle("mouse", NULL);
 		idle = (kbd_idle < mouse_idle)?kbd_idle:mouse_idle;
-	}
-	else {
-		sprintf(devname, "%s/%s", _PATH_DEV, tty);
-		if (stat(devname, &st) < 0) {
+	} else {
+		sprintf(ttyname, "%s/%s", _PATH_DEV, tty);
+		if (stat(ttyname, &st) < 0) {
 #ifdef DEBUG
-			printf("%s: %s\n", devname, strerror(errno));
+			printf("%s: %s\n", ttyname, strerror(errno));
 #endif
 			return(-1);
 		}
 		time(&now);
 #ifdef DEBUG
-		printf("%s: now=%d atime=%d\n", devname, now,
+		printf("%s: now=%d atime=%d\n", ttyname, now,
 		       st.st_atime);
 #endif
 		idle = now - st.st_atime;
 		idle = (idle + 30) / 60; /* secs->mins */
 	}
-	if (idle < 0) idle = 0;
 
 	return(idle);
 }
 
 static utmpidlearr *
-do_names_2(int all)
+do_names_2(void)
 {
 	static utmpidlearr ut;
-	struct utmp usr;
+	struct utmpx *usr;
 	int nusers = 0;
 
-	bzero((char *)&ut, sizeof(ut));
+	memset(&ut, 0, sizeof(ut));
 	ut.utmpidlearr_val = &utmp_idle[0];
 
-	ufp = fopen(_PATH_UTMP, "r");
-	if (!ufp) {
-		syslog(LOG_ERR, "%m");
-		return(&ut);
+	setutxent();
+	while ((usr = getutxent()) != NULL && nusers < MAXUSERS) {
+		if (usr->ut_type != USER_PROCESS)
+			continue;
+
+		memcpy(&utmp_list[nusers], usr, sizeof(*usr));
+		utmp_idle[nusers].ui_utmp.ut_time = usr->ut_tv.tv_sec;
+		utmp_idle[nusers].ui_idle =
+		    getidle(usr->ut_line, usr->ut_host);
+		utmp_idle[nusers].ui_utmp.ut_line =
+		    utmp_list[nusers].ut_line;
+		utmp_idle[nusers].ui_utmp.ut_name =
+		    utmp_list[nusers].ut_user;
+		utmp_idle[nusers].ui_utmp.ut_host =
+		    utmp_list[nusers].ut_host;
+
+		nusers++;
 	}
-
-	/* only entries with both name and line fields */
-	while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1 &&
-	       nusers < MAXUSERS)
-		if (*usr.ut_name && *usr.ut_line &&
-		    strncmp(usr.ut_name, IGNOREUSER,
-			    sizeof(usr.ut_name))
-#ifdef OSF
-		    && usr.ut_type == USER_PROCESS
-#endif
-		    ) {
-			utmp_idle[nusers].ui_utmp.ut_time =
-				usr.ut_time;
-			utmp_idle[nusers].ui_idle =
-				getidle(usr.ut_line, usr.ut_host);
-			utmp_idle[nusers].ui_utmp.ut_line = line[nusers];
-			strncpy(line[nusers], usr.ut_line, UT_LINESIZE);
-			utmp_idle[nusers].ui_utmp.ut_name = name[nusers];
-			strncpy(name[nusers], usr.ut_name, UT_NAMESIZE);
-			utmp_idle[nusers].ui_utmp.ut_host = host[nusers];
-			strncpy(host[nusers], usr.ut_host, UT_HOSTSIZE);
-
-			/* Make sure entries are NUL terminated */
-			line[nusers][UT_LINESIZE] =
-			name[nusers][UT_NAMESIZE] =
-			host[nusers][UT_HOSTSIZE] = '\0';
-			nusers++;
-		}
+	endutxent();
 
 	ut.utmpidlearr_len = nusers;
-	fclose(ufp);
 	return(&ut);
 }
 
-int *
-rusers_num(void)
+static int *
+rusers_num(void *argp __unused, struct svc_req *rqstp __unused)
 {
 	static int num_users = 0;
-	struct utmp usr;
-
-	ufp = fopen(_PATH_UTMP, "r");
-	if (!ufp) {
-		syslog(LOG_ERR, "%m");
-		return(NULL);
+	struct utmpx *usr;
+ 
+	setutxent();
+	while ((usr = getutxent()) != NULL) {
+		if (usr->ut_type != USER_PROCESS)
+			continue;
+		num_users++;
 	}
-
-	/* only entries with both name and line fields */
-	while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
-		if (*usr.ut_name && *usr.ut_line &&
-		    strncmp(usr.ut_name, IGNOREUSER,
-			    sizeof(usr.ut_name))
-#ifdef OSF
-		    && usr.ut_type == USER_PROCESS
-#endif
-		    ) {
-			num_users++;
-		}
-
-	fclose(ufp);
+	endutxent();
+ 
 	return(&num_users);
 }
 
 static utmparr *
-do_names_1(int all)
+do_names_1(void)
 {
 	utmpidlearr *utidle;
 	static utmparr ut;
-	int i;
+	unsigned int i;
 
 	bzero((char *)&ut, sizeof(ut));
 
-	utidle = do_names_2(all);
+	utidle = do_names_2();
 	if (utidle) {
 		ut.utmparr_len = utidle->utmpidlearr_len;
 		ut.utmparr_val = &old_utmp[0];
@@ -281,29 +223,31 @@ do_names_1(int all)
 }
 
 utmpidlearr *
-rusersproc_names_2_svc(void *argp, struct svc_req *rqstp)
+rusersproc_names_2_svc(void *argp __unused, struct svc_req *rqstp __unused)
 {
-	return(do_names_2(0));
+	return (do_names_2());
 }
 
 utmpidlearr *
-rusersproc_allnames_2_svc(void *argp, struct svc_req *rqstp)
+rusersproc_allnames_2_svc(void *argp __unused, struct svc_req *rqstp __unused)
 {
-	return(do_names_2(1));
+	return (do_names_2());
 }
 
 utmparr *
-rusersproc_names_1_svc(void *argp, struct svc_req *rqstp)
+rusersproc_names_1_svc(void *argp __unused, struct svc_req *rqstp __unused)
 {
-	return(do_names_1(0));
+	return (do_names_1());
 }
 
 utmparr *
-rusersproc_allnames_1_svc(void *argp, struct svc_req *rqstp)
+rusersproc_allnames_1_svc(void *argp __unused, struct svc_req *rqstp __unused)
 {
-	return(do_names_1(1));
+	return (do_names_1());
 }
 
+typedef void *(*rusersproc_t)(void *, struct svc_req *);
+
 void
 rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 {
@@ -311,8 +255,8 @@ rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 		int fill;
 	} argument;
 	char *result;
-	bool_t (*xdr_argument)(), (*xdr_result)();
-	char *(*local)();
+	xdrproc_t xdr_argument, xdr_result;
+	rusersproc_t local;
 
 	switch (rqstp->rq_proc) {
 	case NULLPROC:
@@ -320,20 +264,20 @@ rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 		goto leave;
 
 	case RUSERSPROC_NUM:
-		xdr_argument = xdr_void;
-		xdr_result = xdr_int;
-		local = (char *(*)()) rusers_num;
+		xdr_argument = (xdrproc_t)xdr_void;
+		xdr_result = (xdrproc_t)xdr_int;
+		local = (rusersproc_t)rusers_num;
 		break;
 
 	case RUSERSPROC_NAMES:
-		xdr_argument = xdr_void;
-		xdr_result = xdr_utmpidlearr;
+		xdr_argument = (xdrproc_t)xdr_void;
+		xdr_result = (xdrproc_t)xdr_utmpidlearr;
 		switch (rqstp->rq_vers) {
 		case RUSERSVERS_ORIG:
-			local = (char *(*)()) rusersproc_names_1_svc;
+			local = (rusersproc_t)rusersproc_names_1_svc;
 			break;
 		case RUSERSVERS_IDLE:
-			local = (char *(*)()) rusersproc_names_2_svc;
+			local = (rusersproc_t)rusersproc_names_2_svc;
 			break;
 		default:
 			svcerr_progvers(transp, RUSERSVERS_ORIG, RUSERSVERS_IDLE);
@@ -343,14 +287,14 @@ rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 		break;
 
 	case RUSERSPROC_ALLNAMES:
-		xdr_argument = xdr_void;
-		xdr_result = xdr_utmpidlearr;
+		xdr_argument = (xdrproc_t)xdr_void;
+		xdr_result = (xdrproc_t)xdr_utmpidlearr;
 		switch (rqstp->rq_vers) {
 		case RUSERSVERS_ORIG:
-			local = (char *(*)()) rusersproc_allnames_1_svc;
+			local = (rusersproc_t)rusersproc_allnames_1_svc;
 			break;
 		case RUSERSVERS_IDLE:
-			local = (char *(*)()) rusersproc_allnames_2_svc;
+			local = (rusersproc_t)rusersproc_allnames_2_svc;
 			break;
 		default:
 			svcerr_progvers(transp, RUSERSVERS_ORIG, RUSERSVERS_IDLE);
@@ -363,8 +307,8 @@ rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 		svcerr_noproc(transp);
 		goto leave;
 	}
-	bzero((char *)&argument, sizeof(argument));
-	if (!svc_getargs(transp, (xdrproc_t)xdr_argument, (caddr_t)&argument)) {
+	bzero(&argument, sizeof(argument));
+	if (!svc_getargs(transp, (xdrproc_t)xdr_argument, &argument)) {
 		svcerr_decode(transp);
 		goto leave;
 	}
@@ -373,7 +317,7 @@ rusers_service(struct svc_req *rqstp, SVCXPRT *transp)
 	    !svc_sendreply(transp, (xdrproc_t)xdr_result, result)) {
 		svcerr_systemerr(transp);
 	}
-	if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (caddr_t)&argument)) {
+	if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, &argument)) {
 		syslog(LOG_ERR, "unable to free arguments");
 		exit(1);
 	}
diff --git a/libexec/rpc.rusersd/rusersd.c b/libexec/rpc.rusersd/rusersd.c
index 14a6c3a3e4..ad5d3d7d8e 100644
--- a/libexec/rpc.rusersd/rusersd.c
+++ b/libexec/rpc.rusersd/rusersd.c
@@ -1,4 +1,6 @@
 /*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
  * Copyright (c) 1993, John Brezak
  * All rights reserved.
  *
@@ -26,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/libexec/rpc.rusersd/rusersd.c,v 1.8 1999/08/28 00:09:56 peter Exp $
+ * $FreeBSD: head/libexec/rpc.rusersd/rusersd.c 326025 2017-11-20 19:49:47Z pfg $
  */
 
 #include <stdlib.h>
@@ -34,16 +36,14 @@
 #include <sys/socket.h>
 #include <signal.h>
 #include <syslog.h>
-#define utmp rutmp
 #include <rpcsvc/rnusers.h>
-#undef utmp
 
-extern void rusers_service();
+#include "extern.h"
 
 int from_inetd = 1;
 
-void __dead2
-cleanup(int sig)
+static void __dead2
+cleanup(int sig __unused)
 {
 	(void) rpcb_unset(RUSERSPROG, RUSERSVERS_IDLE, NULL);
 	(void) rpcb_unset(RUSERSPROG, RUSERSVERS_ORIG, NULL);
@@ -51,12 +51,12 @@ cleanup(int sig)
 }
 
 int
-main(int argc, char *argv[])
+main(int argc __unused, char *argv[] __unused)
 {
-	SVCXPRT *transp;
+	SVCXPRT *transp = NULL; /* Keep compiler happy. */
 	int ok;
 	struct sockaddr_storage from;
-	int fromlen;
+	socklen_t fromlen;
 
 	/*
 	 * See if inetd started us
@@ -69,8 +69,8 @@ main(int argc, char *argv[])
 	if (!from_inetd) {
 		daemon(0, 0);
 
-		(void) pmap_unset(RUSERSPROG, RUSERSVERS_IDLE);
-		(void) pmap_unset(RUSERSPROG, RUSERSVERS_ORIG);
+		(void) rpcb_unset(RUSERSPROG, RUSERSVERS_IDLE, NULL);
+		(void) rpcb_unset(RUSERSPROG, RUSERSVERS_ORIG, NULL);
 
 		(void) signal(SIGINT, cleanup);
 		(void) signal(SIGTERM, cleanup);
@@ -86,25 +86,25 @@ main(int argc, char *argv[])
 			exit(1);
 		}
 		ok = svc_reg(transp, RUSERSPROG, RUSERSVERS_IDLE,
-		    rusers_service, NULL);
+			     rusers_service, NULL);
 	} else
 		ok = svc_create(rusers_service,
-		    RUSERSPROG, RUSERSVERS_IDLE, "udp");
+				RUSERSPROG, RUSERSVERS_IDLE, "udp");
 	if (!ok) {
 		syslog(LOG_ERR, "unable to register (RUSERSPROG, RUSERSVERS_IDLE, %s)", (!from_inetd)?"udp":"(inetd)");
 		exit(1);
 	}
-
 	if (from_inetd)
 		ok = svc_reg(transp, RUSERSPROG, RUSERSVERS_ORIG,
-		    rusers_service, NULL);
+			     rusers_service, NULL);
 	else
 		ok = svc_create(rusers_service,
-		    RUSERSPROG, RUSERSVERS_ORIG, "udp");
+				RUSERSPROG, RUSERSVERS_ORIG, "udp");
 	if (!ok) {
 		syslog(LOG_ERR, "unable to register (RUSERSPROG, RUSERSVERS_ORIG, %s)", (!from_inetd)?"udp":"(inetd)");
 		exit(1);
 	}
+
 	svc_run();
 	syslog(LOG_ERR, "svc_run returned");
 	exit(1);
diff --git a/libexec/talkd/Makefile b/libexec/talkd/Makefile
index 501d1d31f7..91b8a1ea79 100644
--- a/libexec/talkd/Makefile
+++ b/libexec/talkd/Makefile
@@ -11,6 +11,6 @@ DPADD=	${LIBUTIL}
 LDADD=	-lutil
 
 CFLAGS+=-I${.CURDIR}/../../usr.bin/wall
-CFLAGS+=-I${.CURDIR}/../../usr.bin/who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+=-I${.CURDIR}/../../usr.bin/who
 
 .include <bsd.prog.mk>
diff --git a/libexec/telnetd/Makefile b/libexec/telnetd/Makefile
index 6ed20a6259..5c1c0cdc99 100644
--- a/libexec/telnetd/Makefile
+++ b/libexec/telnetd/Makefile
@@ -11,8 +11,7 @@ SRCS=		authenc.c global.c slc.c state.c sys_term.c telnetd.c \
 
 WARNS?=		2
 
-CFLAGS+=	-DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS
-CFLAGS+=	-DOLD_ENVIRON -DENV_HACK -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+=	-DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON -DENV_HACK
 CFLAGS+=	-I${.CURDIR}/../../lib
 
 .if !defined(NO_INET6)
diff --git a/libexec/telnetd/sys_term.c b/libexec/telnetd/sys_term.c
index 71dac32fec..ae20362402 100644
--- a/libexec/telnetd/sys_term.c
+++ b/libexec/telnetd/sys_term.c
@@ -34,9 +34,7 @@
 #include <sys/tty.h>
 #include <libutil.h>
 #include <stdlib.h>
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 
 #include "telnetd.h"
 #include "pathnames.h"
@@ -1323,14 +1321,8 @@ cleanup(int sig __unused)
 	 */
 	sigfillset(&mask);
 	sigprocmask(SIG_SETMASK, &mask, NULL);
-#ifdef SUPPORT_UTMP
-	if (logout(p))
-		logwtmp(p, "", "");
-#endif
-#ifdef SUPPORT_UTMPX
 	if (logoutx(p, 0, DEAD_PROCESS))
 		logwtmpx(p, "", "", 0, DEAD_PROCESS);
-#endif
 	(void)chmod(line, 0666);
 	(void)chown(line, 0, 0);
 	*p = 'p';
diff --git a/libexec/telnetd/telnetd.8 b/libexec/telnetd/telnetd.8
index 3595e60899..64f2742017 100644
--- a/libexec/telnetd/telnetd.8
+++ b/libexec/telnetd/telnetd.8
@@ -28,7 +28,7 @@
 .\"	@(#)telnetd.8	8.4 (Berkeley) 6/1/94
 .\" $FreeBSD: src/crypto/telnet/telnetd/telnetd.8,v 1.5.2.6 2002/04/13 10:59:09 markm Exp $
 .\"
-.Dd July 27, 2009
+.Dd September 1, 2019
 .Dt TELNETD 8
 .Os
 .Sh NAME
@@ -244,21 +244,7 @@ The alternate command must
 understand the same command arguments as the standard login.
 .It Fl S Ar tos
 .It Fl u Ar len
-This option is used to specify the size of the field
-in the
-.Dv utmp
-structure that holds the remote host name.
-If the resolved host name is longer than
-.Ar len ,
-the dotted decimal value will be used instead.
-This allows hosts with very long host names that
-overflow this field to still be uniquely identified.
-Specifying
-.Fl u0
-indicates that only dotted decimal addresses
-should be put into the
-.Pa utmp
-file.
+This option is provided for backward compatibility and has no effect.
 .It Fl U
 This option causes
 .Nm
diff --git a/libexec/telnetd/telnetd.c b/libexec/telnetd/telnetd.c
index 44cf1a1385..5c2f1856bb 100644
--- a/libexec/telnetd/telnetd.c
+++ b/libexec/telnetd/telnetd.c
@@ -38,9 +38,6 @@
 #include <libutil.h>
 #include <paths.h>
 #include <termcap.h>
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-#endif
 
 #include <arpa/inet.h>
 
@@ -54,9 +51,6 @@ int	auth_level = 0;
 #include <libtelnet/misc.h>
 
 char	remote_hostname[MAXHOSTNAMELEN];
-#ifdef SUPPORT_UTMP
-size_t	utmp_len = sizeof(remote_hostname) - 1;
-#endif
 int	registerd_host_only = 0;
 
 
@@ -271,13 +265,7 @@ main(int argc, char *argv[])
 			break;
 
 		case 'u':
-#ifdef SUPPORT_UTMP
-			utmp_len = (size_t)atoi(optarg);
-			if (utmp_len >= sizeof(remote_hostname))
-				utmp_len = sizeof(remote_hostname) - 1;
-#else
 			fprintf(stderr, "telnetd: -u option unneeded\n");
-#endif
 			break;
 
 		case 'U':
@@ -641,9 +629,6 @@ terminaltypeok(char *s)
 void
 doit(struct sockaddr *who)
 {
-#ifdef SUPPORT_UTMP
-	int err_; /* XXX */
-#endif
 	int ptynum;
 
 	/*
@@ -675,15 +660,6 @@ doit(struct sockaddr *who)
 	Please contact your net administrator");
 	remote_hostname[sizeof(remote_hostname) - 1] = '\0';
 
-#ifdef SUPPORT_UTMP
-	trimdomain(remote_hostname, UT_HOSTSIZE);
-	if (!isdigit(remote_hostname[0]) && strlen(remote_hostname) > utmp_len)
-		err_ = getnameinfo(who, who->sa_len, remote_hostname,
-				  sizeof(remote_hostname), NULL, 0,
-				  NI_NUMERICHOST|NI_WITHSCOPEID);
-		/* XXX: do 'err_' check */
-#endif
-
 	(void) gethostname(host_name, sizeof(host_name) - 1);
 	host_name[sizeof(host_name) - 1] = '\0';
 	hostname = host_name;
diff --git a/sbin/init/Makefile b/sbin/init/Makefile
index bfc244fa29..279397b4ed 100644
--- a/sbin/init/Makefile
+++ b/sbin/init/Makefile
@@ -10,7 +10,6 @@ INSTALLFLAGS= -b -B.bak
 INSTALLFLAGS+= -fschg
 .endif
 CFLAGS+=-DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT
-CFLAGS+=-DSUPPORT_UTMP -DSUPPORT_UTMPX
 DPADD=	${LIBUTIL} ${LIBCRYPT} ${LIBCRYPTO}
 LDADD=	-lutil -lcrypt -lprivate_crypto
 LDFLAGS+=	${PRIVATELIB_LDFLAGS}
diff --git a/sbin/init/init.c b/sbin/init/init.c
index 79b85346a2..e8f84d9d9d 100644
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -196,7 +196,6 @@ static void	add_session(session_t *);
 static void	del_session(session_t *);
 static session_t *find_session(pid_t);
 
-#ifdef SUPPORT_UTMPX
 static struct timeval boot_time;
 state_t current_state = death;
 static void session_utmpx(const session_t *, int);
@@ -204,7 +203,6 @@ static void make_utmpx(const char *, const char *, int, pid_t,
     const struct timeval *, int);
 static char get_runlevel(const state_t);
 static void utmpx_set_runlevel(char, char);
-#endif
 
 static int Reboot = FALSE;
 static int howto = RB_AUTOBOOT;
@@ -225,9 +223,7 @@ main(int argc, char *argv[])
 	sigset_t mask;
 	struct stat sts;
 
-#ifdef SUPPORT_UTMPX
 	(void)gettimeofday(&boot_time, NULL);
-#endif /* SUPPORT_UTMPX */
 
 	/* Dispose of random users. */
 	if (getuid() != 0)
@@ -595,11 +591,9 @@ static void
 transition(state_t s)
 {
 	for (;;) {
-#ifdef SUPPORT_UTMPX
 		utmpx_set_runlevel(get_runlevel(current_state),
 		    get_runlevel(s));
 		current_state = s;
-#endif
 		s = (*state_funcs[s])();
 	}
 }
@@ -612,14 +606,8 @@ clear_session_logs(session_t *sp, int status)
 {
 	char *line = sp->se_device + sizeof(_PATH_DEV) - 1;
 
-#ifdef SUPPORT_UTMPX
 	if (logoutx(line, status, DEAD_PROCESS))
 		 logwtmpx(line, "", "", status, DEAD_PROCESS);
-#endif
-#ifdef SUPPORT_UTMP
-	if (logout(line))
-		logwtmp(line, "", "");
-#endif
 }
 
 /*
@@ -880,12 +868,7 @@ f_runcom(void)
 		return single_user;
 
 	runcom_mode = AUTOBOOT;		/* the default */
-#ifdef SUPPORT_UTMPX
 	logwtmpx("~", "reboot", "", 0, INIT_PROCESS);
-#endif
-#ifdef SUPPORT_UTMP
-	logwtmp("~", "reboot", "");
-#endif
 	return read_ttys;
 }
 
@@ -923,9 +906,7 @@ add_session(session_t *sp)
 
 	if ((*session_db->put)(session_db, &key, &data, 0))
 		emergency("insert %d: %s", sp->se_process, strerror(errno));
-#ifdef SUPPORT_UTMPX
 	session_utmpx(sp, 1);
-#endif
 }
 
 /*
@@ -941,9 +922,7 @@ del_session(session_t *sp)
 
 	if ((*session_db->del)(session_db, &key, 0))
 		emergency("delete %d: %s", sp->se_process, strerror(errno));
-#ifdef SUPPORT_UTMPX
 	session_utmpx(sp, 0);
-#endif
 }
 
 /*
@@ -1145,7 +1124,6 @@ f_read_ttys(void)
 	session_t *sp, *snext;
 	struct ttyent *typ;
 
-#ifdef SUPPORT_UTMPX
 	if (sessions == NULL) {
 		struct stat st;
 
@@ -1163,7 +1141,6 @@ f_read_ttys(void)
 			make_utmpx("", DOWN_MSG, DOWN_TIME, 0, &down_time, 0);
 		}
 	}
-#endif
 	/*
 	 * Destroy any previous session state.
 	 * There shouldn't be any, but just in case...
@@ -1549,12 +1526,7 @@ f_death(void)
 	int status;
 	static const int death_sigs[2] = { SIGTERM, SIGKILL };
 
-#ifdef SUPPORT_UTMPX
 	logwtmpx("~", "shutdown", "", 0, INIT_PROCESS);
-#endif
-#ifdef SUPPORT_UTMP
-	logwtmp("~", "shutdown", "");
-#endif
 
 	for (sp = sessions; sp; sp = sp->se_next) {
 		sp->se_flags |= SE_SHUTDOWN;
@@ -1779,7 +1751,6 @@ setprocresources(const char *cname)
 }
 #endif
 
-#ifdef SUPPORT_UTMPX
 static void
 session_utmpx(const session_t *sp, int add)
 {
@@ -1860,4 +1831,3 @@ utmpx_set_runlevel(char old, char new)
 		warning("can't add utmpx record for `runlevel': %m");
 	endutxent();
 }
-#endif
diff --git a/sbin/reboot/Makefile b/sbin/reboot/Makefile
index 30aa22917f..0a996d2ee9 100644
--- a/sbin/reboot/Makefile
+++ b/sbin/reboot/Makefile
@@ -4,7 +4,6 @@
 PROG=	reboot
 DPADD=	${LIBUTIL}
 LDADD=	-lutil
-CFLAGS+=-DSUPPORT_UTMP -DSUPPORT_UTMPX
 MAN=	reboot.8
 MLINKS=	reboot.8 halt.8 reboot.8 fastboot.8 reboot.8 fasthalt.8
 
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index 0d631d0878..e86ff28dfa 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -45,9 +45,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 
 void usage(void) __dead2;
 u_int get_pageins(void);
@@ -134,12 +132,7 @@ main(int argc, char *argv[])
 			syslog(LOG_CRIT, "rebooted by %s", user);
 		}
 	}
-#ifdef SUPPORT_UTMP
-	logwtmp("~", "shutdown", "");
-#endif
-#ifdef SUPPORT_UTMPX
 	logwtmpx("~", "shutdown", "", 0, INIT_PROCESS);
-#endif
 
 	/*
 	 * Do a sync early on, so disks start transfers while we're off
diff --git a/share/man/man5/Makefile b/share/man/man5/Makefile
index 845396976d..9f3fa80215 100644
--- a/share/man/man5/Makefile
+++ b/share/man/man5/Makefile
@@ -54,7 +54,6 @@ MAN=	acct.5 \
 	sysctl.conf.5 \
 	tmpfs.5 \
 	autofs.5 \
-	utmp.5 \
 	utmpx.5 \
 	uuids.5 \
 	varsym.conf.5
@@ -72,8 +71,6 @@ MLINKS+=null.5 nullfs.5
 MLINKS+=hosts.equiv.5 rhosts.5
 MLINKS+=passwd.5 master.passwd.5
 MLINKS+=resolver.5 resolv.conf.5
-MLINKS+=utmp.5 lastlog.5 \
-	utmp.5 wtmp.5
 MLINKS+=utmpx.5 lastlogx.5 \
 	utmpx.5 wtmpx.5
 
diff --git a/share/man/man5/utmp.5 b/share/man/man5/utmp.5
deleted file mode 100644
index 4ce24614a1..0000000000
--- a/share/man/man5/utmp.5
+++ /dev/null
@@ -1,267 +0,0 @@
-.\" Copyright (c) 1980, 1991, 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.
-.\"
-.\"     @(#)utmp.5	8.2 (Berkeley) 3/17/94
-.\" $FreeBSD: src/share/man/man5/utmp.5,v 1.9.2.8 2001/12/17 11:30:15 ru Exp $
-.\" $DragonFly: src/share/man/man5/utmp.5,v 1.3 2006/05/26 19:39:40 swildner Exp $
-.\"
-.Dd November 14, 2001
-.Dt UTMP 5
-.Os
-.Sh NAME
-.Nm utmp ,
-.Nm wtmp ,
-.Nm lastlog
-.Nd login records
-.Sh SYNOPSIS
-.In sys/types.h
-.In utmp.h
-.Sh DESCRIPTION
-The file
-.In utmp.h
-declares the structures used to record information about current
-users in the file
-.Nm ,
-logins and logouts in the file
-.Nm wtmp ,
-and last logins in the file
-.Nm lastlog .
-The time stamps of date changes, shutdowns and reboots are also logged in
-the
-.Nm wtmp
-file.
-.Bd -literal -offset indent
-#define _PATH_UTMP      "/var/run/utmp"
-#define _PATH_WTMP      "/var/log/wtmp"
-#define _PATH_LASTLOG   "/var/log/lastlog"
-
-#define UT_NAMESIZE     16
-#define UT_LINESIZE     8
-#define UT_HOSTSIZE     16
-
-struct lastlog {
-        time_t  ll_time;		/* When user logged in */
-        char    ll_line[UT_LINESIZE];	/* Terminal line name */
-        char    ll_host[UT_HOSTSIZE];	/* Host user came from */
-};
-
-struct utmp {
-        char    ut_line[UT_LINESIZE];	/* Terminal line name */
-        char    ut_name[UT_NAMESIZE];	/* User's login name */
-        char    ut_host[UT_HOSTSIZE];	/* Host user came from */
-        time_t  ut_time;		/* When user logged in */
-};
-.Ed
-.Pp
-The
-.Nm lastlog
-file is a linear array of
-.Vt lastlog
-structures indexed by a user's
-.Tn UID .
-The
-.Nm
-file is a linear array of
-.Vt utmp
-structures indexed by a terminal line number
-(see
-.Xr ttyslot 3 ) .
-The
-.Nm wtmp
-file consists of
-.Vt utmp
-structures and is a binary log file,
-that is, grows linearly at its end.
-.Pp
-Each time a user logs in, the
-.Xr login 1
-program looks up the user's
-.Tn UID
-in the file
-.Nm lastlog .
-If it is found, the timestamp of the last time the user logged
-in, the terminal line and the hostname
-are written to the standard output (unless the login is
-.Em quiet ,
-see
-.Xr login 1 ) .
-The
-.Xr login 1
-program then records the new login time in the file
-.Nm lastlog .
-.Pp
-After the new
-.Vt lastlog
-record is written,
-.\" the
-.\" .Xr libutil 3
-.\" routine
-the file
-.Nm
-is opened and the
-.Vt utmp
-record for the user is inserted.
-This record remains there until
-the user logs out at which time it is deleted.
-The
-.Nm
-file is used by the programs
-.Xr rwho 1 ,
-.Xr users 1 ,
-.Xr w 1 ,
-and
-.Xr who 1 .
-.Pp
-Next, the
-.Xr login 1
-program opens the file
-.Nm wtmp ,
-and appends the user's
-.Vt utmp
-record.
-The user's subsequent logout from the terminal
-line is marked by a special
-.Vt utmp
-record with
-.Va ut_line
-set accordingly,
-.Va ut_time
-updated, but
-.Va ut_name
-and
-.Va ut_host
-both empty
-(see
-.Xr init 8 ) .
-The
-.Nm wtmp
-file is used by the programs
-.Xr last 1
-and
-.Xr ac 8 .
-.Pp
-In the event of a date change, a shutdown or reboot, the
-following items are logged in the
-.Nm wtmp
-file.
-.Pp
-.Bl -tag -width ".Li shutdown" -compact
-.It Li reboot
-.It Li shutdown
-A system reboot or shutdown has been initiated.
-The character
-.Ql \&~
-is placed in the field
-.Va ut_line ,
-and
-.Li reboot
-or
-.Li shutdown
-in the field
-.Va ut_name
-(see
-.Xr shutdown 8
-and
-.Xr reboot 8 ) .
-.Pp
-.It Li date
-The system time has been manually or automatically updated
-(see
-.Xr date 1 ) .
-The command name
-.Li date
-is recorded in the field
-.Va ut_name .
-In the field
-.Va ut_line ,
-the character
-.Ql \&|
-indicates the time prior to the change, and the character
-.Ql \&{
-indicates the new time.
-.El
-.Sh NOTES
-The
-.Nm wtmp
-file can grow rapidly on busy systems, so daily or weekly rotation
-is recommended.
-It is maintained by
-.Xr newsyslog 8 .
-.Pp
-If any one of these files does not exist, it is not created by
-.Xr login 1 .
-They must be created manually.
-.Pp
-The supplied
-.Xr login 3 ,
-.Xr logout 3 ,
-and
-.Xr logwtmp 3
-utility functions should be used to perform
-the standard actions on the
-.Nm
-and
-.Nm wtmp
-files in order to maintain the portability across
-systems with different formats of those files.
-.Sh FILES
-.Bl -tag -width ".Pa /var/log/lastlog" -compact
-.It Pa /var/run/utmp
-The
-.Nm
-file.
-.It Pa /var/log/wtmp
-The
-.Nm wtmp
-file.
-.It Pa /var/log/lastlog
-The
-.Nm lastlog
-file.
-.El
-.Sh SEE ALSO
-.Xr last 1 ,
-.Xr login 1 ,
-.Xr w 1 ,
-.Xr who 1 ,
-.Xr login 3 ,
-.Xr logout 3 ,
-.Xr logwtmp 3 ,
-.Xr ttyslot 3 ,
-.Xr ac 8 ,
-.Xr init 8
-.Sh HISTORY
-A
-.Nm
-and
-.Nm wtmp
-file format appeared in
-.At v6 .
-The
-.Nm lastlog
-file format appeared in
-.Bx 3.0 .
diff --git a/share/man/man5/utmpx.5 b/share/man/man5/utmpx.5
index 7a4aa7cb99..9cb943c612 100644
--- a/share/man/man5/utmpx.5
+++ b/share/man/man5/utmpx.5
@@ -130,6 +130,7 @@ file.
 .Xr rwho 1 ,
 .Xr w 1 ,
 .Xr who 1 ,
+.Xr wtmpxcvt 1 ,
 .Xr endutxent 3 ,
 .Xr logwtmpx 3 ,
 .Xr utmp 5 ,
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 22699637ee..f38a584e7f 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -207,9 +207,10 @@
  * 500702 - TCP_KEEP* milliseconds -> seconds
  * 500703 - Static TLS bindings support for late-loaded shared libraries
  * 500704 - Announce IP6 address flag changes via route(4)
+ * 500705 - Move us to utmpx, delete utmp
  */
 #undef __DragonFly_version
-#define __DragonFly_version 500704	/* propagated to newvers */
+#define __DragonFly_version 500705	/* propagated to newvers */
 
 #include <sys/_null.h>
 
@@ -222,13 +223,12 @@
  * Redefined constants are from POSIX 1003.1 limits file.
  *
  * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>)
- * MAXLOGNAME should be == UT_NAMESIZE+1 (see <utmp.h>)
  */
 #include <sys/syslimits.h>
 
 #define MAXCOMLEN	16		/* max command name remembered */
 #define MAXINTERP	32		/* max interpreter file name length */
-#define MAXLOGNAME	17		/* max login name length (incl. NUL) */
+#define MAXLOGNAME	33		/* max login name length (incl. NUL) */
 #define MAXUPRC		CHILD_MAX	/* max simultaneous processes */
 #define NCARGS		ARG_MAX		/* max bytes for an exec function */
 #define NGROUPS		NGROUPS_MAX	/* max number groups */
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 85a3597050..d009d71604 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -238,6 +238,7 @@ SUBDIR=	alias \
 	window \
 	wmake \
 	write \
+	wtmpcvt \
 	xargs \
 	xinstall \
 	xstr \
diff --git a/usr.bin/finger/Makefile b/usr.bin/finger/Makefile
index 5ad7fed9e2..c1bd7c4da9 100644
--- a/usr.bin/finger/Makefile
+++ b/usr.bin/finger/Makefile
@@ -10,6 +10,6 @@ MAN=	finger.1 finger.conf.5
 DPADD+=	${LIBUTIL}
 LDADD+=	-lutil
 
-CFLAGS+= -I${.CURDIR}/../who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+= -I${.CURDIR}/../who
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/finger/lprint.c b/usr.bin/finger/lprint.c
index 933f6ed4c1..abec08f9ff 100644
--- a/usr.bin/finger/lprint.c
+++ b/usr.bin/finger/lprint.c
@@ -31,7 +31,6 @@
  *
  * @(#)lprint.c	8.3 (Berkeley) 4/28/95
  * $FreeBSD: src/usr.bin/finger/lprint.c,v 1.10.2.4 2002/07/03 01:14:24 des Exp $
- * $DragonFly: src/usr.bin/finger/lprint.c,v 1.4 2004/09/03 19:13:23 dillon Exp $
  */
 
 #include <sys/types.h>
@@ -48,7 +47,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <utmp.h>
 #include "finger.h"
 #include "pathnames.h"
 #include "extern.h"
diff --git a/usr.bin/finger/net.c b/usr.bin/finger/net.c
index 514160300c..21ccb55c1a 100644
--- a/usr.bin/finger/net.c
+++ b/usr.bin/finger/net.c
@@ -45,7 +45,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <utmp.h>
 #include "finger.h"
 
 static void cleanup(int sig);
diff --git a/usr.bin/finger/sprint.c b/usr.bin/finger/sprint.c
index e8620bc58c..7e1eaa9e31 100644
--- a/usr.bin/finger/sprint.c
+++ b/usr.bin/finger/sprint.c
@@ -31,9 +31,9 @@
  *
  * @(#)sprint.c	8.3 (Berkeley) 4/28/95
  * $FreeBSD: src/usr.bin/finger/sprint.c,v 1.11.2.5 2002/07/03 01:14:24 des Exp $
- * $DragonFly: src/usr.bin/finger/sprint.c,v 1.4 2008/02/09 17:12:05 matthias Exp $
  */
 
+#include <sys/param.h>
 #include <sys/socket.h>
 #include <db.h>
 #include <err.h>
@@ -42,7 +42,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
-#include <utmp.h>
 #include "finger.h"
 
 static void	  stimeprint(WHERE *);
@@ -78,7 +77,7 @@ sflag_print(void)
 	 */
 #define	MAXREALNAME	20
 #define MAXHOSTNAME     17      /* in reality, hosts are never longer than 16 */
-	(void)printf("%-*s %-*s%s  %s\n", UT_NAMESIZE, "Login", MAXREALNAME,
+	(void)printf("%-*s %-*s%s  %s\n", MAXLOGNAME, "Login", MAXREALNAME,
 	    "Name", " TTY  Idle  Login  Time ", (gflag) ? "" :
 	    oflag ? "Office  Phone" : "Where");
 
@@ -95,7 +94,7 @@ sflag_print(void)
 			namelen = MAXREALNAME;
 			if (w->info == LOGGEDIN && !w->writable)
 				--namelen;	/* leave space before `*' */
-			(void)printf("%-*.*s %-*.*s", UT_NAMESIZE, UT_NAMESIZE,
+			(void)printf("%-*.*s %-*.*s", MAXLOGNAME, MAXLOGNAME,
 				pn->name, MAXREALNAME, namelen,
 				pn->realname ? pn->realname : "");
 			if (!w->loginat) {
diff --git a/usr.bin/finger/util.c b/usr.bin/finger/util.c
index b45bd3afe9..49fd69cb77 100644
--- a/usr.bin/finger/util.c
+++ b/usr.bin/finger/util.c
@@ -31,7 +31,6 @@
  *
  * @(#)util.c	8.3 (Berkeley) 4/28/95
  * $FreeBSD: src/usr.bin/finger/util.c,v 1.8.2.6 2002/07/03 01:14:24 des Exp $
- * $DragonFly: src/usr.bin/finger/util.c,v 1.3 2003/10/04 20:36:44 hmp Exp $
  */
 
 #include <sys/param.h>
@@ -49,7 +48,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "utmpentry.h"
-#include <utmp.h>
+#include <utmpx.h>
 #include "finger.h"
 #include "pathnames.h"
 
@@ -101,29 +100,18 @@ void
 enter_lastlog(PERSON *pn)
 {
 	WHERE *w;
-	static int opened, fd;
-	struct lastlog ll;
+	struct utmpx *ut = NULL;
 	char doit = 0;
 
-	/* some systems may not maintain lastlog, don't report errors. */
-	if (!opened) {
-		fd = open(_PATH_LASTLOG, O_RDONLY, 0);
-		opened = 1;
-	}
-	if (fd == -1 ||
-	    lseek(fd, (long)pn->uid * sizeof(ll), SEEK_SET) !=
-	    (off_t)((long)pn->uid * sizeof(ll)) ||
-	    read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) {
-			/* as if never logged in */
-			ll.ll_line[0] = ll.ll_host[0] = '\0';
-			ll.ll_time = 0;
-		}
+	if (setutxdb(UTX_DB_LASTLOGX, NULL) == 0)
+		ut = getutxuser(pn->name);
 	if ((w = pn->whead) == NULL)
 		doit = 1;
-	else if (ll.ll_time != 0) {
+	else if (ut != NULL && ut->ut_type == USER_PROCESS) {
 		/* if last login is earlier than some current login */
 		for (; !doit && w != NULL; w = w->next)
-			if (w->info == LOGGEDIN && w->loginat < ll.ll_time)
+			if (w->info == LOGGEDIN &&
+			    w->loginat < ut->ut_tv.tv_sec)
 				doit = 1;
 		/*
 		 * and if it's not any of the current logins
@@ -132,16 +120,17 @@ enter_lastlog(PERSON *pn)
 		 */
 		for (w = pn->whead; doit && w != NULL; w = w->next)
 			if (w->info == LOGGEDIN &&
-			    strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
+			    strcmp(w->tty, ut->ut_line) == 0)
 				doit = 0;
 	}
-	if (doit) {
+	if (ut != NULL && doit) {
 		w = walloc(pn);
 		w->info = LASTLOG;
-		asprintf(&w->tty, "%s", ll.ll_line);
-		asprintf(&w->host, "%s", ll.ll_host);
-		w->loginat = ll.ll_time;
+		strcpy(w->tty, ut->ut_line);
+		strcpy(w->host, ut->ut_host);
+		w->loginat = ut->ut_tv.tv_sec;
 	}
+	endutxent();
 }
 
 void
@@ -197,10 +186,8 @@ find_person(char *name)
 {
 	struct passwd *pw;
 
-	int cnt;
 	DBT data, key;
 	PERSON *p;
-	char buf[UT_NAMESIZE + 1];
 
 	if (!db)
 		return(NULL);
@@ -208,12 +195,8 @@ find_person(char *name)
 	if ((pw = getpwnam(name)) && hide(pw))
 		return(NULL);
 
-	/* Name may be only UT_NAMESIZE long and not NUL terminated. */
-	for (cnt = 0; cnt < UT_NAMESIZE && *name; ++name, ++cnt)
-		buf[cnt] = *name;
-	buf[cnt] = '\0';
-	key.data = buf;
-	key.size = cnt;
+	key.data = name;
+	key.size = strlen(name);
 
 	if ((*db->get)(db, &key, &data, 0))
 		return (NULL);
diff --git a/usr.bin/last/Makefile b/usr.bin/last/Makefile
index 4e251316e1..df0c972808 100644
--- a/usr.bin/last/Makefile
+++ b/usr.bin/last/Makefile
@@ -3,6 +3,6 @@
 
 PROG=	last
 
-CFLAGS+=-DSUPPORT_UTMP -DSUPPORT_UTMPX -I${.CURDIR}/../../lib/libc/stdtime
+CFLAGS+=-I${.CURDIR}/../../lib/libc/stdtime
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/last/last.c b/usr.bin/last/last.c
index 4a171d6e84..24dfd241f6 100644
--- a/usr.bin/last/last.c
+++ b/usr.bin/last/last.c
@@ -43,12 +43,7 @@
 #include <time.h>
 #include <tzfile.h>
 #include <unistd.h>
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-#endif
 
 #ifndef UT_NAMESIZE
 #define UT_NAMESIZE 8
@@ -94,6 +89,7 @@ typedef struct ttytab {
 } TTY;
 static TTY	*ttylist;		/* head of linked list */
 
+static struct utmpx *bufx;
 static time_t	currentout;		/* current logout value */
 static long	maxrec;			/* records to display */
 static int	fulltime = 0;		/* Display seconds? */
@@ -102,14 +98,11 @@ static void	 addarg(int, char *);
 static TTY	*addtty(const char *);
 static void	 hostconv(char *);
 static char	*ttyconv(char *);
-#ifdef SUPPORT_UTMPX
 static void	 wtmpx(const char *, int, int, int);
-#endif
-#ifdef SUPPORT_UTMP
-static void	 wtmp(const char *, int, int, int);
-#endif
 static char	*fmttime(time_t, int);
 static void	 usage(void);
+static void	 onintrx(int);
+static int	 wantx(struct utmpx *, int);
 
 static
 void usage(void)
@@ -195,40 +188,12 @@ main(int argc, char *argv[])
 		}
 	}
 	if (file == NULL) {
-		/* default to wtmpx */
-#ifdef SUPPORT_UTMPX
 		if (access(_PATH_WTMPX, R_OK) == 0)
 			file = _PATH_WTMPX;
-		else
-#endif
-#ifdef SUPPORT_UTMP
-		if (access(_PATH_WTMP, R_OK) == 0)
-			file = _PATH_WTMP;
-#endif
 		if (file == NULL)
-#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
-			errx(1, "Cannot access `%s' or `%s'", _PATH_WTMPX,
-			    _PATH_WTMP);
-#elif defined(SUPPORT_UTMPX)
 			errx(1, "Cannot access `%s'", _PATH_WTMPX);
-#elif defined(SUPPORT_UTMP)
-			errx(1, "Cannot access `%s'", _PATH_WTMP);
-#else
-			errx(1, "No utmp or utmpx support compiled in.");
-#endif
 	}
-#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
-	if (file[strlen(file) - 1] == 'x')
-		wtmpx(file, namesize, linesize, hostsize);
-	else
-		wtmp(file, namesize, linesize, hostsize);
-#elif defined(SUPPORT_UTMPX)
 	wtmpx(file, namesize, linesize, hostsize);
-#elif defined(SUPPORT_UTMP)
-	wtmp(file, namesize, linesize, hostsize);
-#else
-	errx(1, "No utmp or utmpx support compiled in.");
-#endif
 	exit(0);
 }
 
@@ -342,33 +307,199 @@ fmttime(time_t t, int flags)
 	return (tbuf);
 }
 
-#ifdef SUPPORT_UTMP
-#define TYPE(a)	0
-#define NAMESIZE UT_NAMESIZE
-#define LINESIZE UT_LINESIZE
-#define HOSTSIZE UT_HOSTSIZE
-#define ut_timefld ut_time
-#define FIRSTVALID 0
-#include "want.c"
-#undef TYPE
-#undef NAMESIZE
-#undef LINESIZE
-#undef HOSTSIZE
-#undef ut_timefld
-#undef FIRSTVALID
+/*
+ * wtmpx --
+ *	read through the wtmpx file
+ */
+static void
+wtmpx(const char *file, int namesz, int linesz, int hostsz)
+{
+	struct utmpx	*bp;		/* current structure */
+	TTY	*T;			/* tty list entry */
+	struct stat	stb;		/* stat of file for sz */
+	time_t	delta;			/* time difference */
+	off_t	bl;
+	int	bytes, wfd;
+	char	*ct;
+	const char *crmsg;
+	size_t  len = sizeof(*bufx) * MAXUTMP;
+
+	if ((bufx = malloc(len)) == NULL)
+		err(1, "Cannot allocate utmpx buffer");
+
+	crmsg = NULL;
+
+	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
+		err(1, "%s", file);
+	bl = (stb.st_size + len - 1) / len;
+
+	bufx[1].ut_xtime = time(NULL);
+	(void)signal(SIGINT, onintrx);
+	(void)signal(SIGQUIT, onintrx);
+
+	while (--bl >= 0) {
+		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
+		    (bytes = read(wfd, bufx, len)) == -1)
+			err(1, "%s", file);
+		for (bp = &bufx[bytes / sizeof(*bufx) - 1]; bp >= bufx; --bp) {
+			/*
+			 * if the terminal line is '~', the machine stopped.
+			 * see utmpx(5) for more info.
+			 */
+			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
+				/* everybody just logged out */
+				for (T = ttylist; T; T = T->next)
+					T->logout = -bp->ut_xtime;
+				currentout = -bp->ut_xtime;
+#ifdef __DragonFly__	/* XXX swildner: this should not be needed afaict */
+				if (!strncmp(bp->ut_name, "shutdown", namesz))
+					crmsg = "shutdown";
+				else if (!strncmp(bp->ut_name, "reboot", namesz))
+					crmsg = "reboot";
+				else
+					crmsg = "crash";
+#else
+				crmsg = strncmp(bp->ut_name, "shutdown",
+				    namesz) ? "crash" : "shutdown";
 #endif
+				if (wantx(bp, NO)) {
+					ct = fmttime(bp->ut_xtime, fulltime);
+					printf("%-*.*s  %-*.*s %-*.*s %s\n",
+					    namesz, namesz, bp->ut_name,
+					    linesz, linesz, bp->ut_line,
+					    hostsz, hostsz, bp->ut_host, ct);
+					if (maxrec != -1 && !--maxrec)
+						return;
+				}
+				continue;
+			}
+			/*
+			 * if the line is '{' or '|', date got set; see
+			 * utmpx(5) for more info.
+			 */
+			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
+			    && !bp->ut_line[1]) {
+				if (wantx(bp, NO)) {
+					ct = fmttime(bp->ut_xtime, fulltime);
+				printf("%-*.*s  %-*.*s %-*.*s %s\n",
+				    namesz, namesz,
+				    bp->ut_name,
+				    linesz, linesz,
+				    bp->ut_line,
+				    hostsz, hostsz,
+				    bp->ut_host,
+				    ct);
+					if (maxrec && !--maxrec)
+						return;
+				}
+				continue;
+			}
+			/* find associated tty */
+			for (T = ttylist;; T = T->next) {
+				if (!T) {
+					/* add new one */
+					T = addtty(bp->ut_line);
+					break;
+				}
+				if (!strncmp(T->tty, bp->ut_line, UTX_LINESIZE))
+					break;
+			}
+			if (bp->ut_type == SIGNATURE)
+				continue;
+			if (bp->ut_name[0] && wantx(bp, YES)) {
+				ct = fmttime(bp->ut_xtime, fulltime);
+				printf("%-*.*s  %-*.*s %-*.*s %s ",
+				    namesz, namesz, bp->ut_name,
+				    linesz, linesz, bp->ut_line,
+				    hostsz, hostsz, bp->ut_host,
+				    ct);
+				if (!T->logout)
+					puts("  still logged in");
+				else {
+					if (T->logout < 0) {
+						T->logout = -T->logout;
+						printf("- %s", crmsg);
+					}
+					else
+						printf("- %s",
+						    fmttime(T->logout,
+						    fulltime | TIMEONLY));
+					delta = T->logout - bp->ut_xtime;
+					if (delta < SECSPERDAY)
+						printf("  (%s)\n",
+						    fmttime(delta,
+						    fulltime | TIMEONLY | GMT));
+					else
+						printf(" (%ld+%s)\n",
+						    delta / SECSPERDAY,
+						    fmttime(delta,
+						    fulltime | TIMEONLY | GMT));
+				}
+				if (maxrec != -1 && !--maxrec)
+					return;
+			}
+			T->logout = bp->ut_xtime;
+		}
+	}
+	fulltime = 1;	/* show full time */
+	crmsg = fmttime(bufx[1].ut_xtime, FULLTIME);
+	if ((ct = strrchr(file, '/')) != NULL)
+		ct++;
+	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
+}
 
-#ifdef SUPPORT_UTMPX
-#define utmp utmpx
-#define want wantx
-#define wtmp wtmpx
-#define buf bufx
-#define onintr onintrx
-#define TYPE(a) (a)->ut_type
-#define NAMESIZE UTX_USERSIZE
-#define LINESIZE UTX_LINESIZE
-#define HOSTSIZE UTX_HOSTSIZE
-#define ut_timefld ut_xtime
-#define FIRSTVALID 1
-#include "want.c"
-#endif
+/*
+ * wantx --
+ *	see if want this entry
+ */
+static int
+wantx(struct utmpx *bp, int check)
+{
+	ARG *step;
+
+	if (check) {
+		/*
+		 * when uucp and ftp log in over a network, the entry in
+		 * the utmpx file is the name plus their process id.  See
+		 * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
+		 */
+		if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
+			bp->ut_line[3] = '\0';
+		else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
+			bp->ut_line[4] = '\0';
+	}
+	if (!arglist)
+		return (YES);
+
+	for (step = arglist; step; step = step->next)
+		switch(step->type) {
+		case HOST_TYPE:
+			if (!strncasecmp(step->name, bp->ut_host, UTX_HOSTSIZE))
+				return (YES);
+			break;
+		case TTY_TYPE:
+			if (!strncmp(step->name, bp->ut_line, UTX_LINESIZE))
+				return (YES);
+			break;
+		case USER_TYPE:
+			if (!strncmp(step->name, bp->ut_name, UTX_USERSIZE))
+				return (YES);
+			break;
+	}
+	return (NO);
+}
+
+/*
+ * onintrx --
+ *	on interrupt, we inform the user how far we've gotten
+ */
+static void
+onintrx(int signo)
+{
+
+	printf("\ninterrupted %s\n", fmttime(bufx[1].ut_xtime,
+	    FULLTIME));
+	if (signo == SIGINT)
+		exit(1);
+	(void)fflush(stdout);		/* fix required for rsh */
+}
diff --git a/usr.bin/last/want.c b/usr.bin/last/want.c
deleted file mode 100644
index ee5e64faa8..0000000000
--- a/usr.bin/last/want.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*	$NetBSD: last.c,v 1.15 2000/06/30 06:19:58 simonb Exp $	*/
-
-/*
- * Copyright (c) 1987, 1993, 1994
- *	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.
- */
-static struct utmp *buf;
-
-static void onintr(int);
-static int want(struct utmp *, int);
-
-/*
- * wtmp --
- *	read through the wtmp file
- */
-void
-wtmp(const char *file, int namesz, int linesz, int hostsz)
-{
-	struct utmp	*bp;		/* current structure */
-	TTY	*T;			/* tty list entry */
-	struct stat	stb;		/* stat of file for sz */
-	time_t	delta;			/* time difference */
-	off_t	bl;
-	int	bytes, wfd;
-	char	*ct;
-	const char *crmsg;
-	size_t  len = sizeof(*buf) * MAXUTMP;
-
-	if ((buf = malloc(len)) == NULL)
-		err(1, "Cannot allocate utmp buffer");
-
-	crmsg = NULL;
-
-	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
-		err(1, "%s", file);
-	bl = (stb.st_size + len - 1) / len;
-
-	buf[FIRSTVALID].ut_timefld = time(NULL);
-	(void)signal(SIGINT, onintr);
-	(void)signal(SIGQUIT, onintr);
-
-	while (--bl >= 0) {
-		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
-		    (bytes = read(wfd, buf, len)) == -1)
-			err(1, "%s", file);
-		for (bp = &buf[bytes / sizeof(*buf) - 1]; bp >= buf; --bp) {
-			/*
-			 * if the terminal line is '~', the machine stopped.
-			 * see utmp(5) for more info.
-			 */
-			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
-				/* everybody just logged out */
-				for (T = ttylist; T; T = T->next)
-					T->logout = -bp->ut_timefld;
-				currentout = -bp->ut_timefld;
-				crmsg = strncmp(bp->ut_name, "shutdown",
-				    namesz) ? "crash" : "shutdown";
-				if (want(bp, NO)) {
-					ct = fmttime(bp->ut_timefld, fulltime);
-					printf("%-*.*s  %-*.*s %-*.*s %s\n",
-					    namesz, namesz, bp->ut_name,
-					    linesz, linesz, bp->ut_line,
-					    hostsz, hostsz, bp->ut_host, ct);
-					if (maxrec != -1 && !--maxrec)
-						return;
-				}
-				continue;
-			}
-			/*
-			 * if the line is '{' or '|', date got set; see
-			 * utmp(5) for more info.
-			 */
-			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
-			    && !bp->ut_line[1]) {
-				if (want(bp, NO)) {
-					ct = fmttime(bp->ut_timefld, fulltime);
-				printf("%-*.*s  %-*.*s %-*.*s %s\n",
-				    namesz, namesz,
-				    bp->ut_name,
-				    linesz, linesz,
-				    bp->ut_line,
-				    hostsz, hostsz,
-				    bp->ut_host,
-				    ct);
-					if (maxrec && !--maxrec)
-						return;
-				}
-				continue;
-			}
-			/* find associated tty */
-			for (T = ttylist;; T = T->next) {
-				if (!T) {
-					/* add new one */
-					T = addtty(bp->ut_line);
-					break;
-				}
-				if (!strncmp(T->tty, bp->ut_line, LINESIZE))
-					break;
-			}
-			if (TYPE(bp) == SIGNATURE)
-				continue;
-			if (bp->ut_name[0] && want(bp, YES)) {
-				ct = fmttime(bp->ut_timefld, fulltime);
-				printf("%-*.*s  %-*.*s %-*.*s %s ",
-				    namesz, namesz, bp->ut_name,
-				    linesz, linesz, bp->ut_line,
-				    hostsz, hostsz, bp->ut_host,
-				    ct);
-				if (!T->logout)
-					puts("  still logged in");
-				else {
-					if (T->logout < 0) {
-						T->logout = -T->logout;
-						printf("- %s", crmsg);
-					}
-					else
-						printf("- %s",
-						    fmttime(T->logout,
-						    fulltime | TIMEONLY));
-					delta = T->logout - bp->ut_timefld;
-					if (delta < SECSPERDAY)
-						printf("  (%s)\n",
-						    fmttime(delta,
-						    fulltime | TIMEONLY | GMT));
-					else
-						printf(" (%ld+%s)\n",
-						    delta / SECSPERDAY,
-						    fmttime(delta,
-						    fulltime | TIMEONLY | GMT));
-				}
-				if (maxrec != -1 && !--maxrec)
-					return;
-			}
-			T->logout = bp->ut_timefld;
-		}
-	}
-	fulltime = 1;	/* show full time */
-	crmsg = fmttime(buf[FIRSTVALID].ut_timefld, FULLTIME);
-	if ((ct = strrchr(file, '/')) != NULL)
-		ct++;
-	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
-}
-
-/*
- * want --
- *	see if want this entry
- */
-static int
-want(struct utmp *bp, int check)
-{
-	ARG *step;
-
-	if (check) {
-		/*
-		 * when uucp and ftp log in over a network, the entry in
-		 * the utmp file is the name plus their process id.  See
-		 * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
-		 */
-		if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
-			bp->ut_line[3] = '\0';
-		else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
-			bp->ut_line[4] = '\0';
-	}
-	if (!arglist)
-		return (YES);
-
-	for (step = arglist; step; step = step->next) {
-		switch(step->type) {
-		case HOST_TYPE:
-			if (!strncasecmp(step->name, bp->ut_host, HOSTSIZE))
-				return (YES);
-			break;
-		case TTY_TYPE:
-			if (!strncmp(step->name, bp->ut_line, LINESIZE))
-				return (YES);
-			break;
-		case USER_TYPE:
-			if (!strncmp(step->name, bp->ut_name, NAMESIZE))
-				return (YES);
-			break;
-		}
-	}
-	return (NO);
-}
-
-/*
- * onintr --
- *	on interrupt, we inform the user how far we've gotten
- */
-static void
-onintr(int signo)
-{
-
-	printf("\ninterrupted %s\n", fmttime(buf[FIRSTVALID].ut_timefld,
-	    FULLTIME));
-	if (signo == SIGINT)
-		exit(1);
-	(void)fflush(stdout);		/* fix required for rsh */
-}
diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile
index 22bb0cbaca..28b9787714 100644
--- a/usr.bin/systat/Makefile
+++ b/usr.bin/systat/Makefile
@@ -21,6 +21,6 @@ LDADD+=	-lutil
 CFLAGS+=	-I${_SHLIBDIRPREFIX}/usr/include/priv/ncurses
 LDFLAGS+=	${PRIVATELIB_LDFLAGS}
 
-CFLAGS+= -I${.CURDIR}/../who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+= -I${.CURDIR}/../who
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/users/Makefile b/usr.bin/users/Makefile
index b6caa023d1..ba84671853 100644
--- a/usr.bin/users/Makefile
+++ b/usr.bin/users/Makefile
@@ -7,6 +7,6 @@ SRCS=	users.c utmpentry.c
 DPADD=	${LIBUTIL}
 LDADD=	-lutil
 
-CFLAGS+= -I${.CURDIR}/../who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+= -I${.CURDIR}/../who
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/w/Makefile b/usr.bin/w/Makefile
index cc05d02fd4..21b09fde95 100644
--- a/usr.bin/w/Makefile
+++ b/usr.bin/w/Makefile
@@ -12,7 +12,6 @@ LINKS=	${BINDIR}/w ${BINDIR}/uptime
 WARNS?=	3
 NO_STRICT_ALIASING=
 
-CFLAGS+=	-DSUPPORT_UTMP -DSUPPORT_UTMPX
 .PATH: ${.CURDIR}/../../bin/ps
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/w/w.c b/usr.bin/w/w.c
index 86c23fbc65..7cca80da78 100644
--- a/usr.bin/w/w.c
+++ b/usr.bin/w/w.c
@@ -65,12 +65,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-#endif
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 #include <vis.h>
 
 #include <arpa/nameser.h>
@@ -79,9 +74,6 @@
 #include "extern.h"
 
 struct timeval	boottime;
-#ifdef SUPPORT_UTMP
-struct utmp	utmp;
-#endif
 struct winsize	ws;
 kvm_t	       *kd;
 time_t		now;		/* the current time of day */
@@ -120,10 +112,8 @@ struct	entry {
 #define debugproc(p) *((struct kinfo_proc **)&(p)->kp_spare[0])
 
 static void		 pr_header(time_t *, int);
-#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
 static struct stat	*ttystat(char *, int);
 static void	process(struct entry *);
-#endif
 static void		 usage(int);
 static int		 this_is_uptime(const char *s);
 
@@ -138,12 +128,7 @@ main(int argc, char **argv)
 	in_addr_t l;
 	int ch, i, nentries, nusers, wcmd, longidle, dropgid;
 	char *memf, *nlistf, *p, *x;
-#ifdef SUPPORT_UTMP
-	struct utmp *ut;
-#endif
-#ifdef SUPPORT_UTMPX
 	struct utmpx *utx;
-#endif
 	char buf[MAXHOSTNAMELEN], errbuf[_POSIX2_LINE_MAX];
 
 	(void)setlocale(LC_ALL, "");
@@ -210,18 +195,12 @@ main(int argc, char **argv)
 		errx(1, "%s", errbuf);
 
 	(void)time(&now);
-#ifdef SUPPORT_UTMPX
 	setutxent();
-#endif
-#ifdef SUPPORT_UTMP
-	setutent();
-#endif
 
 	if (*argv)
 		sel_users = argv;
 
 	nusers = 0;
-#ifdef SUPPORT_UTMPX
 	while ((utx = getutxent()) != NULL) {
 		if (utx->ut_type != USER_PROCESS)
 			continue;
@@ -266,59 +245,7 @@ main(int argc, char **argv)
 		if (wcmd != 0)
 			process(ep);
 	}
-#endif
-
-#ifdef SUPPORT_UTMP
-	while ((ut = getutent()) != NULL) {
-		if (ut->ut_name[0] == '\0')
-			continue;
-		++nusers;
-		if (sel_users) {
-			int usermatch;
-			char **user;
-
-			usermatch = 0;
-			for (user = sel_users; !usermatch && *user; user++)
-				if (!strncmp(ut->ut_name, *user, UT_NAMESIZE))
-					usermatch = 1;
-			if (!usermatch)
-				continue;
-		}
-
-		/* Don't process entries that we have utmpx for */
-		for (ep = ehead; ep != NULL; ep = ep->next) {
-			if (strncmp(ep->line, ut->ut_line,
-			    sizeof(ut->ut_line)) == 0)
-				break;
-		}
-		if (ep != NULL) {
-			--nusers; /* Duplicate entry */
-			continue;
-		}
-
-		if ((ep = calloc(1, sizeof(struct entry))) == NULL)
-			err(1, NULL);
-		(void)memcpy(ep->name, ut->ut_name, sizeof(ut->ut_name));
-		(void)memcpy(ep->line, ut->ut_line, sizeof(ut->ut_line));
-		(void)memcpy(ep->host, ut->ut_host, sizeof(ut->ut_host));
-		ep->name[sizeof(ut->ut_name)] = '\0';
-		ep->line[sizeof(ut->ut_line)] = '\0';
-		ep->host[sizeof(ut->ut_host)] = '\0';
-		ep->tv.tv_sec = ut->ut_time;
-
-		*nextp = ep;
-		nextp = &(ep->next);
-		if (wcmd != 0)
-			process(ep);
-	}
-#endif
-
-#ifdef SUPPORT_UTMPX
 	endutxent();
-#endif
-#ifdef SUPPORT_UTMP
-	endutent();
-#endif	
 	
 	if (header || wcmd == 0) {
 		pr_header(&now, nusers);
@@ -409,9 +336,7 @@ main(int argc, char **argv)
 			save->next = *nextp;
 			*nextp = save;
 		}
-	}
-#if defined(SUPPORT_UTMP) && defined(SUPPORT_UTMPX)
-	else if (ehead != NULL) {
+	} else if (ehead != NULL) {
 		struct entry *from = ehead, *save;
 
 		ehead = NULL;
@@ -426,7 +351,6 @@ main(int argc, char **argv)
 			*nextp = save;
 		}
 	}
-#endif
 
 	if (!nflag) {
 		if (gethostname(domain, sizeof(domain)) < 0 ||
@@ -610,7 +534,6 @@ this_is_uptime(const char *s)
 	return (-1);
 }
 
-#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
 static void
 process(struct entry *ep)
 {
@@ -656,4 +579,3 @@ process(struct entry *ep)
 	if ((ep->idle = now - touched) < 0)
 		ep->idle = 0;
 }
-#endif
diff --git a/usr.bin/wall/Makefile b/usr.bin/wall/Makefile
index 81e3c9638e..5c8b456d24 100644
--- a/usr.bin/wall/Makefile
+++ b/usr.bin/wall/Makefile
@@ -10,6 +10,6 @@ BINMODE=2555
 DPADD+=	${LIBUTIL}
 LDADD+=	-lutil
 
-CFLAGS+= -I${.CURDIR}/../who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+= -I${.CURDIR}/../who
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/who/Makefile b/usr.bin/who/Makefile
index 68d3b1d324..df91528b2e 100644
--- a/usr.bin/who/Makefile
+++ b/usr.bin/who/Makefile
@@ -1,10 +1,6 @@
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
-# $DragonFly: src/usr.bin/who/Makefile,v 1.3 2007/08/27 16:51:01 pavalos Exp $
 
 PROG=	who
-
 SRCS+=	who.c utmpentry.c
 
-CFLAGS+=	-DSUPPORT_UTMPX -DSUPPORT_UTMP
-
 .include <bsd.prog.mk>
diff --git a/usr.bin/who/utmpentry.c b/usr.bin/who/utmpentry.c
index 324805edd0..a6427fbea3 100644
--- a/usr.bin/who/utmpentry.c
+++ b/usr.bin/who/utmpentry.c
@@ -37,13 +37,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
-
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-#endif
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 
 #include "utmpentry.h"
 
@@ -78,25 +72,16 @@
 #define	COMPILE_ASSERT(x)	_Static_assert(x, "assertion failed")
 
 
-#ifdef SUPPORT_UTMP
-static void getentry(struct utmpentry *, struct utmp *);
-static struct timespec utmptime = {0, 0};
-#endif
-#ifdef SUPPORT_UTMPX
 static void getentryx(struct utmpentry *, struct utmpx *);
 static struct timespec utmpxtime = {0, 0};
-#endif
-#if defined(SUPPORT_UTMPX) || defined(SUPPORT_UTMP)
 static int setup(const char *);
 static void adjust_size(struct utmpentry *e);
-#endif
 
 int maxname = 8, maxline = 8, maxhost = 16;
 int etype = 1 << USER_PROCESS;
 static int numutmp = 0;
 static struct utmpentry *ehead;
 
-#if defined(SUPPORT_UTMPX) || defined(SUPPORT_UTMP)
 static void
 adjust_size(struct utmpentry *e)
 {
@@ -118,36 +103,18 @@ setup(const char *fname)
 	const char *sfname;
 
 	if (fname == NULL) {
-#ifdef SUPPORT_UTMPX
 		setutxent();
-#endif
-#ifdef SUPPORT_UTMP
-		setutent();
-#endif
 	} else {
 		size_t len = strlen(fname);
 		if (len == 0)
 			errx(1, "Filename cannot be 0 length.");
 		what = fname[len - 1] == 'x' ? 1 : 2;
 		if (what == 1) {
-#ifdef SUPPORT_UTMPX
 			if (utmpxname(fname) == 0)
 				warnx("Cannot set utmpx file to `%s'",
 				    fname);
-#else
-			warnx("utmpx support not compiled in");
-#endif
-		} else {
-#ifdef SUPPORT_UTMP
-			if (utmpname(fname) == 0)
-				warnx("Cannot set utmp file to `%s'",
-				    fname);
-#else
-			warnx("utmp support not compiled in");
-#endif
 		}
 	}
-#ifdef SUPPORT_UTMPX
 	if (what & 1) {
 		sfname = fname ? fname : _PATH_UTMPX;
 		if (stat(sfname, &st) == -1) {
@@ -160,36 +127,15 @@ setup(const char *fname)
 			    what &= ~1;
 		}
 	}
-#endif
-#ifdef SUPPORT_UTMP
-	if (what & 2) {
-		sfname = fname ? fname : _PATH_UTMP;
-		if (stat(sfname, &st) == -1) {
-			warn("Cannot stat `%s'", sfname);
-			what &= ~2;
-		} else {
-			if (timespeccmp(&st.st_mtimespec, &utmptime, >))
-				utmptime = st.st_mtimespec;
-			else
-				what &= ~2;
-		}
-	}
-#endif
 	return what;
 }
-#endif
 
 void
 endutentries(void)
 {
 	struct utmpentry *ep;
 
-#ifdef SUPPORT_UTMP
-	timespecclear(&utmptime);
-#endif
-#ifdef SUPPORT_UTMPX
 	timespecclear(&utmpxtime);
-#endif
 	ep = ehead;
 	while (ep) {
 		struct utmpentry *sep = ep;
@@ -203,13 +149,7 @@ endutentries(void)
 int
 getutentries(const char *fname, struct utmpentry **epp)
 {
-#ifdef SUPPORT_UTMPX
 	struct utmpx *utx;
-#endif
-#ifdef SUPPORT_UTMP
-	struct utmp *ut;
-#endif
-#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
 	struct utmpentry *ep;
 	int what = setup(fname);
 	struct utmpentry **nextp = &ehead;
@@ -223,9 +163,7 @@ getutentries(const char *fname, struct utmpentry **epp)
 		ehead = NULL;
 		numutmp = 0;
 	}
-#endif
 
-#ifdef SUPPORT_UTMPX
 	while ((what & 1) && (utx = getutxent()) != NULL) {
 		if (fname == NULL && ((1 << utx->ut_type) & etype) == 0) {
 			continue;
@@ -238,34 +176,8 @@ getutentries(const char *fname, struct utmpentry **epp)
 		*nextp = ep;
 		nextp = &(ep->next);
 	}
-#endif
 
-#ifdef SUPPORT_UTMP
-	if ((etype & (1 << USER_PROCESS)) != 0) {
-		while ((what & 2) && (ut = getutent()) != NULL) {
-			if (fname == NULL && (*ut->ut_name == '\0' ||
-			    *ut->ut_line == '\0'))
-				continue;
-			/* Don't process entries that we have utmpx for */
-			for (ep = ehead; ep != NULL; ep = ep->next) {
-				if (strncmp(ep->line, ut->ut_line,
-				    sizeof(ut->ut_line)) == 0)
-					break;
-			}
-			if (ep != NULL)
-				continue;
-			if ((ep = calloc(1, sizeof(*ep))) == NULL) {
-				warn(NULL);
-				return 0;
-			}
-			getentry(ep, ut);
-			*nextp = ep;
-			nextp = &(ep->next);
-		}
-	}
-#endif
 	numutmp = 0;
-#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
 	if (ehead != NULL) {
 		struct utmpentry *from = ehead, *save;
 		
@@ -284,50 +196,8 @@ getutentries(const char *fname, struct utmpentry **epp)
 	}
 	*epp = ehead;
 	return numutmp;
-#else
-	*epp = NULL;
-	return 0;
-#endif
-}
-
-#ifdef SUPPORT_UTMP
-static void
-getentry(struct utmpentry *e, struct utmp *up)
-{
-#if 1
-	COMPILE_ASSERT(sizeof(e->name) > sizeof(up->ut_name));
-	COMPILE_ASSERT(sizeof(e->line) > sizeof(up->ut_line));
-	COMPILE_ASSERT(sizeof(e->host) > sizeof(up->ut_host));
-#endif
-
-	/*
-	 * e has just been calloc'd. We don't need to clear it or
-	 * append null-terminators, because its length is strictly
-	 * greater than the source string. Use strncpy to _read_
-	 * up->ut_* because they may not be terminated. For this
-	 * reason we use the size of the _source_ as the length
-	 * argument.
-	 */
-
-	snprintf(e->name, sizeof(e->name), "%.*s",
-		 (int)sizeof(up->ut_name), up->ut_name);
-	snprintf(e->line, sizeof(e->line), "%.*s",
-		 (int)sizeof(up->ut_line), up->ut_line);
-	snprintf(e->host, sizeof(e->host), "%.*s",
-		 (int)sizeof(up->ut_host), up->ut_host);
-
-	e->tv.tv_sec = up->ut_time;
-	e->tv.tv_usec = 0;
-	e->pid = 0;
-	e->term = 0;
-	e->exit = 0;
-	e->sess = 0;
-	e->type = USER_PROCESS;
-	adjust_size(e);
 }
-#endif
 
-#ifdef SUPPORT_UTMPX
 static void
 getentryx(struct utmpentry *e, struct utmpx *up)
 {
@@ -358,4 +228,3 @@ getentryx(struct utmpentry *e, struct utmpx *up)
 	e->type = up->ut_type;
 	adjust_size(e);
 }
-#endif
diff --git a/usr.bin/who/utmpentry.h b/usr.bin/who/utmpentry.h
index 6ebd8937e2..0bf93d0371 100644
--- a/usr.bin/who/utmpentry.h
+++ b/usr.bin/who/utmpentry.h
@@ -29,19 +29,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#if defined(SUPPORT_UTMPX)
-# include <utmpx.h>
-# define WHO_NAME_LEN		_UTX_USERSIZE
-# define WHO_LINE_LEN		_UTX_LINESIZE
-# define WHO_HOST_LEN		_UTX_HOSTSIZE
-#elif defined(SUPPORT_UTMP)
-# include <utmp.h>
-# define WHO_NAME_LEN		UT_NAMESIZE
-# define WHO_LINE_LEN		UT_LINESIZE
-# define WHO_HOST_LEN		UT_HOSTSIZE
-#else
-# error Either SUPPORT_UTMPX or SUPPORT_UTMP must be defined!
-#endif
+#include <utmpx.h>
+#define WHO_NAME_LEN		_UTX_USERSIZE
+#define WHO_LINE_LEN		_UTX_LINESIZE
+#define WHO_HOST_LEN		_UTX_HOSTSIZE
 
 
 struct utmpentry {
diff --git a/usr.bin/who/who.c b/usr.bin/who/who.c
index ab9aff8c2e..3d2bd24ca9 100644
--- a/usr.bin/who/who.c
+++ b/usr.bin/who/who.c
@@ -45,12 +45,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#ifdef SUPPORT_UTMP
-#include <utmp.h>
-#endif
-#ifdef SUPPORT_UTMPX
 #include <utmpx.h>
-#endif
 
 #include "utmpentry.h"
 
@@ -73,7 +68,6 @@ struct ut_type_names {
   int type;
   const char *name;
 } ut_type_names[] = {
-#ifdef SUPPORT_UTMPX
   { EMPTY, "empty" },
   { RUN_LVL, "run level" },
   { BOOT_TIME, "boot time" },
@@ -86,7 +80,6 @@ struct ut_type_names {
   { ACCOUNTING, "accounting" },
   { SIGNATURE, "signature" },
   { DOWN_TIME, "down time" },
-#endif /* SUPPORT_UTMPX */
   { -1, "unknown" }
 };
 
diff --git a/usr.bin/write/Makefile b/usr.bin/write/Makefile
index 7de9cc6208..8dc09e5eaf 100644
--- a/usr.bin/write/Makefile
+++ b/usr.bin/write/Makefile
@@ -10,6 +10,6 @@ BINGRP=	tty
 DPADD+=	${LIBUTIL}
 LDADD+=	-lutil
 
-CFLAGS+= -I${.CURDIR}/../who -DSUPPORT_UTMP -DSUPPORT_UTMPX
+CFLAGS+= -I${.CURDIR}/../who
 
 .include <bsd.prog.mk>
diff --git a/usr.bin/wtmpcvt/Makefile b/usr.bin/wtmpcvt/Makefile
new file mode 100644
index 0000000000..0caa097be1
--- /dev/null
+++ b/usr.bin/wtmpcvt/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+PROG=	wtmpcvt
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/wtmpcvt/wtmpcvt.1 b/usr.bin/wtmpcvt/wtmpcvt.1
new file mode 100644
index 0000000000..04acfde4cc
--- /dev/null
+++ b/usr.bin/wtmpcvt/wtmpcvt.1
@@ -0,0 +1,66 @@
+.\" Copyright (c) 2010 Ed Schouten <ed@FreeBSD.org>
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 14, 2010
+.Dt WTMPCVT 1
+.Os
+.Sh NAME
+.Nm wtmpcvt
+.Nd convert wtmp files to the utmpx format
+.Sh SYNOPSIS
+.Nm
+.Ar input
+.Ar output
+.Sh DESCRIPTION
+The
+.Nm
+utility converts traditional
+.Pa wtmp
+user accounting database files to the same format that is used by
+.Pa /var/log/utx.log .
+This makes it possible to view their contents using existing accounting
+utilities, such as
+.Xr last 1
+and
+.Xr ac 8 .
+.Sh SEE ALSO
+.Xr last 1 ,
+.Xr getutxent 3 ,
+.Xr ac 8
+.Sh HISTORY
+The
+.Nm
+utility appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+.An Ed Schouten Aq ed@FreeBSD.org
+.Sh BUGS
+The application assumes the
+.Ar input
+file has the same byte order as the host system.
+The
+.Ar output
+file can be used on any architecture.
diff --git a/usr.bin/wtmpcvt/wtmpcvt.c b/usr.bin/wtmpcvt/wtmpcvt.c
new file mode 100644
index 0000000000..84d52a3042
--- /dev/null
+++ b/usr.bin/wtmpcvt/wtmpcvt.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2010 Ed Schouten <ed@FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/endian.h>
+#include <sys/param.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utmpx.h>
+
+struct outmp {
+	char	ut_line[8];
+	char	ut_user[16];
+	char	ut_host[16];
+        time_t  ut_time;
+};
+
+static const char vers[] = "utmpx-2.00";
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "usage: wtmpcvt input output\n");
+	exit(1);
+}
+
+static void
+outmp_to_utmpx(const struct outmp *ui, struct utmpx *uo)
+{
+
+	memset(uo, 0, sizeof *uo);
+#define	COPY_STRING(field) do {						\
+	strncpy(uo->ut_ ## field, ui->ut_ ## field,			\
+	    MIN(sizeof uo->ut_ ## field, sizeof ui->ut_ ## field));	\
+} while (0)
+#define	COPY_LINE_TO_ID() do {						\
+	strncpy(uo->ut_id, ui->ut_line,					\
+	    MIN(sizeof uo->ut_id, sizeof ui->ut_line));			\
+} while (0)
+#define	MATCH(field, value)	(strncmp(ui->ut_ ## field, (value),	\
+					sizeof(ui->ut_ ## field)) == 0)
+	if (MATCH(user, "reboot") && MATCH(line, "~")) {
+		uo->ut_type = INIT_PROCESS;
+		COPY_STRING(user);
+		COPY_STRING(line);
+	} else if (MATCH(user, "date") && MATCH(line, "|")) {
+		uo->ut_type = OLD_TIME;
+	} else if (MATCH(user, "date") && MATCH(line, "{")) {
+		uo->ut_type = NEW_TIME;
+	} else if (MATCH(user, "shutdown") && MATCH(line, "~")) {
+		uo->ut_type = INIT_PROCESS;
+		COPY_STRING(user);
+		COPY_STRING(line);
+	} else if (MATCH(user, "") && MATCH(host, "") && !MATCH(line, "")) {
+		uo->ut_type = DEAD_PROCESS;
+		COPY_LINE_TO_ID();
+	} else if (!MATCH(user, "") && !MATCH(line, "") && ui->ut_time != 0) {
+		uo->ut_type = USER_PROCESS;
+		COPY_STRING(user);
+		COPY_STRING(line);
+		COPY_STRING(host);
+		COPY_LINE_TO_ID();
+	} else {
+		uo->ut_type = EMPTY;
+		return;
+	}
+#undef COPY_STRING
+#undef COPY_LINE_TO_ID
+#undef MATCH
+
+	uo->ut_tv.tv_sec = ui->ut_time;
+	uo->ut_tv.tv_usec = 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+	FILE *in, *out;
+	struct outmp ui;
+	struct utmpx uo;
+
+	if (argc != 3)
+		usage();
+
+	/* Open files. */
+	in = fopen(argv[1], "r");
+	if (in == NULL)
+		err(1, "%s", argv[1]);
+	out = fopen(argv[2], "w");
+	if (out == NULL)
+		err(1, "%s", argv[2]);
+
+	/* Write signature. */
+	memset(&uo, 0, sizeof uo);
+	uo.ut_type = SIGNATURE;
+	memcpy(uo.ut_user, vers, sizeof(vers));
+	fwrite(&uo, sizeof uo, 1, out);
+
+	/* Process entries. */
+	while (fread(&ui, sizeof ui, 1, in) == 1) {
+		outmp_to_utmpx(&ui, &uo);
+		if (uo.ut_type == EMPTY)
+			continue;
+
+		/* Write new entry to output file. */
+		fwrite(&uo, sizeof uo, 1, out);
+	}
+
+	fclose(in);
+	fclose(out);
+	return (0);
+}
diff --git a/usr.sbin/ac/Makefile b/usr.sbin/ac/Makefile
index 6a33def526..28f9a71eeb 100644
--- a/usr.sbin/ac/Makefile
+++ b/usr.sbin/ac/Makefile
@@ -1,4 +1,4 @@
-# $FreeBSD: src/usr.sbin/ac/Makefile,v 1.4.2.1 2001/04/25 12:09:11 ru Exp $
+# $FreeBSD: head/usr.sbin/ac/Makefile 239910 2012-08-30 16:45:27Z ed $
 
 PROG=	ac
 MAN=	ac.8
diff --git a/usr.sbin/ac/ac.8 b/usr.sbin/ac/ac.8
index aa605049c5..71aca31fd8 100644
--- a/usr.sbin/ac/ac.8
+++ b/usr.sbin/ac/ac.8
@@ -11,11 +11,6 @@
 .\" 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. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"      This product includes software developed by Christopher G. Demetriou.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\"    derived from this software without specific prior written permission
 .\"
 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -28,9 +23,9 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/usr.sbin/ac/ac.8,v 1.13.2.5 2003/03/11 21:13:47 trhodes Exp $
+.\" $FreeBSD: head/usr.sbin/ac/ac.8 248413 2013-03-17 06:54:04Z joel $
 .\"
-.Dd March 15, 1994
+.Dd September 4, 2019
 .Dt AC 8
 .Os
 .Sh NAME
@@ -45,7 +40,7 @@
 .Op Ar users ...
 .Sh DESCRIPTION
 If the file
-.Pa /var/log/wtmp
+.Pa /var/log/wtmpx
 exists, a record of individual login and logout
 times are written to it by
 .Xr login 1
@@ -72,7 +67,8 @@ Display the connect times in 24 hour chunks.
 .It Fl p
 Print individual users' totals.
 .It Fl t Ar tty
-Only do accounting logins on certain ttys.  The
+Only do accounting logins on certain ttys.
+The
 .Ar tty
 specification can start with '!' to indicate not this
 .Ar tty
@@ -84,7 +80,7 @@ flags may be specified.
 Read connect time data from
 .Ar wtmp
 instead of the default file,
-.Pa /var/log/wtmp .
+.Pa /var/log/wtmpx .
 .It Ar users ...
 Display totals for the given individuals only.
 .El
@@ -93,40 +89,40 @@ If no arguments are given,
 .Nm
 displays the total connect time for all
 accounts with login sessions recorded in
-.Pa wtmp .
+.Pa wtmpx .
 .Pp
 The default
-.Pa wtmp
+.Pa wtmpx
 file will increase without bound unless it is truncated.
 It is normally truncated by the daily scripts run
 by
 .Xr cron 8 ,
 which rename and rotate the
-.Pa wtmp
+.Pa wtmpx
 files, keeping a week's worth of data on
-hand.  No login or connect time accounting is performed if
-.Pa /var/log/wtmp
+hand.
+No login or connect time accounting is performed if
+.Pa /var/log/wtmpx
 does not exist.
-.Pp
-For example,
-.Bd -literal
-ac -p -t "ttyd*" > modems
-ac -p -t "!ttyd*" > other
-.Ed
-.Pp
-allows times recorded in
-.Pa modems
-to be charged out at a different rate than
-.Pa other .
 .Sh FILES
-.Bl -tag -width /var/log/wtmp -compact
-.It Pa /var/log/wtmp
+.Bl -tag -width /var/log/wtmpx -compact
+.It Pa /var/log/wtmpx
 connect time accounting file
 .El
 .Sh EXIT STATUS
 .Ex -std
+.Sh EXAMPLES
+Allow times recorded in
+.Pa modems
+to be charged out at a different rate than
+.Pa other :
+.Bd -literal -offset indent
+ac -p -t "ttyd*" > modems
+ac -p -t "!ttyd*" > other
+.Ed
 .Sh SEE ALSO
 .Xr login 1 ,
-.Xr utmp 5 ,
+.Xr getutxent 3 ,
+.Xr utmpx 5 ,
 .Xr init 8 ,
 .Xr sa 8
diff --git a/usr.sbin/ac/ac.c b/usr.sbin/ac/ac.c
index b61bff2cd1..6add63bd3c 100644
--- a/usr.sbin/ac/ac.c
+++ b/usr.sbin/ac/ac.c
@@ -1,74 +1,93 @@
-/*
- *      Copyright (c) 1994 Christopher G. Demetriou.
- *      @(#)Copyright (c) 1994, Simon J. Gerraty.
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * Copyright (c) 1994 Simon J. Gerraty
+ * Copyright (c) 2012 Ed Schouten <ed@FreeBSD.org>
+ * 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.
  *
- *      This is free software.  It comes with NO WARRANTY.
- *      Permission to use, modify and distribute this source code
- *      is granted subject to the following conditions.
- *      1/ that the above copyright notice and this notice
- *      are preserved in all copies and that due credit be given
- *      to the author.
- *      2/ that any changes to this code are clearly commented
- *      as such so that the author does not get blamed for bugs
- *      other than his own.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
  *
- * $FreeBSD: src/usr.sbin/ac/ac.c,v 1.14.2.2 2002/03/12 19:55:04 phantom Exp $
+ * $FreeBSD: head/usr.sbin/ac/ac.c 326276 2017-11-27 15:37:16Z pfg $
  */
 
-#include <sys/types.h>
-#include <sys/file.h>
+#include <sys/queue.h>
 #include <sys/time.h>
+
 #include <err.h>
 #include <errno.h>
 #include <langinfo.h>
 #include <locale.h>
-#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <timeconv.h>
 #include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
 
 /*
  * this is for our list of currently logged in sessions
  */
-struct utmp_list {
-	struct utmp_list *next;
-	struct utmp usr;
+struct utmpx_entry {
+	SLIST_ENTRY(utmpx_entry) next;
+	char		user[sizeof(((struct utmpx *)0)->ut_user)];
+	char		id[sizeof(((struct utmpx *)0)->ut_id)];
+#ifdef CONSOLE_TTY
+	char		line[sizeof(((struct utmpx *)0)->ut_line)];
+#endif
+	struct timeval	time;
 };
 
 /*
  * this is for our list of users that are accumulating time.
  */
-struct user_list {
-	struct user_list *next;
-	char	name[UT_NAMESIZE+1];
-	time_t	secs;
+struct user_entry {
+	SLIST_ENTRY(user_entry) next;
+	char		user[sizeof(((struct utmpx *)0)->ut_user)];
+	struct timeval	time;
 };
 
 /*
  * this is for chosing whether to ignore a login
  */
-struct tty_list {
-	struct tty_list *next;
-	char	name[UT_LINESIZE+3];
-	int	len;
-	int	ret;
+struct tty_entry {
+	SLIST_ENTRY(tty_entry) next;
+	char		line[sizeof(((struct utmpx *)0)->ut_line) + 2];
+	size_t		len;
+	int		ret;
 };
 
 /*
  * globals - yes yuk
  */
 #ifdef CONSOLE_TTY
-static char 	*Console = CONSOLE_TTY;
+static const char *Console = CONSOLE_TTY;
 #endif
-static time_t	Total = 0;
-static time_t	FirstTime = 0;
+static struct timeval Total = { 0, 0 };
+static struct timeval FirstTime = { 0, 0 };
 static int	Flags = 0;
-static struct user_list *Users = NULL;
-static struct tty_list *Ttys = NULL;
-
-#define NEW(type) (type *)malloc(sizeof(type))
+static SLIST_HEAD(, utmpx_entry) CurUtmpx = SLIST_HEAD_INITIALIZER(CurUtmpx);
+static SLIST_HEAD(, user_entry) Users = SLIST_HEAD_INITIALIZER(Users);
+static SLIST_HEAD(, tty_entry) Ttys = SLIST_HEAD_INITIALIZER(Ttys);
 
 #define	AC_W	1				/* not _PATH_WTMP */
 #define	AC_D	2				/* daily totals (ignore -p) */
@@ -76,90 +95,56 @@ static struct tty_list *Ttys = NULL;
 #define	AC_U	8				/* specified users only */
 #define	AC_T	16				/* specified ttys only */
 
-#ifdef DEBUG
-static int Debug = 0;
-#endif
-
-static int		ac(FILE *);
-static struct tty_list	*add_tty(char *);
-static int		do_tty(char *);
-static FILE		*file(const char *);
-static struct utmp_list	*log_in(struct utmp_list *, struct utmp *);
-static struct utmp_list	*log_out(struct utmp_list *, struct utmp *);
-#ifdef CONSOLE_TTY
-static int		on_console(struct utmp_list *);
-#endif
-static void		show(const char *, time_t);
-static void		show_today(struct user_list *, struct utmp_list *,
-			    time_t);
-static void		show_users(struct user_list *);
-static struct user_list	*update_user(struct user_list *, char *, time_t);
-static void		usage(void) __dead2;
+static void	ac(const char *);
+static void	usage(void) __dead2;
 
-/*
- * open wtmp or die
- */
-static FILE *
-file(const char *name)
-{
-	FILE *fp;
-
-	if ((fp = fopen(name, "r")) == NULL)
-		err(1, "%s", name);
-	/* in case we want to discriminate */
-	if (strcmp(_PATH_WTMP, name))
-		Flags |= AC_W;
-	return fp;
-}
-
-static struct tty_list *
-add_tty(char *name)
+static void
+add_tty(const char *line)
 {
-	struct tty_list *tp;
+	struct tty_entry *tp;
 	char *rcp;
 
 	Flags |= AC_T;
 
-	if ((tp = NEW(struct tty_list)) == NULL)
+	if ((tp = malloc(sizeof(*tp))) == NULL)
 		errx(1, "malloc failed");
 	tp->len = 0;				/* full match */
 	tp->ret = 1;				/* do if match */
-	if (*name == '!') {			/* don't do if match */
+	if (*line == '!') {			/* don't do if match */
 		tp->ret = 0;
-		name++;
+		line++;
 	}
-	strncpy(tp->name, name, sizeof(tp->name) - 1);
-	tp->name[sizeof(tp->name) - 1] = '\0';
-	if ((rcp = strchr(tp->name, '*')) != NULL) {	/* wild card */
+	strlcpy(tp->line, line, sizeof(tp->line));
+	/* Wildcard. */
+	if ((rcp = strchr(tp->line, '*')) != NULL) {
 		*rcp = '\0';
-		tp->len = strlen(tp->name);	/* match len bytes only */
+		/* Match len bytes only. */
+		tp->len = strlen(tp->line);
 	}
-	tp->next = Ttys;
-	Ttys = tp;
-	return Ttys;
+	SLIST_INSERT_HEAD(&Ttys, tp, next);
 }
 
 /*
  * should we process the named tty?
  */
 static int
-do_tty(char *name)
+do_tty(const char *line)
 {
-	struct tty_list *tp;
+	struct tty_entry *tp;
 	int def_ret = 0;
 
-	for (tp = Ttys; tp != NULL; tp = tp->next) {
+	SLIST_FOREACH(tp, &Ttys, next) {
 		if (tp->ret == 0)		/* specific don't */
 			def_ret = 1;		/* default do */
 		if (tp->len != 0) {
-			if (strncmp(name, tp->name, tp->len) == 0)
+			if (strncmp(line, tp->line, tp->len) == 0)
 				return tp->ret;
 		} else {
-			if (strncmp(name, tp->name, sizeof(tp->name)) == 0)
+			if (strncmp(line, tp->line, sizeof(tp->line)) == 0)
 				return tp->ret;
 		}
 	}
-	return def_ret;
+	return (def_ret);
 }
 
 #ifdef CONSOLE_TTY
@@ -167,66 +152,66 @@ do_tty(char *name)
  * is someone logged in on Console?
  */
 static int
-on_console(struct utmp_list *head)
+on_console(void)
 {
-	struct utmp_list *up;
+	struct utmpx_entry *up;
 
-	for (up = head; up; up = up->next) {
-		if (strncmp(up->usr.ut_line, Console,
-		    sizeof(up->usr.ut_line)) == 0)
-			return 1;
-	}
-	return 0;
+	SLIST_FOREACH(up, &CurUtmpx, next)
+		if (strcmp(up->line, Console) == 0)
+			return (1);
+	return (0);
 }
 #endif
 
 /*
- * update user's login time
+ * Update user's login time.
+ * If no entry for this user is found, a new entry is inserted into the
+ * list alphabetically.
  */
-static struct user_list *
-update_user(struct user_list *head, char *name, time_t secs)
+static void
+update_user(const char *user, struct timeval secs)
 {
-	struct user_list *up;
+	struct user_entry *up, *aup;
+	int c;
 
-	for (up = head; up != NULL; up = up->next) {
-		if (strncmp(up->name, name, UT_NAMESIZE) == 0) {
-			up->secs += secs;
-			Total += secs;
-			return head;
-		}
+	aup = NULL;
+	SLIST_FOREACH(up, &Users, next) {
+		c = strcmp(up->user, user);
+		if (c == 0) {
+			timeradd(&up->time, &secs, &up->time);
+			timeradd(&Total, &secs, &Total);
+			return;
+		} else if (c > 0)
+			break;
+		aup = up;
 	}
 	/*
 	 * not found so add new user unless specified users only
 	 */
 	if (Flags & AC_U)
-		return head;
+		return;
 
-	if ((up = NEW(struct user_list)) == NULL)
+	if ((up = malloc(sizeof(*up))) == NULL)
 		errx(1, "malloc failed");
-	up->next = head;
-	strncpy(up->name, name, sizeof(up->name) - 1);
-	up->name[sizeof(up->name) - 1] = '\0';	/* paranoid! */
-	up->secs = secs;
-	Total += secs;
-	return up;
+	if (aup == NULL)
+		SLIST_INSERT_HEAD(&Users, up, next);
+	else
+		SLIST_INSERT_AFTER(aup, up, next);
+	strlcpy(up->user, user, sizeof(up->user));
+	up->time = secs;
+	timeradd(&Total, &secs, &Total);
 }
 
 int
-main(int argc, char **argv)
+main(int argc, char *argv[])
 {
-	FILE *fp;
+	const char *wtmpf = NULL;
 	int c;
 
 	setlocale(LC_TIME, "");
 
-	fp = NULL;
-	while ((c = getopt(argc, argv, "Dc:dpt:w:")) != -1) {
+	while ((c = getopt(argc, argv, "c:dpt:w:")) != -1) {
 		switch (c) {
-#ifdef DEBUG
-		case 'D':
-			Debug++;
-			break;
-#endif
 		case 'c':
 #ifdef CONSOLE_TTY
 			Console = optarg;
@@ -244,7 +229,8 @@ main(int argc, char **argv)
 			add_tty(optarg);
 			break;
 		case 'w':
-			fp = file(optarg);
+			Flags |= AC_W;
+			wtmpf = optarg;
 			break;
 		case '?':
 		default:
@@ -257,129 +243,111 @@ main(int argc, char **argv)
 		 * initialize user list
 		 */
 		for (; optind < argc; optind++) {
-			Users = update_user(Users, argv[optind], 0L);
+			update_user(argv[optind], (struct timeval){ 0, 0 });
 		}
 		Flags |= AC_U;			/* freeze user list */
 	}
 	if (Flags & AC_D)
 		Flags &= ~AC_P;
-	if (fp == NULL) {
-		/*
-		 * if _PATH_WTMP does not exist, exit quietly
-		 */
-		if (access(_PATH_WTMP, 0) != 0 && errno == ENOENT)
-			return 0;
+	ac(wtmpf);
 
-		fp = file(_PATH_WTMP);
-	}
-	ac(fp);
-
-	return 0;
+	return (0);
 }
 
 /*
  * print login time in decimal hours
  */
 static void
-show(const char *name, time_t secs)
+show(const char *user, struct timeval secs)
 {
-	printf("\t%-*s %8.2f\n", UT_NAMESIZE, name,
-	    ((double)secs / 3600));
+	printf("\t%-*s %8.2f\n",
+	    (int)sizeof(((struct user_entry *)0)->user), user,
+	    (double)secs.tv_sec / 3600);
 }
 
 static void
-show_users(struct user_list *list)
+show_users(void)
 {
-	struct user_list *lp;
+	struct user_entry *lp;
 
-	for (lp = list; lp; lp = lp->next)
-		show(lp->name, lp->secs);
+	SLIST_FOREACH(lp, &Users, next)
+		show(lp->user, lp->time);
 }
 
 /*
  * print total login time for 24hr period in decimal hours
  */
 static void
-show_today(struct user_list *users, struct utmp_list *logins, time_t secs)
+show_today(struct timeval today)
 {
-	struct user_list *up;
-	struct utmp_list *lp;
+	struct user_entry *up;
+	struct utmpx_entry *lp;
 	char date[64];
-	time_t yesterday = secs - 1;
+	struct timeval diff, total = { 0, 0 }, usec = { 0, 1 }, yesterday;
 	static int d_first = -1;
 
 	if (d_first < 0)
 		d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
+	timersub(&today, &usec, &yesterday);
 	strftime(date, sizeof(date),
 		       d_first ? "%e %b  total" : "%b %e  total",
-		       localtime(&yesterday));
-
-	/* restore the missing second */
-	yesterday++;
+		       localtime(&yesterday.tv_sec));
 
-	for (lp = logins; lp != NULL; lp = lp->next) {
-		secs = yesterday - lp->usr.ut_time;
-		Users = update_user(Users, lp->usr.ut_name, secs);
-		lp->usr.ut_time = yesterday;	/* as if they just logged in */
+	SLIST_FOREACH(lp, &CurUtmpx, next) {
+		timersub(&today, &lp->time, &diff);
+		update_user(lp->user, diff);
+		/* As if they just logged in. */
+		lp->time = today;
 	}
-	secs = 0;
-	for (up = users; up != NULL; up = up->next) {
-		secs += up->secs;
-		up->secs = 0;			/* for next day */
+	SLIST_FOREACH(up, &Users, next) {
+		timeradd(&total, &up->time, &total);
+		/* For next day. */
+		timerclear(&up->time);
 	}
- 	if (secs)
-		printf("%s %11.2f\n", date, ((double)secs / 3600));
+	if (timerisset(&total))
+		printf("%s %11.2f\n", date, (double)total.tv_sec / 3600);
 }
 
 /*
- * log a user out and update their times.
- * if ut_line is "~", we log all users out as the system has
- * been shut down.
+ * Log a user out and update their times.
+ * If ut_type is BOOT_TIME or INIT_PROCESS, we log all users out as the
+ * system has been shut down.
  */
-static struct utmp_list *
-log_out(struct utmp_list *head, struct utmp *up)
+static void
+log_out(const struct utmpx *up)
 {
-	struct utmp_list *lp, *lp2, *tlp;
-	time_t secs;
-
-	for (lp = head, lp2 = NULL; lp != NULL; )
-		if (*up->ut_line == '~' || strncmp(lp->usr.ut_line, up->ut_line,
-		    sizeof(up->ut_line)) == 0) {
-			secs = up->ut_time - lp->usr.ut_time;
-			Users = update_user(Users, lp->usr.ut_name, secs);
-#ifdef DEBUG
-			if (Debug)
-				printf("%-.*s %-.*s: %-.*s logged out (%2d:%02d:%02d)\n",
-				    19, ctime(&up->ut_time),
-				    sizeof(lp->usr.ut_line), lp->usr.ut_line,
-				    sizeof(lp->usr.ut_name), lp->usr.ut_name,
-				    secs / 3600, (secs % 3600) / 60, secs % 60);
-#endif
+	struct utmpx_entry *lp, *lp2, *tlp;
+	struct timeval secs;
+
+	for (lp = SLIST_FIRST(&CurUtmpx), lp2 = NULL; lp != NULL;)
+		if (up->ut_type == BOOT_TIME || up->ut_type == INIT_PROCESS ||
+		    (up->ut_type == DEAD_PROCESS &&
+		    memcmp(lp->id, up->ut_id, sizeof(up->ut_id)) == 0)) {
+			timersub(&up->ut_tv, &lp->time, &secs);
+			update_user(lp->user, secs);
 			/*
 			 * now lose it
 			 */
 			tlp = lp;
-			lp = lp->next;
-			if (tlp == head)
-				head = lp;
-			else if (lp2 != NULL)
-				lp2->next = lp;
+			lp = SLIST_NEXT(lp, next);
+			if (lp2 == NULL)
+				SLIST_REMOVE_HEAD(&CurUtmpx, next);
+			else
+				SLIST_REMOVE_AFTER(lp2, next);
 			free(tlp);
 		} else {
 			lp2 = lp;
-			lp = lp->next;
+			lp = SLIST_NEXT(lp, next);
 		}
-	return head;
 }
 
-
 /*
  * if do_tty says ok, login a user
  */
-static struct utmp_list *
-log_in(struct utmp_list *head, struct utmp *up)
+static void
+log_in(struct utmpx *up)
 {
-	struct utmp_list *lp;
+	struct utmpx_entry *lp;
 
 	/*
 	 * this could be a login. if we're not dealing with
@@ -398,140 +366,147 @@ log_in(struct utmp_list *head, struct utmp *up)
 		 * SunOS 4.0.2 does not treat ":0.0" as special but we
 		 * do.
 		 */
-		if (on_console(head))
-			return head;
+		if (on_console())
+			return;
 		/*
 		 * ok, no recorded login, so they were here when wtmp
 		 * started!  Adjust ut_time!
 		 */
-		up->ut_time = FirstTime;
+		up->ut_tv = FirstTime;
 		/*
 		 * this allows us to pick the right logout
 		 */
-		strncpy(up->ut_line, Console, sizeof(up->ut_line) - 1);
-		up->ut_line[sizeof(up->ut_line) - 1] = '\0'; /* paranoid! */
+		strlcpy(up->ut_line, Console, sizeof(up->ut_line));
 	}
 #endif
 	/*
 	 * If we are doing specified ttys only, we ignore
 	 * anything else.
 	 */
-	if (Flags & AC_T)
-		if (!do_tty(up->ut_line))
-			return head;
+	if (Flags & AC_T && !do_tty(up->ut_line))
+		return;
 
 	/*
 	 * go ahead and log them in
 	 */
-	if ((lp = NEW(struct utmp_list)) == NULL)
+	if ((lp = malloc(sizeof(*lp))) == NULL)
 		errx(1, "malloc failed");
-	lp->next = head;
-	head = lp;
-	memmove((char *)&lp->usr, (char *)up, sizeof(struct utmp));
-#ifdef DEBUG
-	if (Debug) {
-		printf("%-.*s %-.*s: %-.*s logged in", 19,
-		    ctime(&lp->usr.ut_time), sizeof(up->ut_line),
-		       up->ut_line, sizeof(up->ut_name), up->ut_name);
-		if (*up->ut_host)
-			printf(" (%-.*s)", sizeof(up->ut_host), up->ut_host);
-		putchar('\n');
-	}
+	SLIST_INSERT_HEAD(&CurUtmpx, lp, next);
+	strlcpy(lp->user, up->ut_user, sizeof(lp->user));
+	memcpy(lp->id, up->ut_id, sizeof(lp->id));
+#ifdef CONSOLE_TTY
+	memcpy(lp->line, up->ut_line, sizeof(lp->line));
 #endif
-	return head;
+	lp->time = up->ut_tv;
 }
 
-static int
-ac(FILE *fp)
+static void
+ac(const char *file)
 {
-	struct utmp_list *lp, *head = NULL;
-	struct utmp usr;
+	struct utmpx_entry *lp;
+	struct utmpx *usr, usht;
 	struct tm *ltm;
-	time_t secs;
-	int day = -1;
-
-	secs = 0;
-
-	while (fread((char *)&usr, sizeof(usr), 1, fp) == 1) {
-		if (!FirstTime)
-			FirstTime = usr.ut_time;
+	struct timeval prev_secs, ut_timecopy, secs, clock_shift, now;
+	int day, rfound;
+
+	day = -1;
+	timerclear(&prev_secs);	/* Minimum acceptable date == 1970. */
+	timerclear(&secs);
+	timerclear(&clock_shift);
+	rfound = 0;
+	if (setutxdb(UTX_DB_WTMPX, file) != 0)
+		err(1, "%s", file);
+	while ((usr = getutxent()) != NULL) {
+		rfound++;
+		ut_timecopy = usr->ut_tv;
+		/* Don't let the time run backwards. */
+		if (timercmp(&ut_timecopy, &prev_secs, <))
+			ut_timecopy = prev_secs;
+		prev_secs = ut_timecopy;
+
+		if (!timerisset(&FirstTime))
+			FirstTime = ut_timecopy;
 		if (Flags & AC_D) {
-			ltm = localtime(&usr.ut_time);
+			ltm = localtime(&ut_timecopy.tv_sec);
 			if (day >= 0 && day != ltm->tm_yday) {
 				day = ltm->tm_yday;
 				/*
 				 * print yesterday's total
 				 */
-				secs = usr.ut_time;
-				secs -= ltm->tm_sec;
-				secs -= 60 * ltm->tm_min;
-				secs -= 3600 * ltm->tm_hour;
-				show_today(Users, head, secs);
+				secs = ut_timecopy;
+				secs.tv_sec -= ltm->tm_sec;
+				secs.tv_sec -= 60 * ltm->tm_min;
+				secs.tv_sec -= 3600 * ltm->tm_hour;
+				secs.tv_usec = 0;
+				show_today(secs);
 			} else
 				day = ltm->tm_yday;
 		}
-		switch(*usr.ut_line) {
-		case '|':
-			secs = usr.ut_time;
+		switch(usr->ut_type) {
+		case OLD_TIME:
+			clock_shift = ut_timecopy;
 			break;
-		case '{':
-			secs -= usr.ut_time;
+		case NEW_TIME:
+			timersub(&clock_shift, &ut_timecopy, &clock_shift);
 			/*
 			 * adjust time for those logged in
 			 */
-			for (lp = head; lp != NULL; lp = lp->next)
-				lp->usr.ut_time -= secs;
+			SLIST_FOREACH(lp, &CurUtmpx, next)
+				timersub(&lp->time, &clock_shift, &lp->time);
 			break;
-		case '~':			/* reboot or shutdown */
-			head = log_out(head, &usr);
-			FirstTime = usr.ut_time; /* shouldn't be needed */
+		case BOOT_TIME:
+		case INIT_PROCESS:
+			log_out(usr);
+			FirstTime = ut_timecopy; /* shouldn't be needed */
 			break;
-		default:
+		case USER_PROCESS:
 			/*
-			 * if they came in on tty[p-sP-S]*, then it is only
-			 * a login session if the ut_host field is non-empty
+			 * If they came in on pts/..., then it is only
+			 * a login session if the ut_host field is non-empty.
 			 */
-			if (*usr.ut_name) {
-				if (strncmp(usr.ut_line, "tty", 3) != 0 ||
-				    strchr("pqrsPQRS", usr.ut_line[3]) == 0 ||
-				    *usr.ut_host != '\0')
-					head = log_in(head, &usr);
-			} else
-				head = log_out(head, &usr);
+			if (strncmp(usr->ut_line, "pts/", 4) != 0 ||
+			    *usr->ut_host != '\0')
+				log_in(usr);
+			break;
+		case DEAD_PROCESS:
+			log_out(usr);
 			break;
 		}
 	}
-	fclose(fp);
-	if (!(Flags & AC_W))
-		usr.ut_time = time(NULL);
-	strcpy(usr.ut_line, "~");
+	endutxent();
+	gettimeofday(&now, NULL);
+	if (Flags & AC_W)
+		usht.ut_tv = ut_timecopy;
+	else
+		usht.ut_tv = now;
+	usht.ut_type = INIT_PROCESS;
 
 	if (Flags & AC_D) {
-		ltm = localtime(&usr.ut_time);
+		ltm = localtime(&ut_timecopy.tv_sec);
 		if (day >= 0 && day != ltm->tm_yday) {
 			/*
 			 * print yesterday's total
 			 */
-			secs = usr.ut_time;
-			secs -= ltm->tm_sec;
-			secs -= 60 * ltm->tm_min;
-			secs -= 3600 * ltm->tm_hour;
-			show_today(Users, head, secs);
+			secs = ut_timecopy;
+			secs.tv_sec -= ltm->tm_sec;
+			secs.tv_sec -= 60 * ltm->tm_min;
+			secs.tv_sec -= 3600 * ltm->tm_hour;
+			secs.tv_usec = 0;
+			show_today(secs);
 		}
 	}
 	/*
 	 * anyone still logged in gets time up to now
 	 */
-	head = log_out(head, &usr);
+	log_out(&usht);
 
 	if (Flags & AC_D)
-		show_today(Users, head, time(NULL));
+		show_today(now);
 	else {
 		if (Flags & AC_P)
-			show_users(Users);
+			show_users();
 		show("total", Total);
 	}
-	return 0;
 }
 
 static void
diff --git a/usr.sbin/adduser/adduser.8 b/usr.sbin/adduser/adduser.8
index 6ed42ecc13..318fbc9c4d 100644
--- a/usr.sbin/adduser/adduser.8
+++ b/usr.sbin/adduser/adduser.8
@@ -77,14 +77,6 @@ Given that people have traditionally wanted to break this
 limit for aesthetic reasons, it has never been of great importance to break
 such a basic fundamental parameter in
 .Ux .
-You can change
-.Dv UT_NAMESIZE
-in
-.In utmp.h
-and recompile the
-world; people have done this and it works, but you will have problems
-with any precompiled programs, or source that assumes the 8-character
-name limit, such as NIS.
 The NIS protocol mandates an 8-character username.
 If you need a longer login name for e-mail addresses,
 you can define an alias in
diff --git a/usr.sbin/lastlogin/lastlogin.c b/usr.sbin/lastlogin/lastlogin.c
index 729c59b314..9b5bd3d41b 100644
--- a/usr.sbin/lastlogin/lastlogin.c
+++ b/usr.sbin/lastlogin/lastlogin.c
@@ -40,11 +40,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
-#include <utmp.h>
 #include <utmpx.h>
 #include <unistd.h>
 
-static	void	output(struct passwd *, struct lastlog *);
 static	void	outputx(struct passwd *, struct lastlogx *);
 static	void	usage(void);
 
@@ -52,19 +50,13 @@ int
 main(int argc, char **argv)
 {
 	int	ch, i;
-	long offset;
-	FILE	*fp;
 	struct passwd	*passwd;
-	struct lastlog	last;
 	struct lastlogx	lastx;
 
 	while ((ch = getopt(argc, argv, "")) != -1) {
 		usage();
 	}
 
-	if ((fp = fopen(_PATH_LASTLOG, "r")) == NULL)
-		err(1, "%s", _PATH_LASTLOG);
-
 	setpassent(1);	/* Keep passwd file pointers open */
 
 	/* Process usernames given on the command line. */
@@ -79,18 +71,6 @@ main(int argc, char **argv)
 				outputx(passwd, &lastx);
 				goto done;
 			}
-			/* Calculate the offset into the lastlog file. */
-			offset = (long)(passwd->pw_uid * sizeof(last));
-			if (fseek(fp, offset, SEEK_SET)) {
-				warn("fseek error");
-				continue;
-			}
-			if (fread(&last, sizeof(last), 1, fp) != 1) {
-				warnx("fread error on '%s'", passwd->pw_name);
-				clearerr(fp);
-				continue;
-			}
-			output(passwd, &last);
 		}
 	}
 	/* Read all lastlog entries, looking for active ones */
@@ -101,57 +81,21 @@ main(int argc, char **argv)
 				if (lastx.ll_tv.tv_sec == 0)
 					continue;
 				outputx(passwd, &lastx);
-			} else {
-				offset = (long)(passwd->pw_uid * sizeof(last));
-
-				if (fseek(fp, offset, SEEK_SET)) {
-					continue;
-				}
-				if (fread(&last, sizeof(last), 1, fp) != 1) {
-					continue;
-				}
-				if (last.ll_time == 0)
-					continue;
-				output(passwd, &last);
 			}
 		}
-#if 0
-		for (i = 0; fread(&last, sizeof(last), 1, fp) == 1; i++) {
-			if (last.ll_time == 0)
-				continue;
-			if ((passwd = getpwuid((uid_t)i)) != NULL)
-				output(passwd, &last);
-		}
-		if (ferror(fp))
-			warnx("fread error");
-#endif
 	}
 
 done:
 	setpassent(0);	/* Close passwd file pointers */
 
-	fclose(fp);
 	exit(0);
 }
 
-/* Duplicate the output of last(1) */
-static void
-output(struct passwd *p, struct lastlog *l)
-{
-	printf("%-*.*s  %-*.*s %-*.*s   %s",
-		UT_NAMESIZE, UT_NAMESIZE, p->pw_name,
-		UT_LINESIZE+4, UT_LINESIZE+4, l->ll_line,
-		UT_HOSTSIZE, UT_HOSTSIZE, l->ll_host,
-		(l->ll_time) ? ctime(&(l->ll_time)) : "Never logged in\n");
-}
-
 static void
 outputx(struct passwd *p, struct lastlogx *l)
 {
-	printf("%-*.*s  %-*.*s %-*.*s   %s",
-		UT_NAMESIZE, UT_NAMESIZE, p->pw_name,
-		UT_LINESIZE+4, UT_LINESIZE+4, l->ll_line,
-		UT_HOSTSIZE, UT_HOSTSIZE, l->ll_host,
+	printf("%-10s  %-8s %-22.22s   %s",
+		p->pw_name, l->ll_line, l->ll_host,
 		(l->ll_tv.tv_sec) ? ctime((&l->ll_tv.tv_sec)) : "Never logged in\n");
 }
 
diff --git a/usr.sbin/ppp/id.c b/usr.sbin/ppp/id.c
index 154970657d..5a077ecdb3 100644
--- a/usr.sbin/ppp/id.c
+++ b/usr.sbin/ppp/id.c
@@ -24,7 +24,6 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/usr.sbin/ppp/id.c,v 1.18.2.3 2002/09/01 02:12:27 brian Exp $
- * $DragonFly: src/usr.sbin/ppp/id.c,v 1.4 2005/11/24 23:42:54 swildner Exp $
  */
 
 #include <sys/param.h>
@@ -50,7 +49,7 @@
 #else
 #include <libutil.h>
 #endif
-#include <utmp.h>
+#include <utmpx.h>
 
 #include "log.h"
 #include "main.h"
@@ -203,36 +202,25 @@ ID0uu_unlock(const char *basettyname)
 }
 
 void
-ID0login(struct utmp *ut)
+ID0login(const struct utmpx *ut)
 {
   ID0set0();
-  if (logout(ut->ut_line)) {
-    log_Printf(LogID0, "logout(\"%s\")\n", ut->ut_line);
-    logwtmp(ut->ut_line, "", "");
-    log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut->ut_line);
-  }
-  login(ut);
-  log_Printf(LogID0, "login(\"%s\", \"%.*s\")\n",
-            ut->ut_line, (int)(sizeof ut->ut_name), ut->ut_name);
+  pututxline(ut);
+  log_Printf(LogID0, "pututxline(\"%.*s\", \"%.*s\", \"%.*s\", \"%.*s\")\n",
+      (int)sizeof ut->ut_id, ut->ut_id,
+      (int)sizeof ut->ut_user, ut->ut_user,
+      (int)sizeof ut->ut_line, ut->ut_line,
+      (int)sizeof ut->ut_host, ut->ut_host);
   ID0setuser();
 }
 
 void
-ID0logout(const char *device, int nologout)
+ID0logout(const struct utmpx *ut)
 {
-  struct utmp ut;
-  char ut_line[sizeof ut.ut_line + 1];
-
-  strncpy(ut_line, device, sizeof ut_line - 1);
-  ut_line[sizeof ut_line - 1] = '\0';
-
   ID0set0();
-  if (nologout || logout(ut_line)) {
-    log_Printf(LogID0, "logout(\"%s\")\n", ut_line);
-    logwtmp(ut_line, "", "");
-    log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut_line);
-  } else
-    log_Printf(LogERROR, "ID0logout: No longer logged in on %s\n", ut_line);
+  pututxline(ut);
+  log_Printf(LogID0, "pututxline(\"%.*s\")\n",
+      (int)sizeof ut->ut_id, ut->ut_id);
   ID0setuser();
 }
 
diff --git a/usr.sbin/ppp/id.h b/usr.sbin/ppp/id.h
index 9223c118b7..615e588416 100644
--- a/usr.sbin/ppp/id.h
+++ b/usr.sbin/ppp/id.h
@@ -24,11 +24,10 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/usr.sbin/ppp/id.h,v 1.13.2.1 2000/08/19 09:30:03 brian Exp $
- * $DragonFly: src/usr.sbin/ppp/id.h,v 1.3 2004/02/03 07:11:47 dillon Exp $
  */
 
 #ifndef NOSUID
-struct utmp;
+struct utmpx;
 struct sockaddr_un;
 
 extern void ID0init(void);
@@ -42,8 +41,8 @@ extern int ID0write(int, const void *, size_t);
 extern int ID0uu_lock(const char *);
 extern int ID0uu_lock_txfr(const char *, pid_t);
 extern int ID0uu_unlock(const char *);
-extern void ID0login(struct utmp *);
-extern void ID0logout(const char *, int);
+extern void ID0login(const struct utmpx *);
+extern void ID0logout(const struct utmpx *);
 extern int ID0bind_un(int, const struct sockaddr_un *);
 extern int ID0connect_un(int, const struct sockaddr_un *);
 extern int ID0kill(pid_t, int);
@@ -65,20 +64,8 @@ extern int ID0NgMkSockNode(const char *, int *, int *);
 #define ID0uu_lock uu_lock
 #define ID0uu_lock_txfr uu_lock_txfr
 #define ID0uu_unlock uu_unlock
-#define ID0login(u)			\
-  do {					\
-    if (logout((u)->ut_line))		\
-      logwtmp((u)->ut_line, "", "");	\
-    login(u);				\
-  } while (0)
-#define ID0logout(dev, no)				\
-  do {							\
-    struct utmp ut;					\
-    strncpy(ut.ut_line, dev, sizeof ut.ut_line - 1);	\
-    ut.ut_line[sizeof ut.ut_line - 1] = '\0';		\
-    if (no || logout(ut.ut_line))			\
-      logwtmp(ut.ut_line, "", ""); 			\
-  } while (0)
+#define ID0login pututxline
+#define ID0logout pututxline
 #define ID0bind_un(s, n) bind(s, (const struct sockaddr *)(n), sizeof *(n))
 #define ID0connect_un(s, n) \
 	connect(s, (const struct sockaddr *)(n), sizeof *(n))
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index d760123cec..e7973b81e8 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -40,7 +40,7 @@
 #include <termios.h>
 #include <time.h>
 #include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
 #if defined(__OpenBSD__) || defined(__NetBSD__)
 #include <sys/ioctl.h>
 #include <util.h>
@@ -100,8 +100,6 @@
 #endif
 #include "tcpmss.h"
 
-#define PPPOTCPLINE "ppp"
-
 static int physical_DescriptorWrite(struct fdescriptor *, struct bundle *,
                                     const fd_set *);
 
@@ -323,6 +321,7 @@ physical_Close(struct physical *p)
 {
   int newsid;
   char fn[PATH_MAX];
+  struct utmpx ut;
 
   if (p->fd < 0)
     return;
@@ -334,12 +333,11 @@ physical_Close(struct physical *p)
 
   physical_StopDeviceTimer(p);
   if (p->Utmp) {
-    if (p->handler && (p->handler->type == TCP_DEVICE ||
-                       p->handler->type == UDP_DEVICE))
-      /* Careful - we logged in on line ``ppp'' with IP as our host */
-      ID0logout(PPPOTCPLINE, 1);
-    else
-      ID0logout(p->name.base, 0);
+    memset(&ut, 0, sizeof ut);
+    ut.ut_type = DEAD_PROCESS;
+    gettimeofday(&ut.ut_tv, NULL);
+    snprintf(ut.ut_id, sizeof ut.ut_id, "%xppp", (int)getpid());
+    ID0logout(&ut);
     p->Utmp = 0;
   }
   newsid = tcgetpgrp(p->fd) == getpgrp();
@@ -894,16 +892,17 @@ void
 physical_Login(struct physical *p, const char *name)
 {
   if (p->type == PHYS_DIRECT && *p->name.base && !p->Utmp) {
-    struct utmp ut;
+    struct utmpx ut;
     const char *connstr;
     char *colon;
 
     memset(&ut, 0, sizeof ut);
-    time(&ut.ut_time);
-    strncpy(ut.ut_name, name, sizeof ut.ut_name);
+    ut.ut_type = USER_PROCESS;
+    gettimeofday(&ut.ut_tv, NULL);
+    snprintf(ut.ut_id, sizeof ut.ut_id, "%xppp", (int)getpid());
+    strncpy(ut.ut_user, name, sizeof ut.ut_user);
     if (p->handler && (p->handler->type == TCP_DEVICE ||
                        p->handler->type == UDP_DEVICE)) {
-      strncpy(ut.ut_line, PPPOTCPLINE, sizeof ut.ut_line);
       strncpy(ut.ut_host, p->name.base, sizeof ut.ut_host);
       colon = memchr(ut.ut_host, ':', sizeof ut.ut_host);
       if (colon)
@@ -914,7 +913,7 @@ physical_Login(struct physical *p, const char *name)
       /* mgetty sets this to the connection speed */
       strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
     ID0login(&ut);
-    p->Utmp = ut.ut_time;
+    p->Utmp = 1;
   }
 }
 
diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c
index c503e9ebe4..dd4a3be23c 100644
--- a/usr.sbin/rwhod/rwhod.c
+++ b/usr.sbin/rwhod/rwhod.c
@@ -57,8 +57,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <timeconv.h>
 #include <unistd.h>
-#include <utmp.h>
+#include <utmpx.h>
 #include <pwd.h>
 #include <grp.h>
 
@@ -132,7 +133,7 @@ struct	neighbor {
 static struct	neighbor *neighbors;
 static struct	whod mywd;
 static struct	servent *sp;
-static int	s, utmpf;
+static int	s;
 static volatile sig_atomic_t	onsighup;
 
 #define	WHDRSIZE	(sizeof(mywd) - sizeof(mywd.wd_we))
@@ -249,10 +250,6 @@ main(int argc, char *argv[])
 	if ((cp = strchr(myname, '.')) != NULL)
 		*cp = '\0';
 	strlcpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname));
-	utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
-	if (utmpf < 0)
-		quit(_PATH_UTMP, WITH_ERRNO);
-
 	getboottime();
 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 		quit("socket", WITH_ERRNO);
@@ -437,73 +434,44 @@ verify(char *name, int maxlen)
 	return (size > 0);
 }
 
-static int	utmptime;
-static int	utmpent;
-static int	utmpsize;
-static struct	utmp *utmp;
-static int	alarmcount;
-
 static void
 send_host_information(void)
 {
 	struct neighbor *np;
-	struct whoent *we = mywd.wd_we, *wlast;
-	int i;
+	struct whoent *we = mywd.wd_we, *wend;
 	struct stat stb;
+	struct utmpx *ut;
+	static int alarmcount = 0;
 	double avenrun[3];
 	time_t now;
-	int cc;
+	int i, cc;
 
 	now = time(NULL);
 	if (alarmcount % 10 == 0)
 		getboottime();
 	alarmcount++;
-	fstat(utmpf, &stb);
-	if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) {
-		utmptime = stb.st_mtime;
-		if (stb.st_size > utmpsize) {
-			utmpsize = stb.st_size + 10 * sizeof(struct utmp);
-			utmp = reallocf(utmp, utmpsize);
-			if (utmp == NULL) {
-				syslog(LOG_WARNING, "malloc failed: %m");
-				utmpsize = 0;
-				return;
-			}
-		}
-		lseek(utmpf, (off_t)0, L_SET);
-		cc = read(utmpf, (char *)utmp, stb.st_size);
-		if (cc < 0) {
-			syslog(LOG_ERR, "read(%s): %m", _PATH_UTMP);
-			return;
-		}
-		wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
-		utmpent = cc / sizeof(struct utmp);
-		for (i = 0; i < utmpent; i++)
-			if (utmp[i].ut_name[0]) {
-				memcpy(we->we_utmp.out_line, utmp[i].ut_line,
-				   sizeof(utmp[i].ut_line));
-				memcpy(we->we_utmp.out_name, utmp[i].ut_name,
-				   sizeof(utmp[i].ut_name));
-				we->we_utmp.out_time = htonl(utmp[i].ut_time);
-				if (we >= wlast)
-					break;
-				we++;
-			}
-		utmpent = we - mywd.wd_we;
+	wend = &mywd.wd_we[1024 / sizeof(struct whoent)];
+	setutxent();
+	while ((ut = getutxent()) != NULL && we < wend) {
+		if (ut->ut_type != USER_PROCESS)
+			continue;
+		strncpy(we->we_utmp.out_line, ut->ut_line,
+		   sizeof(we->we_utmp.out_line));
+		strncpy(we->we_utmp.out_name, ut->ut_user,
+		   sizeof(we->we_utmp.out_name));
+		we->we_utmp.out_time =
+		    htonl(_time_to_time32(ut->ut_tv.tv_sec));
+		we++;
 	}
+	endutxent();
 
-	/*
-	 * The test on utmpent looks silly---after all, if no one is
-	 * logged on, why worry about efficiency?---but is useful on
-	 * (e.g.) compute servers.
-	 */
-	if (utmpent && chdir(_PATH_DEV)) {
+	if (chdir(_PATH_DEV)) {
 		syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
 		exit(1);
 	}
 
-	we = mywd.wd_we;
-	for (i = 0; i < utmpent; i++) {
+	wend = we;
+	for (we = mywd.wd_we; we < wend; we++) {
 		if (stat(we->we_utmp.out_line, &stb) >= 0)
 			we->we_idle = htonl(now - stb.st_atime);
 		we++;
@@ -511,7 +479,7 @@ send_host_information(void)
 	getloadavg(avenrun, NELEM(avenrun));
 	for (i = 0; i < 3; i++)
 		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
-	cc = (char *)we - (char *)&mywd;
+	cc = (char *)wend - (char *)&mywd;
 	mywd.wd_sendtime = htonl(time(0));
 	mywd.wd_vers = WHODVERSION;
 	mywd.wd_type = WHODTYPE_STATUS;
@@ -537,7 +505,7 @@ send_host_information(void)
 		} else Sendto(s, (char *)&mywd, cc, 0,
 				np->n_addr, np->n_addrlen);
 	}
-	if (utmpent && chdir(_PATH_RWHODIR)) {
+	if (chdir(_PATH_RWHODIR)) {
 		syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
 		exit(1);
 	}
diff --git a/usr.sbin/sshd/Makefile b/usr.sbin/sshd/Makefile
index aab7177fdb..f342e6db1b 100644
--- a/usr.sbin/sshd/Makefile
+++ b/usr.sbin/sshd/Makefile
@@ -18,8 +18,8 @@ SRCS+=	auth.c auth-options.c auth-pam.c auth-passwd.c auth-rhosts.c \
 # Custom password routine
 SRCS+=	auth-passwd-custom.c
 CFLAGS+= -DCUSTOM_SYS_AUTH_PASSWD
-CFLAGS+= -DUSE_UTMPX -DUSE_WTMPX
 CFLAGS+= -DWTMPX_FILE=_PATH_WTMPX -DUTMPX_FILE=_PATH_UTMPX
+CFLAGS+= -DUTXDB_LASTLOGIN=UTX_DB_LASTLOGX
 
 WARNS?=	3
 
-- 
2.22.0

