README-release: make it easier to execute commands
[gnulib.git] / tests / test-sethostname2.c
1 /*
2  * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3  * Written by Ben Walton.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program 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 General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include <unistd.h>
21
22 /* for HOST_NAME_MAX */
23 #include <limits.h>
24 /* for strlen */
25 #include <string.h>
26
27 #include <errno.h>
28 #include <stdio.h>
29
30 #include "macros.h"
31
32 #define TESTHOSTNAME "gnulib-hostname"
33
34 /* mingw and MSVC 9 lack geteuid, so setup a dummy value.
35    On Cygwin, geteuid() may return non-zero even for user accounts with
36    administrator privileges, so use a dummy value as well.  */
37 #if !HAVE_GETEUID || defined __CYGWIN__
38 # define geteuid() 0
39 #endif
40
41 int
42 main (int argc, char *argv[] _GL_UNUSED)
43 {
44   char origname[HOST_NAME_MAX];
45   char newname[HOST_NAME_MAX];
46   char longname[HOST_NAME_MAX + 2];
47   int rcs, i;
48
49   /* skip the tests if we don't have root privilege.  this does not
50      consider things like CAP_SYS_ADMIN (linux) or PRIV_SYS_ADMIN
51      (solaris), etc.  systems without a working geteuid (mingw, MSVC
52      9) will always skip this test. */
53   if (geteuid () != 0)
54     {
55       fprintf (stderr, "Skipping test: insufficient permissions.\n");
56       return 77;
57     }
58
59   /* we want to ensure we can do a get/set/get check to ensure the
60      change is accepted. record the current name so it can be restored
61      later */
62   ASSERT (gethostname (origname, sizeof (origname)) == 0);
63
64   /* try setting a valid hostname.  if it fails -1/ENOSYS, we will
65      skip the test for long names as this is an indication we're using
66      the stub function that doesn't do anything on this platform. */
67   rcs = sethostname (TESTHOSTNAME, strlen (TESTHOSTNAME));
68
69   if (rcs != 0)
70     {
71       if (rcs == -1 && errno == ENOSYS)
72         {
73           fprintf (stderr,
74                    "Skipping test: sethostname is not really implemented.\n");
75           return 77;
76         }
77       else if (rcs == -1 && errno == EPERM)
78         {
79           fprintf (stderr, "Skipping test: insufficient permissions.\n");
80           return 77;
81         }
82       else
83         {
84           fprintf (stderr, "error setting valid hostname.\n");
85           return 1;
86         }
87     }
88   else
89     {
90       ASSERT (gethostname (newname, sizeof (newname)) == 0);
91
92       /* On Windows, a hostname change becomes effective only after
93          a reboot.  */
94 #if !((defined _WIN32 || defined __WIN32__) || defined __CYGWIN__)
95
96       /* if we don't get back what we put in, there is no need to
97          restore the original name as we will assume it was not
98          properly changed. */
99       if (strcmp (newname, TESTHOSTNAME) != 0)
100         {
101           fprintf (stderr, "set/get comparison failed.\n");
102           return 1;
103         }
104 #endif
105     }
106
107   /* glibc does allow setting a zero length name, so the lower bound
108      needs no test. validate that we are constrained by
109      HOST_NAME_MAX */
110   for (i = 0; i < (HOST_NAME_MAX + 1); i++)
111     longname[i] = 'a';
112
113   longname[i] = '\0';
114
115   rcs = sethostname (longname, (HOST_NAME_MAX + 1));
116
117   if (rcs != -1)
118     {
119       /* attempt to restore the original name. */
120       ASSERT (sethostname (origname, strlen (origname)) == 0);
121       fprintf (stderr, "setting a too long hostname succeeded.\n");
122       return 1;
123     }
124
125   /* restore the original name. */
126   ASSERT (sethostname (origname, strlen (origname)) == 0);
127
128   return 0;
129 }