Print this page
3758 RFE: Would like "hostname -s"
3430 Support "hostname --fqdn"

@@ -30,80 +30,128 @@
  */
 
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2016 RackTop Systems.
  */
 
 /* Portions Copyright 2007 Jeremy Teo */
 /* Portions Copyright 2006 Stephen P. Potter */
-#pragma ident   "%Z%%M% %I%     %E% SMI"
 
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <locale.h>
 #include <libgen.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <netdb.h>
+#include <getopt.h>
 
 #ifndef TEXT_DOMAIN             /* should be defined by cc -D */
 #define TEXT_DOMAIN "SYS_TEST"  /* use this only if it wasn't */
 #endif
 
 static char *progname;
 
 static void
 usage(void)
 {
-        (void) fprintf(stderr, gettext("usage: %s [system_name]\n"),
+        (void) fprintf(stderr, gettext("usage: %s [-fls|system_name]\n"),
                 basename(progname));
         exit(1);
 }
 
 int
 main(int argc, char *argv[])
 {
         char    *nodename = NULL;
         char    c_hostname[MAXHOSTNAMELEN];
-        int     optlet;
-        char    *optstring = "?";
+        int     optlet, optindex = 0;
+        char    *optstring = "fls";
+        int     fflag = 0, lflag = 0, sflag = 0;
+        struct  option long_options[] = {
+                {"fqdn",        no_argument,    0,      'f'     },
+                {"long",        no_argument,    0,      'l'     },
+                {"short",       no_argument,    0,      's'     },
+                {NULL,          0,              0,      0       }
+        };
 
         (void) setlocale(LC_ALL, "");
         (void) textdomain(TEXT_DOMAIN);
 
         progname = argv[0];
 
         opterr = 0;
-        while ((optlet = getopt(argc, argv, optstring)) != -1) {
+        while ((optlet = getopt_long(argc, argv, optstring, long_options,
+            &optindex)) != -1) {
                 switch (optlet) {
+                case 'f':
+                        fflag++;
+                        break;
+                case 'l':
+                        lflag++;
+                        break;
+                case 's':
+                        sflag++;
+                        break;
                 case '?':
                         usage();
                 }
         }
 
+        /* No flag combinations allowed */
+        if (fflag && (lflag || sflag))
+                usage();
+        if (lflag && (fflag || sflag))
+                usage();
+        if (sflag && (lflag || fflag))
+                usage();
+
         /*
          * if called with no options, just print out the hostname/nodename
          */
         if (argc <= optind) {
                 if (gethostname(c_hostname, sizeof (c_hostname)) < 0) {
                         (void) fprintf(stderr,
                             gettext("%s: unable to obtain hostname\n"),
                             basename(progname));
                         exit(1);
+                }
+                if (fflag || lflag) {
+                        struct addrinfo hints, *info;
+                        memset(&hints, 0, sizeof (struct addrinfo));
+                        hints.ai_socktype = SOCK_DGRAM;
+                        hints.ai_flags = AI_CANONNAME;
+                        if (getaddrinfo(c_hostname, NULL, &hints, &info) != 0) {
+                                (void) fprintf(stderr,
+                                    gettext("%s: unable to obtain fqdn\n"),
+                                    basename(progname));
+                                exit(1);
+                        }
+                        (void) fprintf(stdout, "%s\n", info->ai_canonname);
                 } else {
+                        if (sflag) {
+                                char *p = strchr(c_hostname, '.');
+                                if (p != NULL)
+                                        *p = '\0';
+                        }
                         (void) fprintf(stdout, "%s\n", c_hostname);
                 }
         } else {
                 /*
                  * if called with an argument,
                  * we have to try to set the new hostname/nodename
                  */
                 if (argc > optind + 1)
                         usage();        /* too many arguments */
-
+                if (fflag || lflag)
+                        usage();        /* can't set fqdn this way */
+                if (sflag)
+                        usage();        /* can't set short name */
                 nodename = argv[optind];
                 if (sethostname(nodename, strlen(nodename)) < 0) {
                         int err = errno;
                         (void) fprintf(stderr,
                             gettext("%s: error in setting name: %s\n"),