1 /* Display hostname in various forms.
2 Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
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.
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.
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/>. */
30 #if defined _WIN32 || defined __WIN32__
34 /* Get gethostname(). */
38 /* Native Woe32 API lacks gethostname() but has GetComputerName() instead. */
41 /* Some systems, like early Solaris versions, lack gethostname() but
42 have uname() instead. */
43 # if !HAVE_GETHOSTNAME
44 # include <sys/utsname.h>
48 /* Get MAXHOSTNAMELEN. */
49 #include <sys/param.h>
50 #ifndef MAXHOSTNAMELEN
51 # define MAXHOSTNAMELEN 64
54 /* Support for using gethostbyname(). */
55 #if HAVE_GETHOSTBYNAME
56 # include <sys/types.h>
57 # include <sys/socket.h> /* defines AF_INET, AF_INET6 */
58 # include <netinet/in.h> /* declares ntohs(), defines struct sockaddr_in */
60 # include <arpa/inet.h> /* declares inet_ntoa(), inet_ntop() */
63 # if !defined(__CYGWIN__) /* Cygwin has only s6_addr, no s6_addr16 */
64 # if defined(__APPLE__) && defined(__MACH__) /* MacOS X */
65 # define in6_u __u6_addr
66 # define u6_addr16 __u6_addr16
68 /* Use s6_addr16 for portability. See RFC 2553. */
70 # define s6_addr16 in6_u.u6_addr16
72 # define HAVE_IN6_S6_ADDR16 1
75 # include <netdb.h> /* defines struct hostent, declares gethostbyname() */
78 /* Include this after <sys/socket.h>, to avoid a syntax error on BeOS. */
83 #include "error-progname.h"
85 #include "relocatable.h"
88 #include "propername.h"
91 #define _(str) gettext (str)
95 static enum { default_format, short_format, long_format, ip_format } format;
98 static const struct option long_options[] =
100 { "fqdn", no_argument, NULL, 'f' },
101 { "help", no_argument, NULL, 'h' },
102 { "ip-address", no_argument, NULL, 'i' },
103 { "long", no_argument, NULL, 'f' },
104 { "short", no_argument, NULL, 's' },
105 { "version", no_argument, NULL, 'V' },
110 /* Forward declaration of local functions. */
111 static void usage (int status)
112 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
113 __attribute__ ((noreturn))
116 static void print_hostname (void);
119 main (int argc, char *argv[])
125 /* Set program name for messages. */
126 set_program_name (argv[0]);
127 error_print_progname = maybe_print_progname;
129 #ifdef HAVE_SETLOCALE
130 /* Set locale via LC_ALL. */
131 setlocale (LC_ALL, "");
134 /* Set the text message domain. */
135 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
136 textdomain (PACKAGE);
138 /* Ensure that write errors on stdout are detected. */
139 atexit (close_stdout);
141 /* Set default values for variables. */
144 format = default_format;
146 /* Parse command line options. */
147 while ((optchar = getopt_long (argc, argv, "fhisV", long_options, NULL))
151 case '\0': /* Long option. */
154 format = long_format;
157 format = short_format;
169 usage (EXIT_FAILURE);
173 /* Version information requested. */
176 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
177 /* xgettext: no-wrap */
178 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
179 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
180 This is free software: you are free to change and redistribute it.\n\
181 There is NO WARRANTY, to the extent permitted by law.\n\
183 "2001-2003, 2006-2007");
184 printf (_("Written by %s.\n"), proper_name ("Bruno Haible"));
188 /* Help is requested. */
190 usage (EXIT_SUCCESS);
192 /* Test for extraneous arguments. */
194 error (EXIT_FAILURE, 0, _("too many arguments"));
196 /* Get and print the hostname. */
202 /* Display usage information and exit. */
206 if (status != EXIT_SUCCESS)
207 fprintf (stderr, _("Try `%s --help' for more information.\n"),
212 Usage: %s [OPTION]\n\
216 Print the machine's hostname.\n"));
221 -s, --short short host name\n"));
223 -f, --fqdn, --long long host name, includes fully qualified domain\n\
224 name, and aliases\n"));
226 -i, --ip-address addresses for the hostname\n"));
229 Informative output:\n"));
231 -h, --help display this help and exit\n"));
233 -V, --version output version information and exit\n"));
235 /* TRANSLATORS: The placeholder indicates the bug-reporting address
236 for this package. Please add _another line_ saying
237 "Report translation bugs to <...>\n" with the address for translation
238 bugs (typically your translation team's web or email address). */
239 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
246 /* Returns an xmalloc()ed string containing the machine's host name. */
251 char hostname[MAX_COMPUTERNAME_LENGTH+1];
252 DWORD size = sizeof (hostname);
254 if (!GetComputerName (hostname, &size))
255 error (EXIT_FAILURE, 0, _("could not get host name"));
256 return xstrdup (hostname);
257 #elif HAVE_GETHOSTNAME
258 char hostname[MAXHOSTNAMELEN+1];
260 if (gethostname (hostname, MAXHOSTNAMELEN) < 0)
261 error (EXIT_FAILURE, errno, _("could not get host name"));
262 hostname[MAXHOSTNAMELEN] = '\0';
263 return xstrdup (hostname);
265 struct utsname utsname;
267 if (uname (&utsname) < 0)
268 error (EXIT_FAILURE, errno, _("could not get host name"));
269 return xstrdup (utsname.nodename);
273 /* Converts an AF_INET address to a printable, presentable format.
274 BUFFER is an array with at least 15+1 bytes. ADDR is 'struct in_addr'. */
276 # define ipv4_ntop(buffer,addr) \
277 inet_ntop (AF_INET, &addr, buffer, 15+1)
279 # define ipv4_ntop(buffer,addr) \
280 strcpy (buffer, inet_ntoa (addr))
284 /* Converts an AF_INET6 address to a printable, presentable format.
285 BUFFER is an array with at least 45+1 bytes. ADDR is 'struct in6_addr'. */
287 # define ipv6_ntop(buffer,addr) \
288 inet_ntop (AF_INET6, &addr, buffer, 45+1)
289 # elif HAVE_IN6_S6_ADDR16
290 # define ipv6_ntop(buffer,addr) \
291 sprintf (buffer, "%x:%x:%x:%x:%x:%x:%x:%x", \
292 ntohs ((addr).s6_addr16[0]), \
293 ntohs ((addr).s6_addr16[1]), \
294 ntohs ((addr).s6_addr16[2]), \
295 ntohs ((addr).s6_addr16[3]), \
296 ntohs ((addr).s6_addr16[4]), \
297 ntohs ((addr).s6_addr16[5]), \
298 ntohs ((addr).s6_addr16[6]), \
299 ntohs ((addr).s6_addr16[7]))
301 # define ipv6_ntop(buffer,addr) \
302 sprintf (buffer, "%x:%x:%x:%x:%x:%x:%x:%x", \
303 ((addr).s6_addr[0] << 8) | (addr).s6_addr[1], \
304 ((addr).s6_addr[2] << 8) | (addr).s6_addr[3], \
305 ((addr).s6_addr[4] << 8) | (addr).s6_addr[5], \
306 ((addr).s6_addr[6] << 8) | (addr).s6_addr[7], \
307 ((addr).s6_addr[8] << 8) | (addr).s6_addr[9], \
308 ((addr).s6_addr[10] << 8) | (addr).s6_addr[11], \
309 ((addr).s6_addr[12] << 8) | (addr).s6_addr[13], \
310 ((addr).s6_addr[14] << 8) | (addr).s6_addr[15])
314 /* Print the hostname according to the specified format. */
320 #if HAVE_GETHOSTBYNAME
325 hostname = xgethostname ();
330 /* Print the hostname, as returned by the system call. */
331 printf ("%s\n", hostname);
335 /* Print only the part before the first dot. */
336 dot = strchr (hostname, '.');
339 printf ("%s\n", hostname);
343 /* Look for netwide usable hostname and aliases using gethostbyname(). */
344 #if HAVE_GETHOSTBYNAME
345 h = gethostbyname (hostname);
348 printf ("%s\n", h->h_name);
349 if (h->h_aliases != NULL)
350 for (i = 0; h->h_aliases[i] != NULL; i++)
351 printf ("%s\n", h->h_aliases[i]);
355 printf ("%s\n", hostname);
359 /* Look for netwide usable IP addresses using gethostbyname(). */
360 #if HAVE_GETHOSTBYNAME
361 h = gethostbyname (hostname);
362 if (h != NULL && h->h_addr_list != NULL)
363 for (i = 0; h->h_addr_list[i] != NULL; i++)
366 if (h->h_addrtype == AF_INET6)
369 ipv6_ntop (buffer, *(const struct in6_addr*) h->h_addr_list[i]);
370 printf("[%s]\n", buffer);
374 if (h->h_addrtype == AF_INET)
377 ipv4_ntop (buffer, *(const struct in_addr*) h->h_addr_list[i]);
378 printf("[%s]\n", buffer);