No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / hostname.c
blob975508f0e8483a67f265c19ba3f2574f6b93aa9c
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)
8 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, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <errno.h>
25 #include <getopt.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <locale.h>
31 #if defined _WIN32 || defined __WIN32__
32 # undef WIN32 /* avoid warning on mingw32 */
33 # define WIN32
34 #endif
36 /* Get gethostname(). */
37 #if HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
41 #ifdef WIN32
42 /* Native Woe32 API lacks gethostname() but has GetComputerName() instead. */
43 # include <windows.h>
44 #else
45 /* Some systems, like early Solaris versions, lack gethostname() but
46 have uname() instead. */
47 # if !HAVE_GETHOSTNAME
48 # include <sys/utsname.h>
49 # endif
50 #endif
52 /* Get MAXHOSTNAMELEN. */
53 #include <sys/param.h>
54 #ifndef MAXHOSTNAMELEN
55 # define MAXHOSTNAMELEN 64
56 #endif
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 */
63 # if HAVE_ARPA_INET_H
64 # include <arpa/inet.h> /* declares inet_ntoa(), inet_ntop() */
65 # endif
66 # if HAVE_IPV6
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
71 # endif
72 /* Use s6_addr16 for portability. See RFC 2553. */
73 # ifndef s6_addr16
74 # define s6_addr16 in6_u.u6_addr16
75 # endif
76 # define HAVE_IN6_S6_ADDR16 1
77 # endif
78 # endif
79 # include <netdb.h> /* defines struct hostent, declares gethostbyname() */
80 #endif
82 /* Include this after <sys/socket.h>, to avoid a syntax error on BeOS. */
83 #include <stdbool.h>
85 #include "closeout.h"
86 #include "error.h"
87 #include "error-progname.h"
88 #include "progname.h"
89 #include "relocatable.h"
90 #include "basename.h"
91 #include "xalloc.h"
92 #include "exit.h"
93 #include "gettext.h"
95 #define _(str) gettext (str)
98 /* Output format. */
99 static enum { default_format, short_format, long_format, ip_format } format;
101 /* Long options. */
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' },
110 { NULL, 0, NULL, 0 }
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))
118 #endif
120 static void print_hostname (void);
123 main (int argc, char *argv[])
125 int optchar;
126 bool do_help;
127 bool do_version;
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, "");
136 #endif
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. */
146 do_help = false;
147 do_version = false;
148 format = default_format;
150 /* Parse command line options. */
151 while ((optchar = getopt_long (argc, argv, "fhisV", long_options, NULL))
152 != EOF)
153 switch (optchar)
155 case '\0': /* Long option. */
156 break;
157 case 'f':
158 format = long_format;
159 break;
160 case 's':
161 format = short_format;
162 break;
163 case 'i':
164 format = ip_format;
165 break;
166 case 'h':
167 do_help = true;
168 break;
169 case 'V':
170 do_version = true;
171 break;
172 default:
173 usage (EXIT_FAILURE);
174 /* NOTREACHED */
177 /* Version information requested. */
178 if (do_version)
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\
186 "2001-2003");
187 printf (_("Written by %s.\n"), "Bruno Haible");
188 exit (EXIT_SUCCESS);
191 /* Help is requested. */
192 if (do_help)
193 usage (EXIT_SUCCESS);
195 /* Test for extraneous arguments. */
196 if (optind != argc)
197 error (EXIT_FAILURE, 0, _("too many arguments"));
199 /* Get and print the hostname. */
200 print_hostname ();
202 exit (EXIT_SUCCESS);
205 /* Display usage information and exit. */
206 static void
207 usage (int status)
209 if (status != EXIT_SUCCESS)
210 fprintf (stderr, _("Try `%s --help' for more information.\n"),
211 program_name);
212 else
214 printf (_("\
215 Usage: %s [OPTION]\n\
216 "), program_name);
217 printf ("\n");
218 printf (_("\
219 Print the machine's hostname.\n"));
220 printf ("\n");
221 printf (_("\
222 Output format:\n"));
223 printf (_("\
224 -s, --short short host name\n"));
225 printf (_("\
226 -f, --fqdn, --long long host name, includes fully qualified domain\n\
227 name, and aliases\n"));
228 printf (_("\
229 -i, --ip-address addresses for the hostname\n"));
230 printf ("\n");
231 printf (_("\
232 Informative output:\n"));
233 printf (_("\
234 -h, --help display this help and exit\n"));
235 printf (_("\
236 -V, --version output version information and exit\n"));
237 printf ("\n");
238 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
239 stdout);
242 exit (status);
245 /* Returns an xmalloc()ed string containing the machine's host name. */
246 static char *
247 xgethostname ()
249 #ifdef WIN32
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);
263 #else
264 struct utsname utsname;
266 if (uname (&utsname) < 0)
267 error (EXIT_FAILURE, errno, _("could not get host name"));
268 return xstrdup (utsname.nodename);
269 #endif
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'. */
274 #if HAVE_INET_NTOP
275 # define ipv4_ntop(buffer,addr) \
276 inet_ntop (AF_INET, &addr, buffer, 15+1)
277 #else
278 # define ipv4_ntop(buffer,addr) \
279 strcpy (buffer, inet_ntoa (addr))
280 #endif
282 #if HAVE_IPV6
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'. */
285 # if HAVE_INET_NTOP
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]))
299 # else
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])
310 # endif
311 #endif
313 /* Print the hostname according to the specified format. */
314 static void
315 print_hostname ()
317 char *hostname;
318 char *dot;
319 #if HAVE_GETHOSTBYNAME
320 struct hostent *h;
321 size_t i;
322 #endif
324 hostname = xgethostname ();
326 switch (format)
328 case default_format:
329 /* Print the hostname, as returned by the system call. */
330 printf ("%s\n", hostname);
331 break;
333 case short_format:
334 /* Print only the part before the first dot. */
335 dot = strchr (hostname, '.');
336 if (dot != NULL)
337 *dot = '\0';
338 printf ("%s\n", hostname);
339 break;
341 case long_format:
342 /* Look for netwide usable hostname and aliases using gethostbyname(). */
343 #if HAVE_GETHOSTBYNAME
344 h = gethostbyname (hostname);
345 if (h != NULL)
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]);
352 else
353 #endif
354 printf ("%s\n", hostname);
355 break;
357 case ip_format:
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++)
364 #if HAVE_IPV6
365 if (h->h_addrtype == AF_INET6)
367 char buffer[45+1];
368 ipv6_ntop (buffer, *(const struct in6_addr*) h->h_addr_list[i]);
369 printf("[%s]\n", buffer);
371 else
372 #endif
373 if (h->h_addrtype == AF_INET)
375 char buffer[15+1];
376 ipv4_ntop (buffer, *(const struct in_addr*) h->h_addr_list[i]);
377 printf("[%s]\n", buffer);
380 #endif
381 break;
383 default:
384 abort ();