Blame hurd/get-host.c

Packit Service 82fcde
/* Get a host configuration item kept as the whole contents of a file.
Packit Service 82fcde
   Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
#include <hurd.h>
Packit Service 82fcde
#include <hurd/lookup.h>
Packit Service 82fcde
#include "hurdhost.h"
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
Packit Service 82fcde
ssize_t
Packit Service 82fcde
_hurd_get_host_config (const char *item, char *buf, size_t buflen)
Packit Service 82fcde
{
Packit Service 82fcde
  error_t err;
Packit Service 82fcde
  char *data;
Packit Service 82fcde
  mach_msg_type_number_t nread, more;
Packit Service 82fcde
  file_t config;
Packit Service 82fcde
Packit Service 82fcde
  err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, 0,
Packit Service 82fcde
				 item, O_RDONLY, 0, &config);
Packit Service 82fcde
  switch (err)
Packit Service 82fcde
    {
Packit Service 82fcde
    case 0:			/* Success; read file contents below.  */
Packit Service 82fcde
      break;
Packit Service 82fcde
Packit Service 82fcde
    case ENOENT:		/* ? Others?  All errors? */
Packit Service 82fcde
      /* The file does not exist, so no value has been set.  Rather than
Packit Service 82fcde
	 causing gethostname et al to fail with ENOENT, give an empty value
Packit Service 82fcde
	 as other systems do before sethostname has been called.  */
Packit Service 82fcde
      if (buflen != 0)
Packit Service 82fcde
	*buf = '\0';
Packit Service 82fcde
      return 0;
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 82fcde
      return __hurd_fail (err);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  data = buf;
Packit Service 82fcde
  nread = buflen;
Packit Service 82fcde
  err = __io_read (config, &data, &nread, -1, buflen);
Packit Service 82fcde
  if (! err)
Packit Service 82fcde
    /* Check if there is more in the file we didn't read.  */
Packit Service 82fcde
    err = __io_readable (config, &more);
Packit Service 82fcde
  __mach_port_deallocate (__mach_task_self (), config);
Packit Service 82fcde
  if (err)
Packit Service 82fcde
    return __hurd_fail (err);
Packit Service 82fcde
  if (data != buf)
Packit Service 82fcde
    {
Packit Service 82fcde
      memcpy (buf, data, nread);
Packit Service 82fcde
      __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* If the file is empty, give an empty value.  */
Packit Service 82fcde
  if (nread == 0 && more == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (buflen != 0)
Packit Service 82fcde
	*buf = '\0';
Packit Service 82fcde
      return 0;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Remove newlines in case someone wrote the file by hand.  */
Packit Service 82fcde
  while (nread > 0 && buf[nread - 1] == '\n')
Packit Service 82fcde
    buf[--nread] = '\0';
Packit Service 82fcde
Packit Service 82fcde
  /* Null-terminate the result if there is enough space.  */
Packit Service 82fcde
  if (nread < buflen)
Packit Service 82fcde
    buf[nread] = '\0';
Packit Service 82fcde
  else
Packit Service 82fcde
    if (nread != 0 && buf[nread - 1] != '\0')
Packit Service 82fcde
      more = 1;
Packit Service 82fcde
Packit Service 82fcde
  if (more)
Packit Service 82fcde
    /* If we didn't read the whole file, tell the caller to use a bigger
Packit Service 82fcde
       buffer next time.  */
Packit Service 82fcde
    return __hurd_fail (ENAMETOOLONG);
Packit Service 82fcde
Packit Service 82fcde
  return nread;
Packit Service 82fcde
}