]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
New program 'hostname'.
authorBruno Haible <bruno@clisp.org>
Thu, 25 Oct 2001 09:17:18 +0000 (09:17 +0000)
committerBruno Haible <bruno@clisp.org>
Thu, 25 Oct 2001 09:17:18 +0000 (09:17 +0000)
ChangeLog
configure.in
m4/ChangeLog
m4/Makefile.am
m4/hostname.m4 [new file with mode: 0644]
src/ChangeLog
src/Makefile.am
src/hostname.c [new file with mode: 0644]

index d207a8f6e8195b6c6134e16baf490e73df1fd10f..d747d2fb2dbfbfcaac6a77d51d847162736c6bec 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2001-09-29  Bruno Haible  <haible@clisp.cons.org>
+
+       * configure.in: Call gt_PREREQ_HOSTNAME.
+
 2001-09-25  Bruno Haible  <haible@clisp.cons.org>
 
        Upgrade to automake-1.5.
index 0fd11eeea314e6b690c173624b665c227e69db3a..aa3ac81118fcc4fc51b3d7b9fa7caa3c2f2099c3 100644 (file)
@@ -88,6 +88,8 @@ AM_FUNC_ERROR_AT_LINE
 
 gt_SETLOCALE
 
+gt_PREREQ_HOSTNAME
+
 dnl These are the only lines required to internationalize the package.
 dnl (OK, not quite, the AC_OUTPUT has also some parts.)
 AM_GNU_GETTEXT(use-libtool, need-ngettext)
index c6da425978d1b5ef2ad6244770c2eed957492be1..54e7b262518c9c15895a9cb78385d55aad7b33fa 100644 (file)
@@ -1,3 +1,8 @@
+2001-09-29  Bruno Haible  <haible@clisp.cons.org>
+
+       * hostname.m4: New file.
+       * Makefile.am (EXTRA_DIST): Add it.
+
 2001-10-10  Bruno Haible  <haible@clisp.cons.org>
 
        * javacomp.m4 (gt_JAVACOMP): Ignore gcj version 2.xx, require at least
index 41434b5ad34ff9c6fdba96cfe6abd11e3a61f41c..551cfdfd51a5a3293fd6dbe029936ebe2c9f1e05 100644 (file)
@@ -8,7 +8,8 @@ aclocal_DATA = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.
 #   |sed 's/@$/%/;s/@/ \\@/g' |tr @% '\012\012'
 EXTRA_DIST = README \
 backupfile.m4 c-bs-a.m4 codeset.m4 flex.m4 getline.m4 gettext.m4 \
-glibc21.m4 iconv.m4 inttypes_h.m4 isc-posix.m4 javacomp.m4 javaexec.m4 \
-lcmessage.m4 libtool.m4 mbrtowc.m4 mbstate_t.m4 mbswidth.m4 mkdtemp.m4 \
-progtest.m4 setenv.m4 setlocale.m4 siginfo.m4 signalblocking.m4 signed.m4 \
-ssize_t.m4 stdbool.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 unionwait.m4
+glibc21.m4 hostname.m4 iconv.m4 inttypes_h.m4 isc-posix.m4 javacomp.m4 \
+javaexec.m4 lcmessage.m4 libtool.m4 mbrtowc.m4 mbstate_t.m4 mbswidth.m4 \
+mkdtemp.m4 progtest.m4 setenv.m4 setlocale.m4 siginfo.m4 signalblocking.m4 \
+signed.m4 ssize_t.m4 stdbool.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 \
+unionwait.m4
diff --git a/m4/hostname.m4 b/m4/hostname.m4
new file mode 100644 (file)
index 0000000..aefc865
--- /dev/null
@@ -0,0 +1,22 @@
+#serial 1
+
+# Prerequisites of the hostname.c program.
+AC_DEFUN(gt_PREREQ_HOSTNAME,
+[
+  AC_CHECK_HEADERS(arpa/inet.h)
+  AC_CHECK_FUNCS(gethostname gethostbyname inet_ntop)
+
+  AC_MSG_CHECKING([for IPv6 sockets])
+  AC_CACHE_VAL(gt_cv_socket_ipv6,[
+    AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>],
+[int x = AF_INET6; struct in6_addr y; struct sockaddr_in6 z;],
+      gt_cv_socket_ipv6=yes, gt_cv_socket_ipv6=no)
+  ])
+  AC_MSG_RESULT($gt_cv_socket_ipv6)
+  if test $gt_cv_socket_ipv6 = yes; then
+    AC_DEFINE(HAVE_IPV6, 1, [Define if <sys/socket.h> defines AF_INET6.])
+  fi
+])
index 4f300e587a98c123a4f1114850a956308f2e3bc6..9f12c57b0d1207e900b3432aba33488c20141b49 100644 (file)
@@ -1,3 +1,9 @@
+2001-09-29  Bruno Haible  <haible@clisp.cons.org>
+
+       * hostname.c: New file.
+       * Makefile.am (noinst_PROGRAMS, hostname_SOURCES): New variables.
+       (install-exec-local, installdirs-local, uninstall-local): New rules.
+
 2001-10-10  Bruno Haible  <haible@clisp.cons.org>
 
        * msgexec.c (process_string): Update for changed create_pipe_bidi(),
index 07c1f92433ea9cac515e1a48e908ce0bbdeee98b..f266c8c5004da899a215ba86186033d34c4156fc 100644 (file)
@@ -23,6 +23,8 @@ bin_PROGRAMS = gettext ngettext \
 msgcmp msgfmt msgmerge msgunfmt xgettext \
 msgattrib msgcat msgcomm msgconv msgen msgexec msggrep msguniq
 
+noinst_PROGRAMS = hostname
+
 noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \
 po.h open-po.h read-po.h str-list.h write-po.h dir-list.h file-list.h \
 po-gram-gen.h po-hash-gen.h msgl-charset.h msgl-equal.h msgl-iconv.h \
@@ -78,6 +80,7 @@ msgen_SOURCES     = msgen.c     $(COMMON_SOURCE) msgl-ascii.c write-po.c read-po
 msgexec_SOURCES   = msgexec.c   $(COMMON_SOURCE) msgl-ascii.c write-po.c read-po.c msgl-charset.c
 msggrep_SOURCES   = msggrep.c   $(COMMON_SOURCE) msgl-ascii.c write-po.c read-po.c msgl-charset.c
 msguniq_SOURCES   = msguniq.c   $(COMMON_SOURCE) msgl-ascii.c write-po.c read-po.c msgl-iconv.c msgl-cat.c
+hostname_SOURCES  = hostname.c
 
 # Link dependencies.
 # po-lex.c and po.c may need -liconv.
@@ -113,6 +116,19 @@ x-java.c: x-java.l
 DISTCLEANFILES = po-gram-gen2.h
 
 
+# Special rules for installation of auxiliary programs.
+
+install-exec-local:
+       $(mkinstalldirs) $(DESTDIR)$(libdir)/$(PACKAGE)
+       $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) hostname$(EXEEXT) $(DESTDIR)$(libdir)/$(PACKAGE)/hostname$(EXEEXT)
+
+installdirs-local:
+       $(mkinstalldirs) $(DESTDIR)$(libdir)/$(PACKAGE)
+
+uninstall-local:
+       $(RM) $(DESTDIR)$(libdir)/$(PACKAGE)/hostname$(EXEEXT)
+
+
 # Special rules for Java compilation.
 
 all-local: all-java-@BUILDJAVA@
diff --git a/src/hostname.c b/src/hostname.c
new file mode 100644 (file)
index 0000000..d94374a
--- /dev/null
@@ -0,0 +1,360 @@
+/* Display hostname in various forms.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+
+#if defined _WIN32 || defined __WIN32__
+# undef WIN32   /* avoid warning on mingw32 */
+# define WIN32
+#endif
+
+/* Get gethostname().  */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+/* Some systems, like early Solaris versions, lack gethostname() but
+   have uname() instead.  */
+#if !HAVE_GETHOSTNAME
+# include <sys/utsname.h>
+#endif
+
+/* Get MAXHOSTNAMELEN.  */
+#include <sys/param.h>
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 64
+#endif
+
+/* Support for using gethostbyname().  */
+#if HAVE_GETHOSTBYNAME
+# include <sys/types.h>
+# include <sys/socket.h> /* defines AF_INET, AF_INET6 */
+# include <netinet/in.h> /* declares ntohs(), defines struct sockaddr_in */
+# if HAVE_ARPA_INET_H
+#  include <arpa/inet.h> /* declares inet_ntoa(), inet_ntop() */
+# endif
+# if HAVE_IPV6
+#  if defined(__APPLE__) && defined(__MACH__) /* MacOS X */
+#   define in6_u __u6_addr
+#   define u6_addr16 __u6_addr16
+#  endif
+# endif
+# include <netdb.h> /* defines struct hostent, declares gethostbyname() */
+#endif
+
+/* Include this after <sys/socket.h>, to avoid a syntax error on BeOS.  */
+#include <stdbool.h>
+
+#include "error.h"
+#include "basename.h"
+#include "xmalloc.h"
+#include "system.h"
+#include "libgettext.h"
+
+#define _(str) gettext (str)
+
+
+/* Output format.  */
+static enum { default_format, short_format, long_format, ip_format } format;
+
+/* Name the program is called with.  */
+const char *program_name;
+
+/* Long options.  */
+static const struct option long_options[] =
+{
+  { "fqdn", no_argument, NULL, 'f' },
+  { "help", no_argument, NULL, 'h' },
+  { "ip-address", no_argument, NULL, 'i' },
+  { "long", no_argument, NULL, 'f' },
+  { "short", no_argument, NULL, 's' },
+  { "version", no_argument, NULL, 'V' },
+  { NULL, 0, NULL, 0 }
+};
+
+
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status))
+#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
+     __attribute__ ((noreturn))
+#endif
+;
+static char * xgethostname PARAMS ((void));
+static void print_hostname PARAMS ((void));
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  int optchar;
+  bool do_help;
+  bool do_version;
+
+  /* Set program name for messages.  */
+  program_name = argv[0];
+  if (strncmp (program_name, "lt-", 3) == 0)
+    program_name += 3;
+
+#ifdef HAVE_SETLOCALE
+  /* Set locale via LC_ALL.  */
+  setlocale (LC_ALL, "");
+#endif
+
+  /* Set the text message domain.  */
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  /* Set default values for variables.  */
+  do_help = false;
+  do_version = false;
+  format = default_format;
+
+  /* Parse command line options.  */
+  while ((optchar = getopt_long (argc, argv, "fhisV", long_options, NULL))
+        != EOF)
+    switch (optchar)
+    {
+    case '\0':         /* Long option.  */
+      break;
+    case 'f':
+      format = long_format;
+      break;
+    case 's':
+      format = short_format;
+      break;
+    case 'i':
+      format = ip_format;
+      break;
+    case 'h':
+      do_help = true;
+      break;
+    case 'V':
+      do_version = true;
+      break;
+    default:
+      usage (EXIT_FAILURE);
+      /* NOTREACHED */
+    }
+
+  /* Version information requested.  */
+  if (do_version)
+    {
+      printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
+      /* xgettext: no-wrap */
+      printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"),
+              "2001");
+      printf (_("Written by %s.\n"), "Bruno Haible");
+      exit (EXIT_SUCCESS);
+    }
+
+  /* Help is requested.  */
+  if (do_help)
+    usage (EXIT_SUCCESS);
+
+  /* Test for extraneous arguments.  */
+  if (optind != argc)
+    error (EXIT_FAILURE, 0, _("too many arguments"));
+
+  /* Get and print the hostname.  */
+  print_hostname ();
+
+  exit (EXIT_SUCCESS);
+}
+
+/* Display usage information and exit.  */
+static void
+usage (status)
+     int status;
+{
+  if (status != EXIT_SUCCESS)
+    fprintf (stderr, _("Try `%s --help' for more information.\n"),
+            program_name);
+  else
+    {
+      /* xgettext: no-wrap */
+      printf (_("\
+Usage: %s [OPTION]\n\
+"), program_name);
+      printf ("\n");
+      /* xgettext: no-wrap */
+      printf (_("\
+Print the machine's hostname.\n\
+"));
+      printf ("\n");
+      /* xgettext: no-wrap */
+      printf (_("\
+Output format:\n\
+  -s, --short           short host name\n\
+  -f, --fqdn, --long    long host name, includes fully qualified domain name,\n\
+                          and aliases\n\
+  -i, --ip-address      addresses for the hostname\n\
+"));
+      printf ("\n");
+      /* xgettext: no-wrap */
+      printf (_("\
+Informative output:\n\
+  -h, --help                  display this help and exit\n\
+  -V, --version               output version information and exit\n\
+"));
+      printf ("\n");
+      fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
+            stdout);
+    }
+
+  exit (status);
+}
+
+/* Returns an xmalloc()ed string containing the machine's host name.  */
+static char *
+xgethostname ()
+{
+#if HAVE_GETHOSTNAME
+  char hostname[MAXHOSTNAMELEN+1];
+
+  if (gethostname (hostname, MAXHOSTNAMELEN) < 0)
+    error (EXIT_FAILURE, errno, _("could not get host name"));
+  hostname[MAXHOSTNAMELEN] = '\0';
+  return xstrdup (hostname);
+#else
+  struct utsname utsname;
+
+  if (uname (&utsname) < 0)
+    error (EXIT_FAILURE, errno, _("could not get host name"));
+  return xstrdup (utsname.nodename);
+#endif
+}
+
+/* Converts an AF_INET address to a printable, presentable format.
+   BUFFER is an array with at least 15+1 bytes.  ADDR is sockaddr_in.  */
+#if HAVE_INET_NTOP
+# define ipv4_ntop(buffer,addr) \
+    inet_ntop (AF_INET, &addr, buffer, 15+1)
+#else
+# define ipv4_ntop(buffer,addr) \
+    strcpy (buffer, inet_ntoa (addr))
+#endif
+
+#if HAVE_IPV6
+/* Converts an AF_INET6 address to a printable, presentable format.
+   BUFFER is an array with at least 45+1 bytes.  ADDR is sockaddr_in6.  */
+# if HAVE_INET_NTOP
+#  define ipv6_ntop(buffer,addr) \
+     inet_ntop (AF_INET6, &addr, buffer, 45+1)
+# else
+#  define ipv6_ntop(buffer,addr) \
+     sprintf (buffer, "%x:%x:%x:%x:%x:%x:%x:%x", \
+             ntohs ((addr).in6_u.u6_addr16[0]), \
+             ntohs ((addr).in6_u.u6_addr16[1]), \
+             ntohs ((addr).in6_u.u6_addr16[2]), \
+             ntohs ((addr).in6_u.u6_addr16[3]), \
+             ntohs ((addr).in6_u.u6_addr16[4]), \
+             ntohs ((addr).in6_u.u6_addr16[5]), \
+             ntohs ((addr).in6_u.u6_addr16[6]), \
+             ntohs ((addr).in6_u.u6_addr16[7]))
+# endif
+#endif
+
+/* Print the hostname according to the specified format.  */
+static void
+print_hostname ()
+{
+  char *hostname;
+  char *dot;
+#if HAVE_GETHOSTBYNAME
+  struct hostent *h;
+  size_t i;
+#endif
+
+  hostname = xgethostname ();
+
+  switch (format)
+    {
+    case default_format:
+      /* Print the hostname, as returned by the system call.  */
+      printf ("%s\n", hostname);
+      break;
+
+    case short_format:
+      /* Print only the part before the first dot.  */
+      dot = strchr (hostname, '.');
+      if (dot != NULL)
+       *dot = '\0';
+      printf ("%s\n", hostname);
+      break;
+
+    case long_format:
+      /* Look for netwide usable hostname and aliases using gethostbyname().  */
+#if HAVE_GETHOSTBYNAME
+      h = gethostbyname (hostname);
+      if (h != NULL)
+       {
+         printf ("%s\n", h->h_name);
+         if (h->h_aliases != NULL)
+           for (i = 0; h->h_aliases[i] != NULL; i++)
+             printf ("%s\n", h->h_aliases[i]);
+       }
+      else
+#endif
+       printf ("%s\n", hostname);
+      break;
+
+    case ip_format:
+      /* Look for netwide usable IP addresses using gethostbyname().  */
+#if HAVE_GETHOSTBYNAME
+      h = gethostbyname (hostname);
+      if (h != NULL && h->h_addr_list != NULL)
+       for (i = 0; h->h_addr_list[i] != NULL; i++)
+         {
+#if HAVE_IPV6
+           if (h->h_addrtype == AF_INET6)
+             {
+               char buffer[45+1];
+               ipv6_ntop (buffer, *(const struct in6_addr*) h->h_addr_list[i]);
+               printf("[%s]\n", buffer);
+             }
+           else
+#endif
+           if (h->h_addrtype == AF_INET)
+             {
+               char buffer[15+1];
+               ipv4_ntop (buffer, *(const struct in_addr*) h->h_addr_list[i]);
+               printf("[%s]\n", buffer);
+             }
+         }
+#endif
+      break;
+
+    default:
+      abort ();
+    }
+}