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 [-fs|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 = "fs";
  73         int     fflag = 0, sflag = 0;
  74         struct  option long_options[] = {
  75                 {"fqdn",        no_argument,    0,      'f'     },
  76                 {"long",        no_argument,    0,      'f'     },
  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 's':
  94                         sflag++;
  95                         break;
  96                 case '?':
  97                         usage();
  98                 }
  99         }
 100 
 101         /* No flag combinations allowed */
 102         if (fflag && sflag)
 103                 usage();
 104 
 105         /*
 106          * if called with no options, just print out the hostname/nodename
 107          */
 108         if (argc <= optind) {
 109                 if (gethostname(c_hostname, sizeof (c_hostname)) < 0) {
 110                         (void) fprintf(stderr,
 111                             gettext("%s: unable to obtain hostname\n"),
 112                             basename(progname));
 113                         exit(1);
 114                 }
 115                 if (fflag) {
 116                         struct addrinfo hints, *info;
 117                         memset(&hints, 0, sizeof (struct addrinfo));
 118                         hints.ai_socktype = SOCK_DGRAM;
 119                         hints.ai_flags = AI_CANONNAME;
 120                         if (getaddrinfo(c_hostname, NULL, &hints, &info) != 0) {
 121                                 (void) fprintf(stderr,
 122                                     gettext("%s: unable to obtain fqdn\n"),
 123                                     basename(progname));
 124                                 exit(1);
 125                         }
 126                         (void) fprintf(stdout, "%s\n", info->ai_canonname);
 127                 } else {
 128                         if (sflag) {
 129                                 char *p = strchr(c_hostname, '.');
 130                                 if (p != NULL)
 131                                         *p = '\0';
 132                         }
 133                         (void) fprintf(stdout, "%s\n", c_hostname);
 134                 }
 135         } else {
 136                 /*
 137                  * if called with an argument,
 138                  * we have to try to set the new hostname/nodename
 139                  */
 140                 if (argc > optind + 1)
 141                         usage();        /* too many arguments */
 142                 if (fflag)
 143                         usage();        /* can't set fqdn this way */
 144                 if (sflag)
 145                         usage();        /* can't set short name */
 146                 nodename = argv[optind];
 147                 if (sethostname(nodename, strlen(nodename)) < 0) {
 148                         int err = errno;
 149                         (void) fprintf(stderr,
 150                             gettext("%s: error in setting name: %s\n"),
 151                             basename(progname), strerror(err));
 152                         exit(1);
 153                 }
 154         }
 155         return (0);
 156 }