about summary refs log tree commit diff
path: root/login
diff options
context:
space:
mode:
Diffstat (limited to 'login')
-rw-r--r--login/README.utmpd175
-rw-r--r--login/programs/connection.c180
-rw-r--r--login/programs/database.c543
-rw-r--r--login/programs/error.c104
-rw-r--r--login/programs/request.c646
-rw-r--r--login/programs/xtmp.c121
-rw-r--r--login/programs/xtmp.h55
7 files changed, 0 insertions, 1824 deletions
diff --git a/login/README.utmpd b/login/README.utmpd
deleted file mode 100644
index b691c36f27..0000000000
--- a/login/README.utmpd
+++ /dev/null
@@ -1,175 +0,0 @@
-With the introduction of version 2 of the GNU C Library the format of
-the UTMP and WTMP files changed for some configurations (see Q&A `Why
-does getlogin() always return NULL on my Linux box?' of the FAQ).
-This version of the GNU C Library contains a solution for the problems
-this may cause, by providing an UTMP daemon `utmpd'.
-
-Do I need it?
-=============
-
-If your configuration is one of the following:
-
-                i[3456]86-*-linux-gnu    Linux-2.0 on Intel
-                m68k-*-linux-gnu         Linux-2.0 on Motorola 680x0
-
-you might need it, so please read on.  If it is not, please read the
-section titled `Programming' at the end of this text.
-
-In principle, you only need the daemon if you want to keep using old
-programs linked against the previous version of the Linux C Library
-(libc5).  In addition you will need the daemon if you are running
-Linux on Intel, and you are planning to use iBCS (Intel Binary
-Compatibility Standard).  If you have no libc5 programs left on your
-system and you are not using iBCS, it is probably better not to
-install the daemon since it uses (a small amount of) memory and CPU
-time.  But apart from that it shouldn't hurt to install `utmpd', so
-when in doubt install it anyway.
-
-
-Installation
-============
-
-The installation process (`make install') already places the `utmpd'
-binary in $(sbindir).  The only thing you have to do is modifying your
-startup scripts to start the daemon.  Unfortunately this is a bit of a
-hassle, since the layout of these scripts is not standardized.  You
-should try to find the command that creates the file `/var/run/utmp'.
-This is usually done in a script named `/etc/rc', `/etc/init.d/boot'
-(Debian) or `/etc/rc.d/rc.S' (Slackware).  You could try:
-
-     grep utmp /etc/* /etc/init.d/* /etc/rc.d/*
-
-to find the right script.  The creation of `/var/run/utmp' is usually
-done with a command like:
-
-     : > /var/run/utmp
-
-or
-
-     cat /dev/null > /var/run/utmp
-
-Now add a line before this command to create the file `/var/run/utmpx'
-e.g.
-
-     : > /var/run/utmpx
-
-or
-
-     cat /dev/null > /var/run/utmpx
-
-whatever you prefer, and after this command, add a line to start the
-daemon
-
-     utmpd
-
-The entire fragment could look something like
-
-     # Clean up /var/run and create /var/run/utmp so that we can login.
-     ( cd /var/run && find . ! -type d -exec rm -f -- {} \; )
-     : > /var/run/utmpx
-     : > /var/run/utmp
-     utmpd
-
-If the file `/var/log/wtmp' exists on your system, you will probably
-want to create the file `/var/log/wtmpx'.  Programs linked against the
-GNU C Library will now write to `/var/log/wtmpx', while programs
-linked against the old library will continue to write to
-`/var/log/wtmp'.  Of course this means that the information gets
-spread over two files.  We hope to provide a better solution in the
-future.
-
-After a reboot, user accounting should be working again.  If not,
-please refer to the section titled `Troubleshooting' below before
-submitting a bug report.
-
-
-What is `utmpd' doing?
-======================
-
-After installation there will be two files that store the user
-accounting information: `/var/run/utmp' and `/var/run/utmpx'.  The
-file `/var/run/utmp' will be in the old format so libc5 programs will
-continue to work (even if they are broken and do not use the library
-functions to access the user accounting database).  And on Intel, you
-can safely link `/var/run/utmp' to `/etc/utmp' for iBCS programs.
-Programs linked against the new GNU C Library (glibc2) will contact
-the daemon for all user accounting database access.  The daemon will
-store its information in `/var/run/utmpx' and keeps this file in sync
-with `/var/run/utmp'.  Entries added to `/var/run/utmpx' will be
-converted to the old format and will be added to `/var/run/utmp' and
-vice versa.  This way both libc5 and glibc2 see the same information
-in the same fields of `struct utmp'. Of course libc5 programs see only
-part of the information that glibc2 programs see because not all
-members of the glibc2 `struct utmp' are present in the libc5 `struct
-utmp'.  For the same reason libc5 will see a truncated version of
-those fields where the length of the glibc2 field is larger than the
-corresponding libc5 field (ut_user, ut_line, ut_host).
-
-
-Troubleshooting
-===============
-
-If user accounting is not working on your system, e.g. programs like
-`who' or `logname' return rubbish, or you cannot login, make
-sure that:
-
-*  The file `/var/run/utmpx' exists.
-
-*  The file `/var/log/wtmpx' exists.
-
-*  No program linked against the GNU C Library (libc6) is accessing
-   `/var/run/utmp' directly (see the section on `Programming' below).
-
-If that does not solve your problems, please use the `glibcbug' script
-to report the problem to <bugs@gnu.org>.
-
-The `utmpd' daemon uses `syslogd' to report problems.  It uses the
-`daemon' facility and `warning' and `error' levels.  Alternatively you
-could use the following option to ease debugging:
-
-`--debug'
-    Use this option if you want the daemon to output its warnings and
-    error messages to the terminal instead of sending them to the
-    system logger (`syslogd').  When using this option the daemon does
-    not auto-background itself.
-
-To use this option you should first kill the daemon that is already
-running, and start a fresh one with the desired option:
-
-    kill `cat /var/run/utmpd.pid`
-    utmpd --debug
-
-Please include any warnings or error messages from `utmpd' in your
-bug reports.
-
-
-Programming
-===========
-
-In order for the `utmpd' approach to work it is essential that NO
-program EVER accesses the UTMP and WTMP files directly.  Instead, a
-program should use ONLY the available library functions:
-
-     * utmpname()	Select the database used (UTMP, WTMP, ...).
-     * setutent()	Open the database.
-     * getutent()	Read the next entry from the database.
-     * getutid()	Search for the next entry with a specific ID.
-     * getutline()	Search for the next entry for a specific line.
-     * pututline()	Write an entry to the database.
-     * endutent()	Close the database.
-     * updwtmp()	Add an entry to a database (WTMP, ...).
-
-For details, please refer to `The GNU C Library Reference Manual',
-which also contains information about some additional functions
-derived from BSD and XPG that may be of interest.  The command
-
-    info libc "User Accounting Database"
-
-should point you at the right location.
-
-If you encounter a program that reads from or, even worse, writes to
-the UTMP and WTMP files directly, please report this as a bug to the
-author of that program.  Note that the files referred to by the macros
-`_PATH_UTMP' and `_PATH_WTMP' might even disappear in the future, so
-please do not use these, except in a call to `utmpname()' or
-`updwtmp()', not even to check their existence.
diff --git a/login/programs/connection.c b/login/programs/connection.c
deleted file mode 100644
index 4e1663189d..0000000000
--- a/login/programs/connection.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "utmpd-private.h"
-
-
-/* Prototypes for the local functions.  */
-static client_connection *alloc_connection (void);
-static void free_connection (client_connection *connection);
-static int set_nonblock_flag (int desc, int value);
-
-
-/* The head of the connection list.  */
-static client_connection *connection_list = NULL;
-
-
-/* Accept connection on SOCK, with access permissions given by ACCESS.
-   Returns a pointer to a newly allocated client_connection if
-   successful, NULL if not.  */
-client_connection *
-accept_connection (int sock, int access)
-{
-  client_connection *connection;
-
-  connection = alloc_connection ();
-  if (connection == NULL)
-    return NULL;
-
-  connection->sock = accept (sock, NULL, NULL);
-  connection->access = access;
-  if (connection->sock < 0)
-    {
-      free_connection (connection);
-      return NULL;
-    }
-  
-  if (set_nonblock_flag (connection->sock, 1) < 0)
-    {
-      close_connection (connection);
-      return NULL;
-    }
-
-  return connection;  
-}
-
-
-/* Close CONNECTION.  */
-void
-close_connection (client_connection *connection)
-{
-  close (connection->sock);
-  free_connection (connection);
-}
-
-
-/* Return the connection for SOCK.  */
-client_connection *
-find_connection (int sock)
-{
-  client_connection *connection;
-
-  for (connection = connection_list; connection;
-       connection = connection->next)
-    {
-      if (connection->sock == sock)
-	return connection;
-    }
-
-  return NULL;
-}
-
-
-static client_connection *
-alloc_connection (void)
-{
-  client_connection *connection;
-  size_t read_bufsize = 1024;
-  size_t write_bufsize = 1024;
-
-  connection = (client_connection *)malloc (sizeof (client_connection));
-  if (connection == NULL)
-    return NULL;
-
-  memset (connection, 0, sizeof (client_connection));
-
-  /* Allocate read buffer.  */
-  connection->read_base = malloc (read_bufsize);
-  connection->read_ptr = connection->read_base;
-  connection->read_end = connection->read_base + read_bufsize;
-  if (connection->read_base == NULL)
-    {
-      free (connection);
-      return NULL;
-    }
-
-  /* Allocate write buffer.  */
-  connection->write_base = malloc (write_bufsize);
-  connection->write_ptr = connection->write_base;
-  connection->write_end = connection->write_base + write_bufsize;
-  if (connection->write_base == NULL)
-    {
-      free (connection->read_base);
-      free (connection);
-      return NULL;
-    }
-
-  /* Link connection.  */
-  connection->next = connection_list;
-  connection_list = connection;
-  if (connection->next)
-    connection->next->prev = connection;
-  
-  return connection;
-}
-
-
-static void
-free_connection (client_connection *connection)
-{
-  /* Unlink connection.  */
-  if (connection->next)
-    connection->next->prev = connection->prev;
-  if (connection->prev)
-    connection->prev->next = connection->next;
-
-  /* Take care of the head of the list.  */
-  if (connection == connection_list)
-    connection_list = connection->next;
-  
-  /* Free buffers.  */
-  if (connection->read_base)
-    free (connection->read_base);
-  if (connection->write_base)
-    free (connection->write_base);
-
-  free (connection);
-}
-
-
-/* Set the `O_NONBLOCK' flag of DESC if VALUE is nonzero,
-   or clear the flag if VALUE is 0.
-   Return 0 on success, or -1 on error with `errno' set. */
-static int
-set_nonblock_flag (int desc, int value)
-{
-  int oldflags = fcntl (desc, F_GETFL, 0);
-  /* If reading the flags failed, return error indication now. */
-  if (oldflags == -1)
-    return -1;
-  /* Set just the flag we want to set. */
-  if (value != 0)
-    oldflags |= O_NONBLOCK;
-  else
-    oldflags &= ~O_NONBLOCK;
-  /* Store modified flag word in the descriptor. */
-  return fcntl (desc, F_SETFL, oldflags);
-}
diff --git a/login/programs/database.c b/login/programs/database.c
deleted file mode 100644
index 4267c11186..0000000000
--- a/login/programs/database.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-#include <utmp.h>
-#include <libintl.h>
-
-
-#include "utmpd-private.h"
-#include "xtmp.h"
-
-
-/* Prototypes for the local functions.  */
-static int initialize_database (utmp_database *database);
-static int store_state_entry (utmp_database *database, int old_position,
-			      const struct utmp *old_entry);
-static int store_process_entry (utmp_database *database, int old_position,
-				const struct utmp *old_entry);
-static int replace_entry (utmp_database *database, int old_position,
-			  int new_position, const struct utmp *entry);
-static int store_entry (utmp_database *database, int position,
-			const struct utmp *entry);
-static int get_mtime (int filedes, time_t *timer);
-
-
-/* Open the database specified by FILE and merge it with the contents
-   of the old format file specified by OLD_FILE.  Returns a pointer to
-   a newly allocated structure describing the database, or NULL on
-   error.  */
-utmp_database *
-open_database (const char *file, const char *old_file)
-{
-  mode_t mode =  S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
-  utmp_database *database;
-
-  /* Allocate memory.  */
-  database = (utmp_database *) malloc (sizeof (utmp_database));
-  if (database == NULL)
-    {
-      error (0, 0, _("memory exhausted"));
-      return NULL;
-    }
-
-  memset (database, 0, sizeof (utmp_database));
-
-  /* Open database, create it if it doesn't exist already.  */
-  database->fd = open (file, O_RDWR | O_CREAT, mode);
-  if (database->fd < 0)
-    {
-      error (0, errno, "%s", file);
-      goto return_error;
-    }
-
-  database->file = strdup (file);
-  if (database->file == NULL)
-    {
-      error (0, 0, _("memory exhausted"));
-      goto return_error;
-    }
-
-  if (old_file)
-    {
-      database->old_fd = open (old_file, O_RDWR|O_CREAT, mode);
-      if (database->old_fd < 0)
-	{
-	  error (0, errno, "%s", old_file);
-	  goto return_error;
-	}
-
-      database->old_file = strdup (old_file);
-      if (database->old_file == NULL)
-	{
-	  error (0, 0, _("memory exhausted"));
-	  goto return_error;
-	}
-    }
-
-  /* Initialize database.  */
-  if (initialize_database (database) < 0)
-    goto return_error;
-
-  return database;
-
-return_error:
-  close_database (database);
-
-  return NULL;
-}
-
-/* Synchronize DATABASE.  */
-int
-synchronize_database (utmp_database *database)
-{
-  assert (database);
-
-  /* Check if there is a file in the old format, that we have to
-     synchronize with.  */
-  if (database->old_file)
-    {
-      time_t curtime;
-      time_t mtime;
-
-      curtime = time (NULL);
-
-      if (get_mtime (database->old_fd, &mtime) < 0)
-	{
-	  error (0, errno, _("%s: cannot get modification time"),
-		 database->old_file);
-	  return -1;
-	}
-
-      if (mtime >= database->mtime)
-	{
-	  int position = 0;
-	  struct utmp entry;
-	  struct utmp old_entry;
-
-	  while (1)
-	    {
-	      if (read_old_entry (database, position, &old_entry) < 0)
-		break;
-
-	      if (read_entry (database, position, &entry) < 0
-		  || !compare_entry (&old_entry, &entry))
-		{
-		  if (write_entry (database, position, &old_entry) < 0)
-		    {
-		      error (0, errno, "%s", database->file);
-		      return -1;
-		    }
-		}
-
-	      position++;
-	    }
-
-	  database->mtime = curtime;
-	}
-
-    }
-
-  return 0;
-}
-
-
-/* Close DATABASE.  */
-void
-close_database (utmp_database *database)
-{
-  assert (database);
-
-  if (database->fd >= 0)
-    close (database->fd);
-
-  if (database->old_fd >= 0)
-    close (database->old_fd);
-
-  /* Free allocated memory.  */
-  if (database->file)
-    free (database->file);
-  if (database->old_file)
-    free (database->old_file);
-  free (database);
-}
-
-
-/* Read the entry at POSITION in DATABASE and store the result in
-   ENTRY.  Returns 0 if successful, -1 if not.  */
-int
-read_entry (utmp_database *database, int position, struct utmp *entry)
-{
-  ssize_t nbytes;
-  off_t offset;
-
-  offset = position * sizeof (struct utmp);
-  if (lseek (database->fd, offset, SEEK_SET) < 0)
-    return -1;
-
-  nbytes = read (database->fd, entry, sizeof (struct utmp));
-  if (nbytes != sizeof (struct utmp))
-    return -1;
-
-  return 0;
-}
-
-
-/* Write ENTRY at POSITION in DATABASE.  Returns 0 if successful, -1
-   on error.  */
-int
-write_entry (utmp_database *database, int position,
-	     const struct utmp *entry)
-{
-  int result = -1;
-  struct flock fl;
-  ssize_t nbytes;
-  off_t offset;
-
-  /* Try to lock the file.  */
-  memset (&fl, 0, sizeof (struct flock));
-  fl.l_type = F_WRLCK;
-  fl.l_whence = SEEK_SET;
-  fcntl (database->fd, F_SETLKW, &fl);
-
-  offset = position * sizeof (struct utmp);
-  if (lseek (database->fd, offset, SEEK_SET) < 0)
-    goto fail;
-
-  nbytes = write (database->fd, entry, sizeof (struct utmp));
-  if (nbytes != sizeof (struct utmp))
-    {
-      ftruncate (database->fd, offset);
-      goto fail;
-    }
-
-  result = 0;
-
-fail:
-  /* And unlock the file.  */
-  fl.l_type = F_UNLCK;
-  fcntl (database->fd, F_SETLKW, &fl);
-
-  return result;
-}
-
-
-/* Append ENTRY to DATABASE.  Returns the position of the appended
-   entry if successful, or -1 on error.  */
-int
-append_entry (utmp_database *database, const struct utmp *entry)
-{
-  int result = -1;
-  struct flock fl;
-  ssize_t nbytes;
-  off_t offset;
-
-  /* Try to lock the file.  */
-  memset (&fl, 0, sizeof (struct flock));
-  fl.l_type = F_WRLCK;
-  fl.l_whence = SEEK_SET;
-  fcntl (database->fd, F_SETLKW, &fl);
-
-  offset = lseek (database->fd, 0, SEEK_END);
-  if (offset % sizeof (struct utmp) != 0)
-    {
-      offset -= offset % sizeof (struct utmp);
-      ftruncate (database->fd, offset);
-
-      if (lseek (database->fd, 0, SEEK_END) < 0)
-	goto fail;
-    }
-
-  nbytes = write (database->fd, entry, sizeof (struct utmp));
-  if (nbytes != sizeof (struct utmp))
-    {
-      ftruncate (database->fd, offset);
-      goto fail;
-    }
-
-  result = offset / sizeof (struct utmp);
-
-fail:
-  /* And unlock the file.  */
-  fl.l_type = F_UNLCK;
-  fcntl (database->fd, F_SETLKW, &fl);
-
-  return result;
-}
-
-
-int
-read_old_entry (utmp_database *database, int position,
-		struct utmp *entry)
-{
-  struct xtmp old_entry;
-  ssize_t nbytes;
-  off_t offset;
-
-  offset = position * sizeof (struct xtmp);
-  if (lseek (database->old_fd, offset, SEEK_SET) < 0)
-    return -1;
-
-  nbytes = read (database->old_fd, &old_entry, sizeof (struct xtmp));
-  if (nbytes != sizeof (struct xtmp))
-    return -1;
-
-  xtmp_to_utmp (&old_entry, entry);
-  return 0;
-}
-
-
-int
-write_old_entry (utmp_database *database, int position,
-		 const struct utmp *entry)
-{
-  struct xtmp old_entry;
-  ssize_t nbytes;
-  off_t offset;
-
-  utmp_to_xtmp (entry, &old_entry);
-
-  offset = position * sizeof (struct xtmp);
-  if (lseek (database->old_fd, offset, SEEK_SET) < 0)
-    return -1;
-
-  nbytes = write (database->old_fd, &old_entry, sizeof (struct xtmp));
-  if (nbytes != sizeof (struct xtmp))
-    return -1;
-
-  return 0;
-}
-
-
-/* Initialize DATABASE.  */
-static int
-initialize_database (utmp_database *database)
-{
-  struct utmp entry;
-  int position = 0;
-
-  assert (database);
-
-  /* Check if there is a file in the old format to read.  */
-  if (database->old_file)
-    {
-      while (1)
-	{
-	  if (read_old_entry (database, position, &entry) < 0)
-	    break;
-
-#if _HAVE_UT_TYPE - 0
-	  /* If the login type is one of RUN_LVL, BOOT_TIME, OLD_TIME or
-	     NEW_TIME, search for an entry of the same type in the
-	     database, and replace it if the entry in the file is newer.  */
-	  if (entry.ut_type == RUN_LVL || entry.ut_type == BOOT_TIME
-	      || entry.ut_type == OLD_TIME || entry.ut_type == NEW_TIME)
-	    {
-	      if (store_state_entry (database, position, &entry) < 0)
-		{
-		  error (0, errno, "%s", database->file);
-		  return -1;
-		}
-	    }
-	  else
-#endif
-	    {
-	      if (store_process_entry (database, position, &entry) < 0)
-		{
-		  error (0, errno, "%s", database->file);
-		  return -1;
-		}
-	    }
-
-	  /* Update position.  */
-	  position++;
-	}
-
-      while (1)
-	{
-	  if (read_entry (database, position, &entry) < 0)
-	    break;
-
-	  if (write_old_entry (database, position, &entry) < 0)
-	    {
-	      error (0, errno, "%s", database->file);
-	      return -1;
-	    }
-
-	  /* Update position.  */
-	  position++;
-	}
-    }
-
-  return synchronize_database (database);
-}
-
-
-#if _HAVE_UT_TYPE - 0
-static int
-store_state_entry (utmp_database *database, int old_position,
-		   const struct utmp *old_entry)
-{
-  struct utmp new_entry;
-  int new_position = 0;
-  int found = 0;
-
-  assert (old_entry->ut_type == RUN_LVL
-	  || old_entry->ut_type == BOOT_TIME
-	  || old_entry->ut_type == OLD_TIME
-	  || old_entry->ut_type == NEW_TIME);
-
-  while (!found)
-    {
-      /* Read the next entry.  */
-      if (read_entry (database, new_position, &new_entry) < 0)
-	break;
-
-      if (old_entry->ut_type == new_entry.ut_type)
-	{
-	  found = 1;
-	  continue;
-	}
-
-      /* Update position.  */
-      new_position++;
-    }
-
-  if (found)
-    {
-      const struct utmp *entry;
-
-      if (
-#if _HAVE_UT_TV - 0
-	  old_entry->ut_tv.tv_sec > new_entry.ut_tv.tv_sec
-#else
-	  old_entry->ut_time > new_entry.ut_time
-#endif
-	  )
-	entry = old_entry;
-      else
-	entry = &new_entry;
-
-      return replace_entry (database, old_position, new_position, entry);
-    }
-
-  return store_entry (database, old_position, old_entry);
-}
-#endif
-
-
-static int
-store_process_entry (utmp_database *database, int old_position,
-		     const struct utmp *old_entry)
-{
-  struct utmp new_entry;
-  int new_position = 0;
-  int found = 0;
-
-  while (!found)
-    {
-      /* Read the next entry.  */
-      if (read_entry (database, new_position, &new_entry) < 0)
-	break;
-
-      if (proc_utmp_eq (old_entry, &new_entry))
-	{
-	  found = 1;
-	  continue;
-	}
-
-      /* Update position.  */
-      new_position++;
-    }
-
-  if (found)
-    {
-      const struct utmp *entry;
-
-      if (
-#if _HAVE_UT_TV - 0
-	  old_entry->ut_tv.tv_sec > new_entry.ut_tv.tv_sec
-#else
-	  old_entry->ut_time > new_entry.ut_time
-#endif
-	  )
-	entry = old_entry;
-      else
-	entry = &new_entry;
-
-      return replace_entry (database, old_position, new_position, entry);
-    }
-
-  return store_entry (database, old_position, old_entry);
-}
-
-
-static int
-replace_entry (utmp_database *database, int old_position, int new_position,
-	       const struct utmp *entry)
-{
-  struct utmp tmp;
-
-  if (read_entry (database, old_position, &tmp) < 0
-      || write_entry (database, old_position, entry) < 0
-      || write_entry (database, new_position, &tmp) < 0)
-    return -1;
-
-  return 0;
-}
-
-
-static int
-store_entry (utmp_database *database, int position,
-	     const struct utmp *entry)
-{
-  struct utmp tmp;
-
-  if (read_entry (database, position, &tmp) < 0)
-    return write_entry (database, position, entry);
-
-  if (write_entry (database, position, entry) < 0
-      || append_entry (database, &tmp) < 0)
-    return -1;
-
-  return 0;
-}
-
-
-/* Get modification time of the file with file descriptor FILEDES and
-   put it in TIMER.  Returns 0 if successful, -1 if not.  */
-static int
-get_mtime (int filedes, time_t *timer)
-{
-  struct stat st;
-
-  if (fstat (filedes, &st) < 0)
-    return -1;
-
-  *timer = st.st_mtime;
-
-  return 0;
-}
diff --git a/login/programs/error.c b/login/programs/error.c
deleted file mode 100644
index e6511442e3..0000000000
--- a/login/programs/error.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "utmpd-private.h"
-
-
-/* This variable indicates if we have forked.  If set, we log messages
-   via the system logger.  Otherwise we simply print the program name
-   and the message to standard error.  */
-int forked = 0;
-
-
-/* Log error message MESSAGE, which is a printf-style format string
-   with optional args.
-   If ERRNUM is nonzero, also log its corresponding system error message.
-   Exit with status STATUS if it is nonzero.  */
-void
-error (int status, int errnum, const char *message, ...)
-{
-  va_list ap;
-  char *buffer = NULL;
-
-  va_start (ap, message);
-  vasprintf (&buffer, message, ap);
-  va_end (ap);
-
-  if (forked)
-    {
-      if (errnum == 0)
-	syslog (LOG_ERR, "%s", buffer);
-      else
-	syslog (LOG_ERR, "%s: %s", buffer, strerror (errnum));
-    }
-  else
-    {
-      if (errnum == 0)
-	fprintf (stderr, "%s: %s\n", program_invocation_name, buffer);
-      else
-	fprintf (stderr, "%s: %s: %s\n", program_invocation_name, buffer,
-		 strerror (errnum));
-    }
-
-  if (buffer)
-    free (buffer);
-
-  if (status)
-    exit (status);
-}
-
-/* Log warning message MESSAGE, which is a printf-style format string
-   with optional args.
-   If ERRNUM is nonzero, also log its corresponding system error message. */
-void
-warning (int errnum, const char *message, ...)
-{
-  va_list ap;
-  char *buffer = NULL;
-
-  va_start (ap, message);
-  vasprintf (&buffer, message, ap);
-  va_end (ap);
-
-  if (forked)
-    {
-      if (errnum == 0)
-	syslog (LOG_WARNING, "%s", buffer);
-      else
-	syslog (LOG_WARNING, "%s: %s", buffer, strerror (errnum));
-    }
-  else
-    {
-      if (errnum == 0)
-	printf ("%s: %s\n", program_invocation_name, buffer);
-      else
-	printf ("%s: %s: %s\n", program_invocation_name, buffer,
-		strerror (errnum));
-    }
-
-  if (buffer)
-    free (buffer);
-}
diff --git a/login/programs/request.c b/login/programs/request.c
deleted file mode 100644
index 33f5524c32..0000000000
--- a/login/programs/request.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <utmp.h>
-#include <libintl.h>
-
-#include "utmpd.h"
-#include "utmpd-private.h"
-
-
-/* Prototypes for the local functions.  */
-static int process_request (client_connection *connection);
-static int send_reply (client_connection *connect, const reply_header *reply);
-
-static int do_setutent (client_connection *connection);
-static int do_getutent (client_connection *connection);
-static int do_endutent (client_connection *connection);
-static int do_getutline (client_connection *connection);
-static int do_getutid (client_connection *connection);
-static int do_pututline (client_connection *connection);
-static int do_updwtmp (client_connection *connection);
-
-static int internal_getut_r (client_connection *connection,
-			     const struct utmp *id, struct utmp *buffer);
-
-
-/* Read data from the client on CONNECTION.  */
-int
-read_data (client_connection *connection)
-{
-  ssize_t nbytes;
-
-  assert (connection);
-  assert ((connection->read_end - connection->read_ptr) > 0);
-
-  /* Read data.  */
-  nbytes = read (connection->sock, connection->read_ptr,
-		 connection->read_end - connection->read_ptr);
-  if (nbytes > 0)
-    {
-      size_t total_bytes;
-
-      /* Update read pointer.  */
-      connection->read_ptr += nbytes;
-
-      /* Check if we have a complete request header.  */
-      total_bytes = connection->read_ptr - connection->read_base;
-      if (total_bytes >= sizeof (request_header))
-	{
-	  request_header *header;
-
-	  /* Check if we have a complete request.  */
-	  header = (request_header *)connection->read_base;
-	  if (total_bytes >= header->size)
-	    {
-	      /* Process the request.  */
-	      if (process_request (connection) < 0)
-		return -1;
-
-	      /* Adjust read pointer, and flush buffer.  */
-	      connection->read_ptr -= header->size;
-	      memmove (connection->read_base,
-		       connection->read_base + header->size,
-		       connection->read_ptr - connection->read_base);
-	    }
-	}
-
-      return 0;
-    }
-
-  if (nbytes < 0)
-    error (0, errno, _("cannot read from client"));
-
-  return -1;
-}
-
-
-/* Write data to the client on CONNECTION.  */
-int
-write_data (client_connection *connection)
-{
-  ssize_t nbytes;
-
-  assert (connection);
-  assert ((connection->write_ptr - connection->write_base) > 0);
-
-  /* Write data.  */
-  nbytes = write (connection->sock, connection->write_base,
-		  connection->write_ptr - connection->write_base);
-  if (nbytes > 0)
-    {
-      /* Adjust write pointer and flush buffer.  */
-      connection->write_ptr -= nbytes;
-      memmove (connection->write_base, connection->write_base + nbytes,
-	       connection->write_ptr - connection->write_base);
-
-      return 0;
-    }
-
-  if (nbytes < 0)
-    error (0, errno, _("cannot write to client"));
-
-  return -1;
-}
-
-
-/* Process the request received on CONNECTION.  Returns 0 if
-   successful, -1 if not.  */
-static int
-process_request (client_connection *connection)
-{
-  request_header *header;
-
-  assert (connection);
-  assert (connection->read_base);
-
-  header = (request_header *)connection->read_base;
-  if (header->version != UTMPD_VERSION)
-    {
-      warning (EINVAL, "invalid protocol version");
-      return -1;
-    }
-
-  switch (header->type)
-    {
-    case UTMPD_REQ_SETUTENT:	return do_setutent (connection);
-    case UTMPD_REQ_GETUTENT:	return do_getutent (connection);
-    case UTMPD_REQ_ENDUTENT:	return do_endutent (connection);
-    case UTMPD_REQ_GETUTLINE:	return do_getutline (connection);
-    case UTMPD_REQ_GETUTID:	return do_getutid (connection);
-    case UTMPD_REQ_PUTUTLINE:	return do_pututline (connection);
-    case UTMPD_REQ_UPDWTMP:	return do_updwtmp (connection);
-    default:
-      warning (EINVAL, "invalid request type");
-      return -1;
-    }
-}
-
-
-/* Send the reply specified by HEADER to the client on CONNECTION.
-   Returns 0 if successful, -1 if not.  */
-static int
-send_reply (client_connection *connection, const reply_header *reply)
-{
-  /* Check if the reply fits in the buffer.  */
-  if ((size_t) (connection->write_end - connection->write_ptr) < reply->size)
-    {
-      error (0, 0, _("buffer overflow"));
-      return -1;
-    }
-
-  /* Copy reply to buffer, and adjust write pointer.  */
-  memcpy (connection->write_ptr, reply, reply->size);
-  connection->write_ptr += reply->size;
-
-  return 0;
-}
-
-
-static int
-do_setutent (client_connection *connection)
-{
-  setutent_request *request;
-  setutent_reply reply;
-
-  /* The request size varies, so don't check it.  */
-  request = (setutent_request *)connection->read_base;
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (setutent_reply);
-  reply.header.type = UTMPD_REQ_SETUTENT;
-
-  /* Select database.  */
-  if (!strncmp (request->file, _PATH_UTMP,
-		request->header.size - sizeof (setutent_request)))
-    connection->database = utmp_db;
-  else
-    {
-      errno = EINVAL;
-      goto return_error;
-    }
-
-  /* Initialize position pointer.  */
-  connection->position = 0;
-
-#if _HAVE_UT_TYPE - 0
-  /* Make sure the entry won't match.  */
-  connection->last_entry.ut_type = -1;
-#endif
-
-  reply.errnum = 0;
-  reply.result = 0;
-  return send_reply (connection, &reply.header);
-
-return_error:
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_getutent (client_connection *connection)
-{
-  getutent_request *request;
-  getutent_reply reply;
-
-  request = (getutent_request *)connection->read_base;
-  if (request->header.size != sizeof (getutent_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (getutent_reply);
-  reply.header.type = UTMPD_REQ_GETUTENT;
-
-  if (connection->database == NULL || connection->position == -1)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Make sure we're in synch with the ordinary file.  */
-  if (synchronize_database (connection->database) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Read the next entry from the database.  */
-  if (read_entry (connection->database, connection->position,
-		  &connection->last_entry) < 0)
-    {
-      connection->position = -1;
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Update position pointer.  */
-  connection->position++;
-
-  memcpy (&reply.entry, &connection->last_entry, sizeof (struct utmp));
-  reply.errnum = 0;
-  reply.result = 0;
-  return send_reply (connection, (reply_header *)&reply);
-
-return_error:
-  memset (&reply.entry, 0, sizeof (struct utmp));
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_endutent (client_connection *connection)
-{
-  endutent_request *request;
-  endutent_reply reply;
-
-  request = (endutent_request *)connection->read_base;
-  if (request->header.size != sizeof (endutent_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
-
-  /* Deselect database.  */
-  connection->database = NULL;
-
-  /* Formulate reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (endutent_reply);
-  reply.header.type = UTMPD_REQ_ENDUTENT;
-  reply.errnum = 0;
-  reply.result = 0;
-
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_getutline (client_connection *connection)
-{
-  getutline_request *request;
-  getutline_reply reply;
-
-  request = (getutline_request *)connection->read_base;
-  if (request->header.size != sizeof (getutline_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (getutline_reply);
-  reply.header.type = UTMPD_REQ_GETUTLINE;
-
-  if (connection->database == NULL || connection->position == -1)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Make sure we're in synch with the ordinary file.  */
-  if (synchronize_database (connection->database) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  while (1)
-    {
-      /* Read the next entry.  */
-      if (read_entry (connection->database, connection->position,
-		      &connection->last_entry) < 0)
-	{
-	  connection->position = -1;
-	  errno = ESRCH;
-	  goto return_error;
-	}
-      connection->position++;
-
-      /* Stop if we found a user or login entry.  */
-      if (
-#if _HAVE_UT_TYPE - 0
-	  (connection->last_entry.ut_type == USER_PROCESS
-	   || connection->last_entry.ut_type == LOGIN_PROCESS)
-	  &&
-#endif
-	  !strncmp (request->line.ut_line, connection->last_entry.ut_line,
-		    sizeof request->line.ut_line))
-	break;
-    }
-
-  memcpy (&reply.entry, &connection->last_entry, sizeof (struct utmp));
-  reply.errnum = 0;
-  reply.result = 0;
-  return send_reply (connection, &reply.header);
-
-return_error:
-  memset (&reply.entry, 0, sizeof (struct utmp));
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_getutid (client_connection *connection)
-{
-  getutid_request *request;
-  getutid_reply reply;
-
-  request = (getutid_request *)connection->read_base;
-  if (request->header.size != sizeof (getutid_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (getutid_reply);
-  reply.header.type = UTMPD_REQ_GETUTID;
-
-  if (connection->database == NULL || connection->position == -1)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Make sure we're in synch with the ordinary file.  */
-  if (synchronize_database (connection->database) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  if (internal_getut_r (connection, &request->id,
-			&connection->last_entry) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  reply.errnum = 0;
-  reply.result = 0;
-  memcpy (&reply.entry, &connection->last_entry, sizeof (struct utmp));
-  return send_reply (connection, &reply.header);
-
-return_error:
-  memset (&reply.entry, 0, sizeof (struct utmp));
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_pututline (client_connection *connection)
-{
-  pututline_request *request;
-  pututline_reply reply;
-  struct utmp buffer;
-  int found;
-
-  request = (pututline_request *)connection->read_base;
-  if (request->header.size != sizeof (pututline_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (pututline_reply);
-  reply.header.type = UTMPD_REQ_PUTUTLINE;
-
-  if (!(connection->access & W_OK))
-    {
-      errno = EPERM;
-      goto return_error;
-    }
-
-  if (connection->database == NULL)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Make sure we're in synch with the ordinary file.  */
-  if (synchronize_database (connection->database) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Find the correct place to insert the data.  */
-  if (connection->position > 0
-    && (
-#if _HAVE_UT_TYPE - 0
-	(connection->last_entry.ut_type == request->utmp.ut_type
-	 && (connection->last_entry.ut_type == RUN_LVL
-	     || connection->last_entry.ut_type == BOOT_TIME
-	     || connection->last_entry.ut_type == OLD_TIME
-	     || connection->last_entry.ut_type == NEW_TIME))
-	||
-#endif
-	proc_utmp_eq (&connection->last_entry, &request->utmp)))
-    found = 1;
-  else
-    found = internal_getut_r (connection, &request->utmp, &buffer);
-
-  if (found < 0)
-    {
-      /* We append the next entry.  */
-      connection->position =
-	append_entry (connection->database, &request->utmp);
-      if (connection->position < 0)
-	goto return_error;
-    }
-  else
-    {
-      /* We replace the just read entry.  */
-      connection->position--;
-      if (write_entry (connection->database, connection->position,
-		       &request->utmp) < 0)
-	goto return_error;
-    }
-
-  /* Write the entry to the compatibility file.  */
-  write_old_entry (connection->database, connection->position, &request->utmp);
-
-  /* Update position pointer.  */
-  connection->position++;
-
-  reply.errnum = 0;
-  reply.result = 0;
-  return send_reply (connection, &reply.header);
-
-return_error:
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-static int
-do_updwtmp (client_connection *connection)
-{
-  updwtmp_request *request;
-  updwtmp_reply reply;
-  utmp_database *database;
-
-  /* The request size varies, so don't check it.  */
-  request = (updwtmp_request *)connection->read_base;
-
-  /* Initialize reply.  */
-  reply.header.version = UTMPD_VERSION;
-  reply.header.size = sizeof (updwtmp_reply);
-  reply.header.type = UTMPD_REQ_UPDWTMP;
-
-  if (!(connection->access & W_OK))
-    {
-      errno = EPERM;
-      goto return_error;
-    }
-
-  /* Select database.  */
-  if (!strncmp (request->file, _PATH_UTMP,
-		request->header.size - sizeof (updwtmp_request)))
-    database = utmp_db;
-  else
-    {
-      errno = EINVAL;
-      goto return_error;
-    }
-
-  /* Make sure we're in synch with the ordinary file.  */
-  if (synchronize_database (database) < 0)
-    {
-      errno = ESRCH;
-      goto return_error;
-    }
-
-  /* Append the entry.  */
-  if (append_entry (database, &request->utmp) < 0)
-    goto return_error;
-
-  reply.errnum = 0;
-  reply.result = 0;
-  return send_reply (connection, &reply.header);
-
-return_error:
-  reply.errnum = errno;
-  reply.result = -1;
-  return send_reply (connection, &reply.header);
-}
-
-
-/* This function is identical to the one in login/utmp_file.c.  */
-int
-proc_utmp_eq (const struct utmp *entry, const struct utmp *match)
-{
-  return
-    (
-#if _HAVE_UT_TYPE - 0
-     (entry->ut_type == INIT_PROCESS
-      || entry->ut_type == LOGIN_PROCESS
-      || entry->ut_type == USER_PROCESS
-      || entry->ut_type == DEAD_PROCESS)
-     &&
-     (match->ut_type == INIT_PROCESS
-      || match->ut_type == LOGIN_PROCESS
-      || match->ut_type == USER_PROCESS
-      || match->ut_type == DEAD_PROCESS)
-     &&
-#endif
-#if _HAVE_UT_ID - 0
-     (entry->ut_id[0] && match->ut_id[0]
-      ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
-      : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
-#else
-     strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
-#endif
-     );
-}
-
-
-/* This function is derived from the one in login/utmp_file.c.  */
-static int
-internal_getut_r (client_connection *connection,
-		  const struct utmp *id, struct utmp *buffer)
-{
-#if _HAVE_UT_TYPE - 0
-  if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
-      || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
-    {
-      /* Search for next entry with type RUN_LVL, BOOT_TIME,
-	 OLD_TIME, or NEW_TIME.  */
-
-      while (1)
-	{
-	  /* Read the next entry.  */
-	  if (read_entry (connection->database, connection->position,
-			  buffer) < 0)
-	    {
-	      connection->position = -1;
-	      return -1;
-	    }
-	  connection->position++;
-
-	  if (id->ut_type == buffer->ut_type)
-	    break;
-	}
-    }
-  else
-#endif /* _HAVE_UT_TYPE */
-    {
-      /* Search for the next entry with the specified ID and with type
-	 INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS.  */
-
-      while (1)
-	{
-	  /* Read the next entry.  */
-	  if (read_entry (connection->database, connection->position,
-			  buffer) < 0)
-	    {
-	      connection->position = -1;
-	      return -1;
-	    }
-	  connection->position++;
-
-	  if (proc_utmp_eq (buffer, id))
-	    break;
-	}
-    }
-
-  return 0;
-}
diff --git a/login/programs/xtmp.c b/login/programs/xtmp.c
deleted file mode 100644
index e27e1a8a86..0000000000
--- a/login/programs/xtmp.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <utmp.h>
-
-#include "xtmp.h"
-
-/* Convert the entry XT to the new utmp format and store it in UT.
-   Fields in UT that were not present in the old utmp format are
-   initialized to zero.  */
-void
-xtmp_to_utmp (const struct xtmp *xtmp, struct utmp *utmp)
-{
-  memset (utmp, 0, sizeof (struct utmp));
-#if _HAVE_XT_TYPE - 0
-  utmp->ut_type = xtmp->xt_type;
-#endif
-#if _HAVE_XT_PID - 0
-  utmp->ut_pid = xtmp->xt_pid;
-#endif
-  strncpy (utmp->ut_line, xtmp->xt_line, XT_LINESIZE);
-#if _HAVE_XT_ID - 0
-  strncpy (utmp->ut_id, xtmp->xt_id, sizeof xtmp->xt_id);
-#endif
-#if _HAVE_UT_TV - 0
-  utmp->ut_tv.tv_sec = xtmp->xt_time;
-#else
-  utmp->ut_time = xtmp->xt_time;
-#endif
-  strncpy (utmp->ut_user, xtmp->xt_user, XT_NAMESIZE);
-#if _HAVE_XT_HOST - 0
-  strncpy (utmp->ut_host, xtmp->xt_host, XT_HOSTSIZE);
-#endif
-  utmp->ut_addr = xtmp->xt_addr;
-}
-
-/* Convert the entry UTMP to the old utmp format and store it in XTMP.  */
-void
-utmp_to_xtmp (const struct utmp *utmp, struct xtmp *xtmp)
-{
-  memset (xtmp, 0, sizeof (struct xtmp));
-#if _HAVE_XT_TYPE - 0
-  xtmp->xt_type = utmp->ut_type;
-#endif
-#if _HAVE_XT_PID - 0
-  xtmp->xt_pid = utmp->ut_pid;
-#endif
-  strncpy (xtmp->xt_line, utmp->ut_line, XT_LINESIZE);
-  xtmp->xt_line[XT_LINESIZE] = '\0';
-#if _HAVE_XT_ID - 0
-  strncpy (xtmp->xt_id, utmp->ut_id, sizeof xtmp->xt_id);
-#endif
-#if _HAVE_UT_TV - 0
-  xtmp->xt_time = utmp->ut_tv.tv_sec;
-#else
-  xtmp->xt_time = utmp->ut_time;
-#endif
-  strncpy (xtmp->xt_user, utmp->ut_user, XT_NAMESIZE);
-#if _HAVE_XT_HOST - 0
-  strncpy (xtmp->xt_host, utmp->ut_host, XT_HOSTSIZE);
-  xtmp->xt_host[XT_HOSTSIZE] = '\0';
-#endif
-  xtmp->xt_addr = utmp->ut_addr;
-}
-
-/* Compare an old style entry XTMP with a new style entry UTMP.  The
-   function returns 1 if the information that is in both old and new
-   style entries is identical.  Otherwise this function returns 0.
-   
-   The type of the argument `xtmp' is `struct utmp *', not `struct
-   utmp *'.  This is intentional!  We convert from and to `struct
-   xtmp' directly when we read and write an old style entry.  But
-   since XTMP is converted from an old style entry, we compare only
-   those elements of the structure that are common to both the new and
-   the old style entry.  */
-int
-compare_entry (const struct utmp *xtmp, const struct utmp *utmp)
-{
-  return
-    (
-#if _HAVE_XT_TYPE - 0
-     xtmp->ut_type == utmp->ut_type
-#endif
-#if _HAVE_XT_PID - 0
-     && xtmp->ut_pid == utmp->ut_pid
-#endif
-     && !strncmp (xtmp->ut_line, utmp->ut_line, XT_LINESIZE - 1)
-#if _HAVE_XT_ID - 0
-     && !strncmp (xtmp->ut_id, utmp->ut_id, sizeof utmp->ut_id)
-#endif
-#if _HAVE_UT_TV - 0
-     && xtmp->ut_tv.tv_sec == utmp->ut_tv.tv_sec
-#else
-     && xtmp->ut_time == utmp->ut_time
-#endif
-     && !strncmp (xtmp->ut_user, utmp->ut_user, XT_NAMESIZE)
-#if _HAVE_XT_HOST - 0
-     && !strncmp (xtmp->ut_host, utmp->ut_host, XT_HOSTSIZE - 1)
-#endif
-     && xtmp->ut_addr == utmp->ut_addr);
-}
diff --git a/login/programs/xtmp.h b/login/programs/xtmp.h
deleted file mode 100644
index 2a3d5d2ffc..0000000000
--- a/login/programs/xtmp.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* The `struct xtmp' type, describing the old linux utmp format.
-   Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef _XTMP_H
-#define _XTMP_H		1
-
-#include <sys/time.h>
-#include <sys/types.h>
-
-
-#define XT_LINESIZE	12
-#define XT_NAMESIZE	8
-#define XT_HOSTSIZE	16
-
-struct xtmp
-{
-  short	int xt_type;		/* Type of login.  */
-  pid_t	xt_pid;			/* Pid of login process.  */
-  char	xt_line[XT_LINESIZE];	/* NUL-terminated devicename of tty.  */
-  char	xt_id[4];		/* Inittab id.  */
-  time_t xt_time;		/* Time entry was made.  */
-  char	xt_user[XT_NAMESIZE];	/* Username (not NUL terminated).  */
-  char	xt_host[XT_HOSTSIZE];	/* Hostname for remote login.  */
-  long	xt_addr;		/* Internet address of remote host.  */
-};
-
-#define _HAVE_XT_TYPE	1
-#define _HAVE_XT_PID	1
-#define _HAVE_XT_ID	1
-#define _HAVE_XT_HOST	1
-
-
-extern void xtmp_to_utmp (const struct xtmp *xtmp, struct utmp *utmp);
-extern void utmp_to_xtmp (const struct utmp *utmp, struct xtmp *xtmp);
-extern int compare_entry (const struct utmp *xtmp,
-			  const struct utmp *utmp);
-
-#endif /* xtmp.h  */