From: Bruno Haible Date: Thu, 25 Oct 2001 09:17:18 +0000 (+0000) Subject: New program 'hostname'. X-Git-Tag: v0.11~417 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edb61fb369fd98aa7ba73b3b41d96f2e614b9017;p=thirdparty%2Fgettext.git New program 'hostname'. --- diff --git a/ChangeLog b/ChangeLog index d207a8f6e..d747d2fb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2001-09-29 Bruno Haible + + * configure.in: Call gt_PREREQ_HOSTNAME. + 2001-09-25 Bruno Haible Upgrade to automake-1.5. diff --git a/configure.in b/configure.in index 0fd11eeea..aa3ac8111 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/m4/ChangeLog b/m4/ChangeLog index c6da42597..54e7b2625 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,8 @@ +2001-09-29 Bruno Haible + + * hostname.m4: New file. + * Makefile.am (EXTRA_DIST): Add it. + 2001-10-10 Bruno Haible * javacomp.m4 (gt_JAVACOMP): Ignore gcj version 2.xx, require at least diff --git a/m4/Makefile.am b/m4/Makefile.am index 41434b5ad..551cfdfd5 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -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 index 000000000..aefc8651d --- /dev/null +++ b/m4/hostname.m4 @@ -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 +#include +#include ], +[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 defines AF_INET6.]) + fi +]) diff --git a/src/ChangeLog b/src/ChangeLog index 4f300e587..9f12c57b0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2001-09-29 Bruno Haible + + * 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 * msgexec.c (process_string): Update for changed create_pipe_bidi(), diff --git a/src/Makefile.am b/src/Makefile.am index 07c1f9243..f266c8c50 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 000000000..d94374a75 --- /dev/null +++ b/src/hostname.c @@ -0,0 +1,360 @@ +/* Display hostname in various forms. + Copyright (C) 2001 Free Software Foundation, Inc. + Written by Bruno Haible , 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 +#include +#include +#include +#include +#include + +#if defined _WIN32 || defined __WIN32__ +# undef WIN32 /* avoid warning on mingw32 */ +# define WIN32 +#endif + +/* Get gethostname(). */ +#if HAVE_UNISTD_H +# include +#endif + +/* Some systems, like early Solaris versions, lack gethostname() but + have uname() instead. */ +#if !HAVE_GETHOSTNAME +# include +#endif + +/* Get MAXHOSTNAMELEN. */ +#include +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif + +/* Support for using gethostbyname(). */ +#if HAVE_GETHOSTBYNAME +# include +# include /* defines AF_INET, AF_INET6 */ +# include /* declares ntohs(), defines struct sockaddr_in */ +# if HAVE_ARPA_INET_H +# include /* 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 /* defines struct hostent, declares gethostbyname() */ +#endif + +/* Include this after , to avoid a syntax error on BeOS. */ +#include + +#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 .\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 (); + } +}