Package: hostname
Version: 3.01
Severity: wishlist
Tags: patch

Hi,

The options --fqdn, --domain and --ip-address are problematic because
they all assume that the output of gethostname(3) can be resolved by the
DNS, and that a machine has only one FQDN/domain/address.

The following patch tries to improve the situation by introducing two
new options: --all-fqdns and --all-ip-addresses that do not depend on
the value of gethostname(3) but properly enumerate the configured
network interfaces/addresses instead. At the same time, warnings are
added to the man page not to use the old --fqdn, --domain and
--ip-address options.

I left the French man page untouched as I do not speak the language.

I've tested it on some machines with multiple interfaces and multiple
IPv4 addresses on every interface, and it seems to work fine. I could
not test it with IPv6, but I do not expect any real issues.

Gabor

diff -u -r hostname-3.01/hostname.1 hostname-3.01-new/hostname.1
--- hostname-3.01/hostname.1    2009-09-22 14:21:50.000000000 +0200
+++ hostname-3.01-new/hostname.1        2009-12-28 12:08:15.807846478 +0100
@@ -21,8 +21,12 @@
 .RB [ \-\-domain ]
 .RB [ \-f ]
 .RB [ \-\-fqdn ]
+.RB [ \-A ]
+.RB [ \-\-all-fqdns ]
 .RB [ \-i ]
 .RB [ \-\-ip-address ]
+.RB [ \-I ]
+.RB [ \-\-all-ip-addresses ]
 .RB [ \-\-long ]
 .RB [ \-s ]
 .RB [ \-\-short ]
@@ -89,7 +93,10 @@
 .B dnsdomainname
 will print the domain part of the FQDN (Fully Qualified Domain Name). The
 complete FQDN of the system is returned with
-.BR "hostname \-\-fqdn" .
+.BR "hostname \-\-fqdn"
+(but see the warnings in section
+.B "THE FQDN"
+below).
 
 .SS "SET NAME"
 When called with one argument or with the
@@ -142,6 +149,16 @@
 how you can change it. Usually (if the hosts file is parsed before DNS or
 NIS) you can change it in
 .IR /etc/hosts .
+.LP
+If a machine has multiple network interfaces/addresses or is used in a
+mobile environment, then it may either have multiple FQDNs/domain names
+or none at all. Therefore avoid using
+.BR "hostname \-\-fqdn" ,
+.BR "hostname \-\-domain"
+and
+.BR "dnsdomainname" .
+.BR "hostname \-\-ip-address"
+is subject to the same limitations so it should be avoided as well.
 
 .SH OPTIONS
 .TP
@@ -160,7 +177,9 @@
 to get the DNS domain name because it will show the NIS domain name and
 not the DNS domain name. Use
 .B dnsdomainname
-instead.
+instead. Ssee the warnings in section
+.B "THE FQDN"
+above, and avoid using this option.
 .TP
 .I "\-F, \-\-file filename"
 Read the host name from the specified file. Comments (lines starting with
@@ -170,13 +189,36 @@
 Display the FQDN (Fully Qualified Domain Name). A FQDN consists of a
 short host name and the DNS domain name. Unless you are using bind or NIS
 for host lookups you can change the FQDN and the DNS domain name (which is
-part of the FQDN) in the \fI/etc/hosts\fR file.
+part of the FQDN) in the \fI/etc/hosts\fR file. See the warnings in section
+.B "THE FQDN"
+above, and avoid using this option; use
+.BR "hostname \-\-all-fqdns"
+instead.
+.TP
+.I "\-A, \-\-all-fqdns"
+Displays all FQDNs of the machine. This option enumerates all configured
+network addresses on all configured network interfaces, and translates
+them to DNS domain names. Addresses that cannot be translated (i.e. because
+they do not have an appropriate reverse DNS entry) are skipped. Note that
+different addresses may resolve to the same name, therefore the output may
+contain duplicate entries. Do not make any assumptions about the order of the
+output.
 .TP
 .I "\-h, \-\-help"
 Print a usage message and exit.
 .TP
 .I "\-i, \-\-ip-address"
-Display the network address(es) of the host.
+Display the network address(es) of the host name. Note that this works only
+if the host name can be resolved. Avoid using this option; use
+.BR "hostname \-\-all-ip-addresses"
+instead.
+.TP
+.I "\-I, \-\-all-ip-addresses"
+Display all network addresses of the host. This option enumerates all
+configured addresses on all network interfaces. The loopback interface and IPv6
+link-local addresses are omitted. Contrary to option \fI-i\fR, this option
+does not depend on name resolution. Do not make any assumptions about the
+order of the output.
 .TP
 .I "\-s, \-\-short"
 Display the short host name. This is the host name cut at the first dot.
diff -u -r hostname-3.01/hostname.c hostname-3.01-new/hostname.c
--- hostname-3.01/hostname.c    2009-10-27 13:19:28.000000000 +0100
+++ hostname-3.01-new/hostname.c        2009-12-28 11:54:50.911346554 +0100
@@ -3,7 +3,7 @@
  *             that maintains the host name and the domain name. It
  *             is also used to show the FQDN and the IP-Addresses.
  *
- * Usage:      hostname [-d|-f|-s|-a|-i|-y]
+ * Usage:      hostname [-d|-f|-s|-a|-i|-y|-A|-I]
  *             hostname [-h|-V]
  *             hostname [-b] {name|-F file}
  *             dnsdomainname
@@ -31,6 +31,8 @@
 #include <sys/stat.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <ifaddrs.h>
+#include <net/if.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -45,7 +47,7 @@
 
 #define VERSION "3.00"
 
-enum type_t { DEFAULT, DNS, FQDN, SHORT, ALIAS, IP, NIS, NIS_DEF };
+enum type_t { DEFAULT, DNS, FQDN, SHORT, ALIAS, IP, NIS, NIS_DEF, ALL_FQDNS, 
ALL_IPS };
 
 char *progname;
 
@@ -151,7 +153,7 @@
 {
        fprintf(stream,
                "Usage: hostname [-v] [-b] {hostname|-F file}         set host 
name (from file)\n"
-               "       hostname [-v] [-d|-f|-s|-a|-i|-y]             display 
formatted name\n"
+               "       hostname [-v] [-d|-f|-s|-a|-i|-y|-A|-I]       display 
formatted name(s)\n"
                "       hostname [-v]                                 display 
host name\n"
                "\n"
                "       {yp,nis,}domainname [-v] {nisdomain|-F file}  set NIS 
domain name (from file)\n"
@@ -166,14 +168,16 @@
                "       dnsdomainname=hostname -d\n"
                "\n"
                "Program options:\n"
-               "    -s, --short           short host name\n"
-               "    -a, --alias           alias names\n"
-               "    -i, --ip-address      addresses for the host name\n"
-               "    -f, --fqdn, --long    long host name (FQDN)\n"
-               "    -d, --domain          DNS domain name\n"
-               "    -y, --yp, --nis       NIS/YP domain name\n"
-               "    -b, --boot            set default hostname if none 
available\n"
-               "    -F, --file            read host name or NIS domain name 
from given file\n"
+               "    -s, --short            short host name\n"
+               "    -a, --alias            alias names\n"
+               "    -i, --ip-address       addresses for the host name\n"
+               "    -I, --all-ip-addresses all addresses for the host\n"
+               "    -f, --fqdn, --long     long host name (FQDN)\n"
+               "    -A, --all-fqdns        all long host names (FQDNs)\n"
+               "    -d, --domain           DNS domain name\n"
+               "    -y, --yp, --nis        NIS/YP domain name\n"
+               "    -b, --boot             set default hostname if none 
available\n"
+               "    -F, --file             read host name or NIS domain name 
from given file\n"
                "\n"
                "Description:\n"
                "   This command can get or set the host name or the NIS domain 
name. You can\n"
@@ -249,6 +253,7 @@
 {
        struct addrinfo *res;
        struct addrinfo hints;
+       struct ifaddrs *ifa, *ifap;
        char *p;
        int ret;
 
@@ -265,6 +270,57 @@
                case NIS_DEF:
                        printf("%s\n", localnisdomain());
                        break;
+               case ALL_IPS:
+               case ALL_FQDNS: {
+                       char buf[INET6_ADDRSTRLEN];
+                       int flags, ret, family, addrlen;
+
+                       /* What kind of information do we want from 
getnameinfo()? */
+                       flags = (type == ALL_IPS) ? NI_NUMERICHOST : 
NI_NAMEREQD;
+
+                       if (getifaddrs(&ifa) != 0)
+                               errx(1, "%s", strerror(errno));
+                       for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
+                               /* Skip interfaces that have no configured 
addresses */
+                               if (ifap->ifa_addr == NULL)
+                                       continue;
+                               /* Skip the loopback interface */
+                               if (ifap->ifa_flags & IFF_LOOPBACK)
+                                       continue;
+                               /* Skip interfaces that are not UP */
+                               if (!(ifap->ifa_flags & IFF_UP))
+                                       continue;
+
+                               /* Only handle IPv4 and IPv6 addresses */
+                               family = ifap->ifa_addr->sa_family;
+                               if (family != AF_INET && family != AF_INET6)
+                                       continue;
+
+                               addrlen = (family == AF_INET) ? sizeof(struct 
sockaddr_in) :
+                                                               sizeof(struct 
sockaddr_in6);
+
+                               /* Skip IPv6 link-local addresses */
+                               if (family == AF_INET6) {
+                                       struct sockaddr_in6 *sin6;
+
+                                       sin6 = (struct sockaddr_in6 
*)ifap->ifa_addr;
+                                       if 
(IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
+                                                       
IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))
+                                               continue;
+                               }
+
+                               ret = getnameinfo(ifap->ifa_addr, addrlen,
+                                                 buf, sizeof(buf), NULL, 0, 
flags);
+
+                               /* Just skip addresses that cannot be 
translated */
+                               if (ret != 0 && (type != ALL_FQDNS || ret != 
EAI_NONAME))
+                                       errx(1, "%s", gai_strerror(ret));
+
+                               printf("%s\n", buf);
+                       }
+                       freeifaddrs(ifa);
+                       break;
+               }
                default:
                        memset(&hints, 0, sizeof(struct addrinfo));
                        hints.ai_socktype = SOCK_DGRAM;
@@ -376,6 +432,7 @@
                {"boot", no_argument, 0, 'b'},
                {"file", required_argument, 0, 'F'},
                {"fqdn", no_argument, 0, 'f'},
+               {"all-fqdns", no_argument, 0, 'A'},
                {"help", no_argument, 0, 'h'},
                {"long", no_argument, 0, 'f'},
                {"short", no_argument, 0, 's'},
@@ -383,6 +440,7 @@
                {"verbose", no_argument, 0, 'v'},
                {"alias", no_argument, 0, 'a'},
                {"ip-address", no_argument, 0, 'i'},
+               {"all-ip-addresses", no_argument, 0, 'I'},
                {"nis", no_argument, 0, 'y'},
                {"yp", no_argument, 0, 'y'},
                {0, 0, 0, 0}
@@ -399,7 +457,7 @@
        else if (!strcmp(progname, "nisdomainname"))
                type = NIS_DEF;
 
-       while((o = getopt_long(argc, argv, "adfbF:h?isVvy", long_options, 
NULL)) != -1)
+       while((o = getopt_long(argc, argv, "aAdfbF:h?iIsVvy", long_options, 
NULL)) != -1)
                switch (o) {
                case 'd':
                        type = DNS;
@@ -410,9 +468,15 @@
                case 'f':
                        type = FQDN;
                        break;
+               case 'A':
+                       type = ALL_FQDNS;
+                       break;
                case 'i':
                        type = IP;
                        break;
+               case 'I':
+                       type = ALL_IPS;
+                       break;
                case 's':
                        type = SHORT;
                        break;

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'stable'), (110, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.31.6 (SMP w/2 CPU cores; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages hostname depends on:
ii  libc6                         2.10.2-2   GNU C Library: Shared libraries

hostname recommends no packages.

hostname suggests no packages.

-- no debconf information



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to