minor fix to return E_USAGE on -V instead of exit(0);
[oss-qm-packages.git] / hostname.c
blob8793fb94fef17ce2f5c996798604855cc22d5f05
1 /*
2 * hostname This file contains an implementation of the command
3 * that maintains the hostname and the domainname. It
4 * is also used to show the FQDN and the IP-Addresses.
6 * Usage: hostname [-d|-f|-s|-a|-i|-y|-n]
7 * hostname [-h|-V]
8 * hostname {name|-F file}
9 * dnsdmoainname
10 * nisdomainname {name|-F file}
12 * Version: hostname 1.96 (1996-02-18)
14 * Author: Peter Tobias <tobias@et-inf.fho-emden.de>
16 * Changes:
17 * {1.90} Peter Tobias : Added -a and -i options.
18 * {1.91} Bernd Eckenfels : -v,-V rewritten, long_opts
19 * (major rewrite), usage.
20 *960120 {1.95} Bernd Eckenfels : -y/nisdomainname - support for get/
21 * setdomainname added
22 *960218 {1.96} Bernd Eckenfels : netinet/in.h added
23 *980629 {1.97} Arnaldo Carvalho de Melo : gettext instead of catgets for i18n
24 *20000213 {1.99} Arnaldo Carvalho de Melo : fixed some i18n strings
25 *20010404 {1.100} Arnaldo Carvalho de Melo: use setlocale
27 * This program is free software; you can redistribute it
28 * and/or modify it under the terms of the GNU General
29 * Public License as published by the Free Software
30 * Foundation; either version 2 of the License, or (at
31 * your option) any later version.
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <getopt.h>
36 #include <string.h>
37 #include <netdb.h>
38 #include <errno.h>
39 #include <sys/param.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include "config.h"
43 #include "version.h"
44 #include "../intl.h"
46 #if HAVE_AFDECnet
47 #include <netdnet/dn.h>
48 #endif
50 char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)";
52 static char *program_name;
53 static int opt_v;
55 static void sethname(char *);
56 static void setdname(char *);
57 static void showhname(char *, int);
58 static void usage(void);
59 static void version(void);
60 static void setfilename(char *, int);
62 #define SETHOST 1
63 #define SETDOMAIN 2
64 #define SETNODE 3
66 #if HAVE_AFDECnet
67 static void setnname(char *nname)
69 if (opt_v)
70 fprintf(stderr, _("Setting nodename to `%s'\n"),
71 nname);
72 if (setnodename(nname, strlen(nname))) {
73 switch(errno) {
74 case EPERM:
75 fprintf(stderr, _("%s: you must be root to change the node name\n"), program_name);
76 break;
77 case EINVAL:
78 fprintf(stderr, _("%s: name too long\n"), program_name);
79 break;
80 default:
82 exit(1);
85 #endif /* HAVE_AFDECnet */
87 static void sethname(char *hname)
89 if (opt_v)
90 fprintf(stderr, _("Setting hostname to `%s'\n"),
91 hname);
92 if (sethostname(hname, strlen(hname))) {
93 switch (errno) {
94 case EPERM:
95 fprintf(stderr, _("%s: you must be root to change the host name\n"), program_name);
96 break;
97 case EINVAL:
98 fprintf(stderr, _("%s: name too long\n"), program_name);
99 break;
100 default:
102 exit(1);
106 static void setdname(char *dname)
108 if (opt_v)
109 fprintf(stderr, _("Setting domainname to `%s'\n"),
110 dname);
111 if (setdomainname(dname, strlen(dname))) {
112 switch (errno) {
113 case EPERM:
114 fprintf(stderr, _("%s: you must be root to change the domain name\n"), program_name);
115 break;
116 case EINVAL:
117 fprintf(stderr, _("%s: name too long\n"), program_name);
118 break;
119 default:
121 exit(1);
125 static void showhname(char *hname, int c)
127 struct hostent *hp;
128 register char *p, **alias;
129 struct in_addr **ip;
131 if (opt_v)
132 fprintf(stderr, _("Resolving `%s' ...\n"), hname);
133 if (!(hp = gethostbyname(hname))) {
134 herror(program_name);
135 exit(1);
137 if (opt_v) {
138 fprintf(stderr, _("Result: h_name=`%s'\n"),
139 hp->h_name);
141 alias = hp->h_aliases;
142 while (alias[0])
143 fprintf(stderr, _("Result: h_aliases=`%s'\n"),
144 *alias++);
146 ip = (struct in_addr **) hp->h_addr_list;
147 while (ip[0])
148 fprintf(stderr, _("Result: h_addr_list=`%s'\n"),
149 inet_ntoa(**ip++));
151 if (!(p = strchr(hp->h_name, '.')) && (c == 'd'))
152 return;
154 switch (c) {
155 case 'a':
156 while (hp->h_aliases[0])
157 printf("%s ", *hp->h_aliases++);
158 printf("\n");
159 break;
160 case 'i':
161 while (hp->h_addr_list[0])
162 printf("%s ", inet_ntoa(*(struct in_addr *) *hp->h_addr_list++));
163 printf("\n");
164 break;
165 case 'd':
166 printf("%s\n", ++p);
167 break;
168 case 'f':
169 printf("%s\n", hp->h_name);
170 break;
171 case 's':
172 if (p != NULL)
173 *p = '\0';
174 printf("%s\n", hp->h_name);
175 break;
176 default:
180 static void setfilename(char *name, int what)
182 register FILE *fd;
183 register char *p;
184 char fline[MAXHOSTNAMELEN];
186 if ((fd = fopen(name, "r")) != NULL) {
187 while (fgets(fline, sizeof(fline), fd) != NULL) {
188 if ((p = index(fline, '\n')) != NULL)
189 *p = '\0';
190 if (opt_v)
191 fprintf(stderr, ">> %s\n", fline);
192 if (fline[0] == '#')
193 continue;
194 switch(what) {
195 case SETHOST:
196 sethname(fline);
197 break;
198 case SETDOMAIN:
199 setdname(fline);
200 break;
201 #if HAVE_AFDECnet
202 case SETNODE:
203 setnname(fline);
204 break;
205 #endif /* HAVE_AFDECnet */
208 (void) fclose(fd);
209 } else {
210 fprintf(stderr, _("%s: can't open `%s'\n"),
211 program_name, name);
212 exit(1);
216 static void version(void)
218 fprintf(stderr, "%s\n%s\n", Release, Version);
219 exit(5); /* E_VERSION */
222 static void usage(void)
224 fprintf(stderr, _("Usage: hostname [-v] {hostname|-F file} set hostname (from file)\n"));
225 fprintf(stderr, _(" domainname [-v] {nisdomain|-F file} set NIS domainname (from file)\n"));
226 #if HAVE_AFDECnet
227 fprintf(stderr, _(" nodename [-v] {nodename|-F file} set DECnet node name (from file)\n"));
228 #endif
229 fprintf(stderr, _(" hostname [-v] [-d|-f|-s|-a|-i|-y|-n] display formatted name\n"));
230 fprintf(stderr, _(" hostname [-v] display hostname\n\n"));
231 fprintf(stderr, _(" hostname -V|--version|-h|--help print info and exit\n\n"));
232 fprintf(stderr, _(" dnsdomainname=hostname -d, {yp,nis,}domainname=hostname -y\n\n"));
233 fprintf(stderr, _(" -s, --short short host name\n"));
234 fprintf(stderr, _(" -a, --alias alias names\n"));
235 fprintf(stderr, _(" -i, --ip-address addresses for the hostname\n"));
236 fprintf(stderr, _(" -f, --fqdn, --long long host name (FQDN)\n"));
237 fprintf(stderr, _(" -d, --domain DNS domain name\n"));
238 fprintf(stderr, _(" -y, --yp, --nis NIS/YP domainname\n"));
239 #if HAVE_AFDECnet
240 fprintf(stderr, _(" -n, --node DECnet node name\n"));
241 #endif /* HAVE_AFDECnet */
242 fprintf(stderr, _(" -F, --file read hostname or NIS domainname from given file\n\n"));
243 fprintf(stderr, _(
244 " This command can read or set the hostname or the NIS domainname. You can\n"
245 " also read the DNS domain or the FQDN (fully qualified domain name).\n"
246 " Unless you are using bind or NIS for host lookups you can change the\n"
247 " FQDN (Fully Qualified Domain Name) and the DNS domain name (which is\n"
248 " part of the FQDN) in the /etc/hosts file.\n"));
250 exit(4); /* E_USAGE */
254 int main(int argc, char **argv)
256 int c;
257 char type = '\0';
258 int option_index = 0;
259 int what = 0;
260 char myname[MAXHOSTNAMELEN + 1] =
261 {0};
262 char *file = NULL;
264 static const struct option long_options[] =
266 {"domain", no_argument, 0, 'd'},
267 {"file", required_argument, 0, 'F'},
268 {"fqdn", no_argument, 0, 'f'},
269 {"help", no_argument, 0, 'h'},
270 {"long", no_argument, 0, 'f'},
271 {"short", no_argument, 0, 's'},
272 {"version", no_argument, 0, 'V'},
273 {"verbose", no_argument, 0, 'v'},
274 {"alias", no_argument, 0, 'a'},
275 {"ip-address", no_argument, 0, 'i'},
276 {"nis", no_argument, 0, 'y'},
277 {"yp", no_argument, 0, 'y'},
278 #if HAVE_AFDECnet
279 {"node", no_argument, 0, 'n'},
280 #endif /* HAVE_AFDECnet */
281 {0, 0, 0, 0}
283 #if I18N
284 setlocale (LC_ALL, "");
285 bindtextdomain("net-tools", "/usr/share/locale");
286 textdomain("net-tools");
287 #endif
288 program_name = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
290 if (!strcmp(program_name, "ypdomainname") ||
291 !strcmp(program_name, "domainname") ||
292 !strcmp(program_name, "nisdomainname"))
293 what = 3;
294 if (!strcmp(program_name, "dnsdomainname"))
295 what = 2;
296 #if HAVE_AFDECnet
297 if (!strcmp(program_name, "nodename"))
298 what = 4;
299 #endif /* HAVE_AFDECnet */
301 while ((c = getopt_long(argc, argv, "adfF:h?isVvyn", long_options, &option_index)) != EOF)
302 switch (c) {
303 case 'd':
304 what = 2;
305 break;
306 case 'a':
307 case 'f':
308 case 'i':
309 case 's':
310 what = 1;
311 type = c;
312 break;
313 case 'y':
314 what = 3;
315 break;
316 #if HAVE_AFDECnet
317 case 'n':
318 what = 4;
319 break;
320 #endif /* HAVE_AFDECnet */
321 case 'F':
322 file = optarg;
323 break;
324 case 'v':
325 opt_v++;
326 break;
327 case 'V':
328 version();
329 case '?':
330 case 'h':
331 default:
332 usage();
337 switch (what) {
338 case 2:
339 if (file || (optind < argc)) {
340 fprintf(stderr, _("%s: You can't change the DNS domain name with this command\n"), program_name);
341 fprintf(stderr, _("\nUnless you are using bind or NIS for host lookups you can change the DNS\n"));
342 fprintf(stderr, _("domain name (which is part of the FQDN) in the /etc/hosts file.\n"));
343 exit(1);
345 type = 'd';
346 /* NOBREAK */
347 case 0:
348 if (file) {
349 setfilename(file, SETHOST);
350 break;
352 if (optind < argc) {
353 sethname(argv[optind]);
354 break;
356 case 1:
357 gethostname(myname, sizeof(myname));
358 if (opt_v)
359 fprintf(stderr, _("gethostname()=`%s'\n"), myname);
360 if (!type)
361 printf("%s\n", myname);
362 else
363 showhname(myname, type);
364 break;
365 case 3:
366 if (file) {
367 setfilename(file, SETDOMAIN);
368 break;
370 if (optind < argc) {
371 setdname(argv[optind]);
372 break;
374 getdomainname(myname, sizeof(myname));
375 if (opt_v)
376 fprintf(stderr, _("getdomainname()=`%s'\n"), myname);
377 printf("%s\n", myname);
378 break;
379 #if HAVE_AFDECnet
380 case 4:
381 if (file) {
382 setfilename(file, SETNODE);
383 break;
385 if (optind < argc) {
386 setnname(argv[optind]);
387 break;
389 getnodename(myname, sizeof(myname));
390 if (opt_v)
391 fprintf(stderr, _("getnodename()=`%s'\n"), myname);
392 printf("%s\n", myname);
393 break;
394 #endif /* HAVE_AFDECnet */
396 exit(0);