root/maint/gnulib/lib/sethostname.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sethostname
  2. sethostname

   1 /* sethostname emulation for glibc compliance.
   2 
   3    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 /* Ben Walton <bwalton@artsci.utoronto.ca> */
  19 
  20 #include <config.h>
  21 
  22 #if !(defined _WIN32 || defined __CYGWIN__)
  23 /* Unix API.  */
  24 
  25 /* Specification.  */
  26 # include <unistd.h>
  27 
  28 # include <errno.h>
  29 # include <stdio.h>
  30 # include <limits.h>
  31 
  32 /* Set up to LEN chars of NAME as system hostname.
  33    Return 0 if ok, set errno and return -1 on error. */
  34 
  35 int
  36 sethostname (const char *name, size_t len)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38   /* Ensure the string isn't too long.  glibc does allow setting an
  39      empty hostname so no point in enforcing a lower bound. */
  40   if (len > HOST_NAME_MAX)
  41     {
  42       errno = EINVAL;
  43       return -1;
  44     }
  45 
  46 # ifdef __minix /* Minix */
  47   {
  48     FILE *hostf;
  49     int r = 0;
  50 
  51     /* glibc returns EFAULT, EINVAL, and EPERM on error.  None of
  52        these are appropriate for us to set, even if they may match the
  53        situation, during failed open/write/close operations, so we
  54        leave errno alone and rely on what the system sets up. */
  55     hostf = fopen ("/etc/hostname.file", "we");
  56     if (hostf == NULL)
  57       r = -1;
  58     else
  59       {
  60         fprintf (hostf, "%.*s\n", (int) len, name);
  61         if (ferror (hostf))
  62           {
  63             /* Close hostf, preserving the errno from the fprintf call.  */
  64             int saved_errno = errno;
  65             fclose (hostf);
  66             errno = saved_errno;
  67             r = -1;
  68           }
  69         else
  70           {
  71             if (fclose (hostf))
  72               /* fclose sets errno on failure.  */
  73               r = -1;
  74           }
  75       }
  76 
  77     return r;
  78   }
  79 # else
  80   /* For platforms that we don't have a better option for, simply bail
  81      out.  */
  82   errno = ENOSYS;
  83   return -1;
  84 # endif
  85 }
  86 
  87 #else
  88 /* Native Windows API.  Also used on Cygwin.  */
  89 
  90 /* Ensure that <windows.h> declares SetComputerNameEx.  */
  91 # if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
  92 #  undef _WIN32_WINNT
  93 #  define _WIN32_WINNT _WIN32_WINNT_WIN2K
  94 # endif
  95 
  96 # define WIN32_LEAN_AND_MEAN
  97 
  98 /* Specification.  */
  99 # include <unistd.h>
 100 
 101 # include <errno.h>
 102 # include <limits.h>
 103 # include <string.h>
 104 
 105 # include <windows.h>
 106 
 107 /* Don't assume that UNICODE is not defined.  */
 108 # undef GetComputerNameEx
 109 # define GetComputerNameEx GetComputerNameExA
 110 # undef SetComputerNameEx
 111 # define SetComputerNameEx SetComputerNameExA
 112 
 113 /* Set up to LEN chars of NAME as system hostname.
 114    Return 0 if ok, set errno and return -1 on error. */
 115 
 116 int
 117 sethostname (const char *name, size_t len)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119   char name_asciz[HOST_NAME_MAX + 1];
 120   char old_name[HOST_NAME_MAX + 1];
 121   DWORD old_name_len;
 122 
 123   /* Ensure the string isn't too long.  glibc does allow setting an
 124      empty hostname so no point in enforcing a lower bound. */
 125   if (len > HOST_NAME_MAX)
 126     {
 127       errno = EINVAL;
 128       return -1;
 129     }
 130 
 131   /* Prepare a NUL-terminated copy of name.  */
 132   memcpy (name_asciz, name, len);
 133   name_asciz[len] = '\0';
 134 
 135   /* Save the old NetBIOS name.  */
 136   old_name_len = sizeof (old_name) - 1;
 137   if (! GetComputerNameEx (ComputerNamePhysicalNetBIOS,
 138                            old_name, &old_name_len))
 139     old_name_len = 0;
 140 
 141   /* Set both the NetBIOS and the first part of the IP / DNS name.  */
 142   if (! SetComputerNameEx (ComputerNamePhysicalNetBIOS, name_asciz))
 143     {
 144       errno = (GetLastError () == ERROR_ACCESS_DENIED ? EPERM : EINVAL);
 145       return -1;
 146     }
 147   if (! SetComputerNameEx (ComputerNamePhysicalDnsHostname, name_asciz))
 148     {
 149       errno = (GetLastError () == ERROR_ACCESS_DENIED ? EPERM : EINVAL);
 150       /* Restore the old NetBIOS name.  */
 151       if (old_name_len > 0)
 152         {
 153           old_name[old_name_len] = '\0';
 154           SetComputerNameEx (ComputerNamePhysicalNetBIOS, old_name);
 155         }
 156       return -1;
 157     }
 158 
 159   /* Note that the new host name becomes effective only after a reboot!  */
 160   return 0;
 161 }
 162 
 163 #endif

/* [previous][next][first][last][top][bottom][index][help] */