1/* vi: set sw=4 ts=4: */ 2/* 3 * Mini hostname implementation for busybox 4 * 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 6 * 7 * Adjusted by Erik Andersen <andersen@codepoet.org> to remove 8 * use of long options and GNU getopt. Improved the usage info. 9 * 10 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 11 */ 12//config:config HOSTNAME 13//config: bool "hostname (5.5 kb)" 14//config: default y 15//config: help 16//config: Show or set the system's host name. 17//config: 18//config:config DNSDOMAINNAME 19//config: bool "dnsdomainname (3.6 kb)" 20//config: default y 21//config: help 22//config: Alias to "hostname -d". 23 24// APPLET_NOEXEC:name main location suid_type help 25//applet:IF_DNSDOMAINNAME(APPLET_NOEXEC(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) 26//applet:IF_HOSTNAME( APPLET_NOEXEC(hostname, hostname, BB_DIR_BIN, BB_SUID_DROP, hostname )) 27 28//kbuild: lib-$(CONFIG_HOSTNAME) += hostname.o 29//kbuild: lib-$(CONFIG_DNSDOMAINNAME) += hostname.o 30 31//usage:#define hostname_trivial_usage 32//usage: "[OPTIONS] [HOSTNAME | -F FILE]" 33//usage:#define hostname_full_usage "\n\n" 34//usage: "Get or set hostname or DNS domain name\n" 35//usage: "\n -s Short" 36//usage: "\n -i Addresses for the hostname" 37//usage: "\n -d DNS domain name" 38//usage: "\n -f Fully qualified domain name" 39//usage: "\n -F FILE Use FILE's content as hostname" 40//usage: 41//usage:#define hostname_example_usage 42//usage: "$ hostname\n" 43//usage: "sage\n" 44//usage: 45//usage:#define dnsdomainname_trivial_usage NOUSAGE_STR 46//usage:#define dnsdomainname_full_usage "" 47 48#include "libbb.h" 49 50static void do_sethostname(char *s, int isfile) 51{ 52// if (!s) 53// return; 54 if (isfile) { 55 parser_t *parser = config_open2(s, xfopen_for_read); 56 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) { 57 do_sethostname(s, 0); 58 } 59 if (ENABLE_FEATURE_CLEAN_UP) 60 config_close(parser); 61 } else if (sethostname(s, strlen(s))) { 62// if (errno == EPERM) 63// bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 64 bb_perror_msg_and_die("sethostname"); 65 } 66} 67 68/* Manpage circa 2009: 69 * 70 * hostname [-v] [-a] [--alias] [-d] [--domain] [-f] [--fqdn] [--long] 71 * [-i] [--ip-address] [-s] [--short] [-y] [--yp] [--nis] 72 * 73 * hostname [-v] [-F filename] [--file filename] / [hostname] 74 * 75 * domainname [-v] [-F filename] [--file filename] / [name] 76 * { bbox: not supported } 77 * 78 * nodename [-v] [-F filename] [--file filename] / [name] 79 * { bbox: not supported } 80 * 81 * dnsdomainname [-v] 82 * { bbox: supported: Linux kernel build needs this } 83 * nisdomainname [-v] 84 * { bbox: not supported } 85 * ypdomainname [-v] 86 * { bbox: not supported } 87 * 88 * -a, --alias 89 * Display the alias name of the host (if used). 90 * { bbox: not supported } 91 * -d, --domain 92 * Display the name of the DNS domain. Don't use the command 93 * domainname to get the DNS domain name because it will show the 94 * NIS domain name and not the DNS domain name. Use dnsdomainname 95 * instead. 96 * -f, --fqdn, --long 97 * Display the FQDN (Fully Qualified Domain Name). A FQDN consists 98 * of a short host name and the DNS domain name. Unless you are 99 * using bind or NIS for host lookups you can change the FQDN and 100 * the DNS domain name (which is part of the FQDN) in the 101 * /etc/hosts file. 102 * -i, --ip-address 103 * Display the IP address(es) of the host. 104 * -s, --short 105 * Display the short host name. This is the host name cut at the 106 * first dot. 107 * -v, --verbose 108 * Be verbose and tell what's going on. 109 * { bbox: supported but ignored } 110 * -y, --yp, --nis 111 * Display the NIS domain name. If a parameter is given (or --file 112 * name ) then root can also set a new NIS domain. 113 * { bbox: not supported } 114 * -F, --file filename 115 * Read the host name from the specified file. Comments (lines 116 * starting with a '#') are ignored. 117 */ 118int hostname_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 119int hostname_main(int argc UNUSED_PARAM, char **argv) 120{ 121 enum { 122 OPT_d = 0x1, 123 OPT_f = 0x2, 124 OPT_i = 0x4, 125 OPT_s = 0x8, 126 OPT_F = 0x10, 127 OPT_dfi = 0x7, 128 }; 129 130 unsigned opts; 131 char *buf; 132 char *hostname_str; 133 134 /* dnsdomainname from net-tools 1.60, hostname 1.100 (2001-04-14), 135 * supports hostname's options too (not just -v as manpage says) */ 136 opts = getopt32(argv, "dfisF:v", &hostname_str, 137 "domain\0" No_argument "d" 138 "fqdn\0" No_argument "f" 139 //Enable if seen in active use in some distro: 140 // "long\0" No_argument "f" 141 // "ip-address\0" No_argument "i" 142 // "short\0" No_argument "s" 143 // "verbose\0" No_argument "v" 144 "file\0" No_argument "F" 145 ); 146 argv += optind; 147 buf = safe_gethostname(); 148 if (ENABLE_DNSDOMAINNAME) { 149 if (!ENABLE_HOSTNAME || applet_name[0] == 'd') { 150 /* dnsdomainname */ 151 opts = OPT_d; 152 } 153 } 154 155 if (opts & OPT_dfi) { 156 /* Cases when we need full hostname (or its part) */ 157 struct hostent *hp; 158 char *p; 159 160 hp = xgethostbyname(buf); 161 p = strchrnul(hp->h_name, '.'); 162 if (opts & OPT_f) { 163 puts(hp->h_name); 164 } else if (opts & OPT_s) { 165 *p = '\0'; 166 puts(hp->h_name); 167 } else if (opts & OPT_d) { 168 if (*p) 169 puts(p + 1); 170 } else /*if (opts & OPT_i)*/ { 171 if (hp->h_length == sizeof(struct in_addr)) { 172 struct in_addr **h_addr_list = (struct in_addr **)hp->h_addr_list; 173 while (*h_addr_list) { 174 printf(h_addr_list[1] ? "%s " : "%s", inet_ntoa(**h_addr_list)); 175 h_addr_list++; 176 } 177 bb_putchar('\n'); 178 } 179 } 180 } else if (opts & OPT_s) { 181 strchrnul(buf, '.')[0] = '\0'; 182 puts(buf); 183 } else if (opts & OPT_F) { 184 /* Set the hostname */ 185 do_sethostname(hostname_str, 1); 186 } else if (argv[0]) { 187 /* Set the hostname */ 188 do_sethostname(argv[0], 0); 189 } else { 190 /* Just print the current hostname */ 191 puts(buf); 192 } 193 194 if (ENABLE_FEATURE_CLEAN_UP) 195 free(buf); 196 return EXIT_SUCCESS; 197} 198