about summary refs log tree commit diff
path: root/login/programs/request.c
diff options
context:
space:
mode:
Diffstat (limited to 'login/programs/request.c')
-rw-r--r--login/programs/request.c646
1 files changed, 0 insertions, 646 deletions
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;
-}