Back to index

glibc  2.9
get-host.c
Go to the documentation of this file.
00001 /* Get a host configuration item kept as the whole contents of a file.
00002    Copyright (C) 1996,97,99,2000,2001 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <fcntl.h>
00021 #include <hurd.h>
00022 #include <hurd/lookup.h>
00023 #include "hurdhost.h"
00024 #include <string.h>
00025 
00026 ssize_t
00027 _hurd_get_host_config (const char *item, char *buf, size_t buflen)
00028 {
00029   error_t err;
00030   char *data;
00031   mach_msg_type_number_t nread, more;
00032   file_t config;
00033 
00034   err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, 0,
00035                              item, O_RDONLY, 0, &config);
00036   switch (err)
00037     {
00038     case 0:                 /* Success; read file contents below.  */
00039       break;
00040 
00041     case ENOENT:            /* ? Others?  All errors? */
00042       /* The file does not exist, so no value has been set.  Rather than
00043         causing gethostname et al to fail with ENOENT, give an empty value
00044         as other systems do before sethostname has been called.  */
00045       if (buflen != 0)
00046        *buf = '\0';
00047       return 0;
00048 
00049     default:
00050       return __hurd_fail (err);
00051     }
00052 
00053   data = buf;
00054   nread = buflen;
00055   err = __io_read (config, &data, &nread, -1, buflen);
00056   if (! err)
00057     /* Check if there is more in the file we didn't read.  */
00058     err = __io_readable (config, &more);
00059   __mach_port_deallocate (__mach_task_self (), config);
00060   if (err)
00061     return __hurd_fail (err);
00062   if (data != buf)
00063     {
00064       memcpy (buf, data, nread);
00065       __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
00066     }
00067 
00068   /* If the file is empty, give an empty value.  */
00069   if (nread == 0)
00070     {
00071       if (buflen != 0)
00072        *buf = '\0';
00073       return 0;
00074     }
00075 
00076   /* Remove newlines in case someone wrote the file by hand.  */
00077   while (nread > 0 && buf[nread - 1] == '\n')
00078     buf[--nread] = '\0';
00079 
00080   /* Null-terminate the result if there is enough space.  */
00081   if (nread < buflen)
00082     buf[nread] = '\0';
00083   else
00084     if (buf[nread - 1] != '\0')
00085       more = 1;
00086 
00087   if (more)
00088     /* If we didn't read the whole file, tell the caller to use a bigger
00089        buffer next time.  */
00090     return __hurd_fail (ENAMETOOLONG);
00091 
00092   return nread;
00093 }