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