1
/* Display hostname in various forms.
2
Copyright (C) 2001-2003 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 2, or (at your option)
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, write to the Free Software Foundation,
17
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
31
#if defined _WIN32 || defined __WIN32__
32
# undef WIN32 /* avoid warning on mingw32 */
36
/* Get gethostname(). */
42
/* Native Woe32 API lacks gethostname() but has GetComputerName() instead. */
45
/* Some systems, like early Solaris versions, lack gethostname() but
46
have uname() instead. */
47
# if !HAVE_GETHOSTNAME
48
# include <sys/utsname.h>
52
/* Get MAXHOSTNAMELEN. */
53
#include <sys/param.h>
54
#ifndef MAXHOSTNAMELEN
55
# define MAXHOSTNAMELEN 64
58
/* Support for using gethostbyname(). */
59
#if HAVE_GETHOSTBYNAME
60
# include <sys/types.h>
61
# include <sys/socket.h> /* defines AF_INET, AF_INET6 */
62
# include <netinet/in.h> /* declares ntohs(), defines struct sockaddr_in */
64
# include <arpa/inet.h> /* declares inet_ntoa(), inet_ntop() */
67
# if !defined(__CYGWIN__) /* Cygwin has only s6_addr, no s6_addr16 */
68
# if defined(__APPLE__) && defined(__MACH__) /* MacOS X */
69
# define in6_u __u6_addr
70
# define u6_addr16 __u6_addr16
72
/* Use s6_addr16 for portability. See RFC 2553. */
74
# define s6_addr16 in6_u.u6_addr16
76
# define HAVE_IN6_S6_ADDR16 1
79
# include <netdb.h> /* defines struct hostent, declares gethostbyname() */
82
/* Include this after <sys/socket.h>, to avoid a syntax error on BeOS. */
87
#include "error-progname.h"
89
#include "relocatable.h"
95
#define _(str) gettext (str)
99
static enum { default_format, short_format, long_format, ip_format } format;
102
static const struct option long_options[] =
104
{ "fqdn", no_argument, NULL, 'f' },
105
{ "help", no_argument, NULL, 'h' },
106
{ "ip-address", no_argument, NULL, 'i' },
107
{ "long", no_argument, NULL, 'f' },
108
{ "short", no_argument, NULL, 's' },
109
{ "version", no_argument, NULL, 'V' },
114
/* Forward declaration of local functions. */
115
static void usage (int status)
116
#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
117
__attribute__ ((noreturn))
120
static void print_hostname (void);
123
main (int argc, char *argv[])
129
/* Set program name for messages. */
130
set_program_name (argv[0]);
131
error_print_progname = maybe_print_progname;
133
#ifdef HAVE_SETLOCALE
134
/* Set locale via LC_ALL. */
135
setlocale (LC_ALL, "");
138
/* Set the text message domain. */
139
bindtextdomain (PACKAGE, relocate (LOCALEDIR));
140
textdomain (PACKAGE);
142
/* Ensure that write errors on stdout are detected. */
143
atexit (close_stdout);
145
/* Set default values for variables. */
148
format = default_format;
150
/* Parse command line options. */
151
while ((optchar = getopt_long (argc, argv, "fhisV", long_options, NULL))
155
case '\0': /* Long option. */
158
format = long_format;
161
format = short_format;
173
usage (EXIT_FAILURE);
177
/* Version information requested. */
180
printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
181
/* xgettext: no-wrap */
182
printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
183
This is free software; see the source for copying conditions. There is NO\n\
184
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
187
printf (_("Written by %s.\n"), "Bruno Haible");
191
/* Help is requested. */
193
usage (EXIT_SUCCESS);
195
/* Test for extraneous arguments. */
197
error (EXIT_FAILURE, 0, _("too many arguments"));
199
/* Get and print the hostname. */
205
/* Display usage information and exit. */
209
if (status != EXIT_SUCCESS)
210
fprintf (stderr, _("Try `%s --help' for more information.\n"),
215
Usage: %s [OPTION]\n\
219
Print the machine's hostname.\n"));
224
-s, --short short host name\n"));
226
-f, --fqdn, --long long host name, includes fully qualified domain\n\
227
name, and aliases\n"));
229
-i, --ip-address addresses for the hostname\n"));
232
Informative output:\n"));
234
-h, --help display this help and exit\n"));
236
-V, --version output version information and exit\n"));
238
fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
245
/* Returns an xmalloc()ed string containing the machine's host name. */
250
char hostname[MAX_COMPUTERNAME_LENGTH+1];
251
DWORD size = sizeof (hostname);
253
if (!GetComputerName (hostname, &size))
254
error (EXIT_FAILURE, 0, _("could not get host name"));
255
return xstrdup (hostname);
256
#elif HAVE_GETHOSTNAME
257
char hostname[MAXHOSTNAMELEN+1];
259
if (gethostname (hostname, MAXHOSTNAMELEN) < 0)
260
error (EXIT_FAILURE, errno, _("could not get host name"));
261
hostname[MAXHOSTNAMELEN] = '\0';
262
return xstrdup (hostname);
264
struct utsname utsname;
266
if (uname (&utsname) < 0)
267
error (EXIT_FAILURE, errno, _("could not get host name"));
268
return xstrdup (utsname.nodename);
272
/* Converts an AF_INET address to a printable, presentable format.
273
BUFFER is an array with at least 15+1 bytes. ADDR is 'struct in_addr'. */
275
# define ipv4_ntop(buffer,addr) \
276
inet_ntop (AF_INET, &addr, buffer, 15+1)
278
# define ipv4_ntop(buffer,addr) \
279
strcpy (buffer, inet_ntoa (addr))
283
/* Converts an AF_INET6 address to a printable, presentable format.
284
BUFFER is an array with at least 45+1 bytes. ADDR is 'struct in6_addr'. */
286
# define ipv6_ntop(buffer,addr) \
287
inet_ntop (AF_INET6, &addr, buffer, 45+1)
288
# elif HAVE_IN6_S6_ADDR16
289
# define ipv6_ntop(buffer,addr) \
290
sprintf (buffer, "%x:%x:%x:%x:%x:%x:%x:%x", \
291
ntohs ((addr).s6_addr16[0]), \
292
ntohs ((addr).s6_addr16[1]), \
293
ntohs ((addr).s6_addr16[2]), \
294
ntohs ((addr).s6_addr16[3]), \
295
ntohs ((addr).s6_addr16[4]), \
296
ntohs ((addr).s6_addr16[5]), \
297
ntohs ((addr).s6_addr16[6]), \
298
ntohs ((addr).s6_addr16[7]))
300
# define ipv6_ntop(buffer,addr) \
301
sprintf (buffer, "%x:%x:%x:%x:%x:%x:%x:%x", \
302
((addr).s6_addr[0] << 8) | (addr).s6_addr[1], \
303
((addr).s6_addr[2] << 8) | (addr).s6_addr[3], \
304
((addr).s6_addr[4] << 8) | (addr).s6_addr[5], \
305
((addr).s6_addr[6] << 8) | (addr).s6_addr[7], \
306
((addr).s6_addr[8] << 8) | (addr).s6_addr[9], \
307
((addr).s6_addr[10] << 8) | (addr).s6_addr[11], \
308
((addr).s6_addr[12] << 8) | (addr).s6_addr[13], \
309
((addr).s6_addr[14] << 8) | (addr).s6_addr[15])
313
/* Print the hostname according to the specified format. */
319
#if HAVE_GETHOSTBYNAME
324
hostname = xgethostname ();
329
/* Print the hostname, as returned by the system call. */
330
printf ("%s\n", hostname);
334
/* Print only the part before the first dot. */
335
dot = strchr (hostname, '.');
338
printf ("%s\n", hostname);
342
/* Look for netwide usable hostname and aliases using gethostbyname(). */
343
#if HAVE_GETHOSTBYNAME
344
h = gethostbyname (hostname);
347
printf ("%s\n", h->h_name);
348
if (h->h_aliases != NULL)
349
for (i = 0; h->h_aliases[i] != NULL; i++)
350
printf ("%s\n", h->h_aliases[i]);
354
printf ("%s\n", hostname);
358
/* Look for netwide usable IP addresses using gethostbyname(). */
359
#if HAVE_GETHOSTBYNAME
360
h = gethostbyname (hostname);
361
if (h != NULL && h->h_addr_list != NULL)
362
for (i = 0; h->h_addr_list[i] != NULL; i++)
365
if (h->h_addrtype == AF_INET6)
368
ipv6_ntop (buffer, *(const struct in6_addr*) h->h_addr_list[i]);
369
printf("[%s]\n", buffer);
373
if (h->h_addrtype == AF_INET)
376
ipv4_ntop (buffer, *(const struct in_addr*) h->h_addr_list[i]);
377
printf("[%s]\n", buffer);