1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * University Copyright- Copyright (c) 1982, 1986, 1988
  24  * The Regents of the University of California
  25  * All Rights Reserved
  26  *
  27  * University Acknowledgment- Portions of this document are derived from
  28  * software developed by the University of California, Berkeley, and its
  29  * contributors.
  30  */
  31 
  32 /*
  33  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  34  * Use is subject to license terms.
  35  *
  36  * Copyright 2016 RackTop Systems.
  37  */
  38 
  39 /* Portions Copyright 2007 Jeremy Teo */
  40 /* Portions Copyright 2006 Stephen P. Potter */
  41 
  42 #include <unistd.h>
  43 #include <stdio.h>
  44 #include <string.h>
  45 #include <locale.h>
  46 #include <libgen.h>
  47 #include <stdlib.h>
  48 #include <errno.h>
  49 #include <netdb.h>
  50 #include <getopt.h>
  51 
  52 #ifndef TEXT_DOMAIN             /* should be defined by cc -D */
  53 #define TEXT_DOMAIN "SYS_TEST"  /* use this only if it wasn't */
  54 #endif
  55 
  56 static char *progname;
  57 
  58 static void
  59 usage(void)
  60 {
  61         (void) fprintf(stderr, gettext("usage: %s [-fls|system_name]\n"),
  62                 basename(progname));
  63         exit(1);
  64 }
  65 
  66 int
  67 main(int argc, char *argv[])
  68 {
  69         char    *nodename = NULL;
  70         char    c_hostname[MAXHOSTNAMELEN];
  71         int     optlet, optindex = 0;
  72         char    *optstring = "fls";
  73         int     fflag = 0, lflag = 0, sflag = 0;
  74         struct  option long_options[] = {
  75                 {"fqdn",        no_argument,    0,      'f'     },
  76                 {"long",        no_argument,    0,      'l'     },
  77                 {"short",       no_argument,    0,      's'     },
  78                 {NULL,          0,              0,      0       }
  79         };
  80 
  81         (void) setlocale(LC_ALL, "");
  82         (void) textdomain(TEXT_DOMAIN);
  83 
  84         progname = argv[0];
  85 
  86         opterr = 0;
  87         while ((optlet = getopt_long(argc, argv, optstring, long_options,
  88             &optindex)) != -1) {
  89                 switch (optlet) {
  90                 case 'f':
  91                         fflag++;
  92                         break;
  93                 case 'l':
  94                         lflag++;
  95                         break;
  96                 case 's':
  97                         sflag++;
  98                         break;
  99                 case '?':
 100                         usage();
 101                 }
 102         }
 103 
 104         /* No flag combinations allowed */
 105         if (fflag && (lflag || sflag))
 106                 usage();
 107         if (lflag && (fflag || sflag))
 108                 usage();
 109         if (sflag && (lflag || fflag))
 110                 usage();
 111 
 112         /*
 113          * if called with no options, just print out the hostname/nodename
 114          */
 115         if (argc <= optind) {
 116                 if (gethostname(c_hostname, sizeof (c_hostname)) < 0) {
 117                         (void) fprintf(stderr,
 118                             gettext("%s: unable to obtain hostname\n"),
 119                             basename(progname));
 120                         exit(1);
 121                 }
 122                 if (fflag || lflag) {
 123                         struct addrinfo hints, *info;
 124                         memset(&hints, 0, sizeof (struct addrinfo));
 125                         hints.ai_socktype = SOCK_DGRAM;
 126                         hints.ai_flags = AI_CANONNAME;
 127                         if (getaddrinfo(c_hostname, NULL, &hints, &info) != 0) {
 128                                 (void) fprintf(stderr,
 129                                     gettext("%s: unable to obtain fqdn\n"),
 130                                     basename(progname));
 131                                 exit(1);
 132                         }
 133                         (void) fprintf(stdout, "%s\n", info->ai_canonname);
 134                 } else {
 135                         if (sflag) {
 136                                 char *p = strchr(c_hostname, '.');
 137                                 if (p != NULL)
 138                                         *p = '\0';
 139                         }
 140                         (void) fprintf(stdout, "%s\n", c_hostname);
 141                 }
 142         } else {
 143                 /*
 144                  * if called with an argument,
 145                  * we have to try to set the new hostname/nodename
 146                  */
 147                 if (argc > optind + 1)
 148                         usage();        /* too many arguments */
 149                 if (fflag || lflag)
 150                         usage();        /* can't set fqdn this way */
 151                 if (sflag)
 152                         usage();        /* can't set short name */
 153                 nodename = argv[optind];
 154                 if (sethostname(nodename, strlen(nodename)) < 0) {
 155                         int err = errno;
 156                         (void) fprintf(stderr,
 157                             gettext("%s: error in setting name: %s\n"),
 158                             basename(progname), strerror(err));
 159                         exit(1);
 160                 }
 161         }
 162         return (0);
 163 }