~ubuntu-branches/ubuntu/breezy/gettext/breezy

« back to all changes in this revision

Viewing changes to gettext-tools/src/hostname.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-03-14 17:40:02 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040314174002-p1ad5ldve1hqzhye
Tags: 0.14.1-2
* Added libexpat1-dev to Build-Depends, for glade support.
* Added libc0.1-dev to Build-Depends, for GNU/kFreeBSD.
* Removed special-casing of knetbsd-gnu in debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
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 2, or (at your option)
 
8
   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, write to the Free Software Foundation,
 
17
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
18
 
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
# include "config.h"
 
22
#endif
 
23
 
 
24
#include <errno.h>
 
25
#include <getopt.h>
 
26
#include <stdio.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <locale.h>
 
30
 
 
31
#if defined _WIN32 || defined __WIN32__
 
32
# undef WIN32   /* avoid warning on mingw32 */
 
33
# define WIN32
 
34
#endif
 
35
 
 
36
/* Get gethostname().  */
 
37
#if HAVE_UNISTD_H
 
38
# include <unistd.h>
 
39
#endif
 
40
 
 
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
 
51
 
 
52
/* Get MAXHOSTNAMELEN.  */
 
53
#include <sys/param.h>
 
54
#ifndef MAXHOSTNAMELEN
 
55
# define MAXHOSTNAMELEN 64
 
56
#endif
 
57
 
 
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
 
81
 
 
82
/* Include this after <sys/socket.h>, to avoid a syntax error on BeOS.  */
 
83
#include <stdbool.h>
 
84
 
 
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"
 
94
 
 
95
#define _(str) gettext (str)
 
96
 
 
97
 
 
98
/* Output format.  */
 
99
static enum { default_format, short_format, long_format, ip_format } format;
 
100
 
 
101
/* Long options.  */
 
102
static const struct option long_options[] =
 
103
{
 
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 }
 
111
};
 
112
 
 
113
 
 
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
 
119
;
 
120
static void print_hostname (void);
 
121
 
 
122
int
 
123
main (int argc, char *argv[])
 
124
{
 
125
  int optchar;
 
126
  bool do_help;
 
127
  bool do_version;
 
128
 
 
129
  /* Set program name for messages.  */
 
130
  set_program_name (argv[0]);
 
131
  error_print_progname = maybe_print_progname;
 
132
 
 
133
#ifdef HAVE_SETLOCALE
 
134
  /* Set locale via LC_ALL.  */
 
135
  setlocale (LC_ALL, "");
 
136
#endif
 
137
 
 
138
  /* Set the text message domain.  */
 
139
  bindtextdomain (PACKAGE, relocate (LOCALEDIR));
 
140
  textdomain (PACKAGE);
 
141
 
 
142
  /* Ensure that write errors on stdout are detected.  */
 
143
  atexit (close_stdout);
 
144
 
 
145
  /* Set default values for variables.  */
 
146
  do_help = false;
 
147
  do_version = false;
 
148
  format = default_format;
 
149
 
 
150
  /* Parse command line options.  */
 
151
  while ((optchar = getopt_long (argc, argv, "fhisV", long_options, NULL))
 
152
         != EOF)
 
153
    switch (optchar)
 
154
    {
 
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 */
 
175
    }
 
176
 
 
177
  /* Version information requested.  */
 
178
  if (do_version)
 
179
    {
 
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\
 
185
"),
 
186
              "2001-2003");
 
187
      printf (_("Written by %s.\n"), "Bruno Haible");
 
188
      exit (EXIT_SUCCESS);
 
189
    }
 
190
 
 
191
  /* Help is requested.  */
 
192
  if (do_help)
 
193
    usage (EXIT_SUCCESS);
 
194
 
 
195
  /* Test for extraneous arguments.  */
 
196
  if (optind != argc)
 
197
    error (EXIT_FAILURE, 0, _("too many arguments"));
 
198
 
 
199
  /* Get and print the hostname.  */
 
200
  print_hostname ();
 
201
 
 
202
  exit (EXIT_SUCCESS);
 
203
}
 
204
 
 
205
/* Display usage information and exit.  */
 
206
static void
 
207
usage (int status)
 
208
{
 
209
  if (status != EXIT_SUCCESS)
 
210
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
 
211
             program_name);
 
212
  else
 
213
    {
 
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);
 
240
    }
 
241
 
 
242
  exit (status);
 
243
}
 
244
 
 
245
/* Returns an xmalloc()ed string containing the machine's host name.  */
 
246
static char *
 
247
xgethostname ()
 
248
{
 
249
#ifdef WIN32
 
250
  char hostname[MAX_COMPUTERNAME_LENGTH+1];
 
251
  DWORD size = sizeof (hostname);
 
252
 
 
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];
 
258
 
 
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;
 
265
 
 
266
  if (uname (&utsname) < 0)
 
267
    error (EXIT_FAILURE, errno, _("could not get host name"));
 
268
  return xstrdup (utsname.nodename);
 
269
#endif
 
270
}
 
271
 
 
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
 
281
 
 
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
 
312
 
 
313
/* Print the hostname according to the specified format.  */
 
314
static void
 
315
print_hostname ()
 
316
{
 
317
  char *hostname;
 
318
  char *dot;
 
319
#if HAVE_GETHOSTBYNAME
 
320
  struct hostent *h;
 
321
  size_t i;
 
322
#endif
 
323
 
 
324
  hostname = xgethostname ();
 
325
 
 
326
  switch (format)
 
327
    {
 
328
    case default_format:
 
329
      /* Print the hostname, as returned by the system call.  */
 
330
      printf ("%s\n", hostname);
 
331
      break;
 
332
 
 
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;
 
340
 
 
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)
 
346
        {
 
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]);
 
351
        }
 
352
      else
 
353
#endif
 
354
        printf ("%s\n", hostname);
 
355
      break;
 
356
 
 
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++)
 
363
          {
 
364
#if HAVE_IPV6
 
365
            if (h->h_addrtype == AF_INET6)
 
366
              {
 
367
                char buffer[45+1];
 
368
                ipv6_ntop (buffer, *(const struct in6_addr*) h->h_addr_list[i]);
 
369
                printf("[%s]\n", buffer);
 
370
              }
 
371
            else
 
372
#endif
 
373
            if (h->h_addrtype == AF_INET)
 
374
              {
 
375
                char buffer[15+1];
 
376
                ipv4_ntop (buffer, *(const struct in_addr*) h->h_addr_list[i]);
 
377
                printf("[%s]\n", buffer);
 
378
              }
 
379
          }
 
380
#endif
 
381
      break;
 
382
 
 
383
    default:
 
384
      abort ();
 
385
    }
 
386
}