[Bug #17645] Add netstat(8) support for RcvbufErrors, SndbufErrors.
[platform/upstream/net-tools.git] / hostname.c
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.
5  *
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}
11  *
12  * Version:     hostname 1.101 (2003-10-11)
13  *
14  * Author:      Peter Tobias <tobias@et-inf.fho-emden.de>
15  *
16  * Changes:
17  *         {1.90}  Peter Tobias : Added -a and -i options.
18  *         {1.91}  Bernd Eckenfels : -v,-V rewritten, long_opts (major rewrite), usage.
19  *19960120 {1.95}  Bernd Eckenfels : -y/nisdomainname - support for get/setdomainname added 
20  *19960218 {1.96}  Bernd Eckenfels : netinet/in.h added
21  *19980629 {1.97}  Arnaldo Carvalho de Melo : gettext instead of catgets for i18n
22  *20000213 {1.99}  Arnaldo Carvalho de Melo : fixed some i18n strings
23  *20010404 {1.100} Arnaldo Carvalho de Melo: use setlocale
24  *20031011 {1.101} Maik Broemme: gcc 3.x fixes (default: break)
25  *
26  *              This program is free software; you can redistribute it
27  *              and/or  modify it under  the terms of  the GNU General
28  *              Public  License as  published  by  the  Free  Software
29  *              Foundation;  either  version 2 of the License, or  (at
30  *              your option) any later version.
31  */
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <getopt.h>
37 #include <string.h>
38 #include <netdb.h>
39 #include <errno.h>
40 #include <sys/param.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include "config.h"
44 #include "version.h"
45 #include "../intl.h"
46
47 #if HAVE_AFDECnet
48 #include <netdnet/dn.h>
49 #endif
50
51 char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)";
52
53 static char *program_name;
54 static int opt_v;
55
56 static void sethname(char *);
57 static void setdname(char *);
58 static void showhname(char *, int);
59 static void usage(void);
60 static void version(void);
61 static void setfilename(char *, int);
62
63 #define SETHOST         1
64 #define SETDOMAIN       2
65 #define SETNODE         3
66
67 #if HAVE_AFDECnet
68 static void setnname(char *nname)
69 {
70     if (opt_v)
71         fprintf(stderr, _("Setting nodename to `%s'\n"),
72                 nname);
73     if (setnodename(nname, strlen(nname))) {
74         switch(errno) {
75         case EPERM:
76             fprintf(stderr, _("%s: you must be root to change the node name\n"), program_name);
77             break;
78         case EINVAL:
79             fprintf(stderr, _("%s: name too long\n"), program_name);
80             break;
81         default:
82             break;
83         }
84         exit(1);
85     }
86 }
87 #endif /* HAVE_AFDECnet */
88
89 static void sethname(char *hname)
90 {
91     if (opt_v)
92         fprintf(stderr, _("Setting hostname to `%s'\n"),
93                 hname);
94     if (sethostname(hname, strlen(hname))) {
95         switch (errno) {
96         case EPERM:
97             fprintf(stderr, _("%s: you must be root to change the host name\n"), program_name);
98             break;
99         case EINVAL:
100             fprintf(stderr, _("%s: name too long\n"), program_name);
101             break;
102         }
103         exit(1);
104     };
105 }
106
107 static void setdname(char *dname)
108 {
109     if (opt_v)
110         fprintf(stderr, _("Setting domainname to `%s'\n"),
111                 dname);
112     if (setdomainname(dname, strlen(dname))) {
113         switch (errno) {
114         case EPERM:
115             fprintf(stderr, _("%s: you must be root to change the domain name\n"), program_name);
116             break;
117         case EINVAL:
118             fprintf(stderr, _("%s: name too long\n"), program_name);
119             break;
120         }
121         exit(1);
122     };
123 }
124
125 static void showhname(char *hname, int c)
126 {
127     struct hostent *hp;
128     register char *p, **alias;
129     struct in_addr **ip;
130
131     if (opt_v)
132         fprintf(stderr, _("Resolving `%s' ...\n"), hname);
133     if (!(hp = gethostbyname(hname))) {
134         herror(program_name);
135         exit(1);
136     }
137     if (opt_v) {
138         fprintf(stderr, _("Result: h_name=`%s'\n"),
139                 hp->h_name);
140
141         alias = hp->h_aliases;
142         while (alias[0])
143             fprintf(stderr, _("Result: h_aliases=`%s'\n"),
144                     *alias++);
145
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++));
150     }
151     if (!(p = strchr(hp->h_name, '.')) && (c == 'd'))
152         return;
153
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     }
177 }
178
179 static void setfilename(char *name, int what)
180 {
181     register FILE *fd;
182     register char *p;
183     char fline[MAXHOSTNAMELEN];
184
185     if ((fd = fopen(name, "r")) != NULL) {
186         while (fgets(fline, sizeof(fline), fd) != NULL) {
187             if ((p = index(fline, '\n')) != NULL)
188                 *p = '\0';
189             if (opt_v)
190                 fprintf(stderr, ">> %s\n", fline);
191             if (fline[0] == '#')
192                 continue;
193             switch(what) {
194             case SETHOST:
195                 sethname(fline);
196                 break;
197             case SETDOMAIN:
198                 setdname(fline);
199                 break;
200 #if HAVE_AFDECnet
201             case SETNODE:
202                 setnname(fline);
203                 break;
204 #endif /* HAVE_AFDECnet */
205             }
206         }
207         (void) fclose(fd);
208     } else {
209         fprintf(stderr, _("%s: can't open `%s'\n"),
210                 program_name, name);
211         exit(1);
212     }
213 }
214
215 static void version(void)
216 {
217     fprintf(stderr, "%s\n%s\n", Release, Version);
218     exit(5); /* E_VERSION */
219 }
220
221 static void usage(void)
222 {
223     fprintf(stderr, _("Usage: hostname [-v] {hostname|-F file}      set hostname (from file)\n"));
224     fprintf(stderr, _("       domainname [-v] {nisdomain|-F file}   set NIS domainname (from file)\n"));
225 #if HAVE_AFDECnet
226     fprintf(stderr, _("       nodename [-v] {nodename|-F file}      set DECnet node name (from file)\n"));
227 #endif
228     fprintf(stderr, _("       hostname [-v] [-d|-f|-s|-a|-i|-y|-n]  display formatted name\n"));
229     fprintf(stderr, _("       hostname [-v]                         display hostname\n\n"));
230     fprintf(stderr, _("       hostname -V|--version|-h|--help       print info and exit\n\n"));
231     fprintf(stderr, _("    dnsdomainname=hostname -d, {yp,nis,}domainname=hostname -y\n\n"));
232     fprintf(stderr, _("    -s, --short           short host name\n"));
233     fprintf(stderr, _("    -a, --alias           alias names\n"));
234     fprintf(stderr, _("    -i, --ip-address      addresses for the hostname\n"));
235     fprintf(stderr, _("    -f, --fqdn, --long    long host name (FQDN)\n"));
236     fprintf(stderr, _("    -d, --domain          DNS domain name\n"));
237     fprintf(stderr, _("    -y, --yp, --nis       NIS/YP domainname\n"));
238 #if HAVE_AFDECnet
239     fprintf(stderr, _("    -n, --node            DECnet node name\n"));
240 #endif /* HAVE_AFDECnet */
241     fprintf(stderr, _("    -F, --file            read hostname or NIS domainname from given file\n\n"));
242     fprintf(stderr, _(
243 "   This command can read or set the hostname or the NIS domainname. You can\n"
244 "   also read the DNS domain or the FQDN (fully qualified domain name).\n"
245 "   Unless you are using bind or NIS for host lookups you can change the\n"
246 "   FQDN (Fully Qualified Domain Name) and the DNS domain name (which is\n"
247 "   part of the FQDN) in the /etc/hosts file.\n"));
248
249     exit(4); /* E_USAGE */
250 }
251
252
253 int main(int argc, char **argv)
254 {
255     int c;
256     char type = '\0';
257     int option_index = 0;
258     int what = 0;
259     char myname[MAXHOSTNAMELEN + 1] =
260     {0};
261     char *file = NULL;
262
263     static const struct option long_options[] =
264     {
265         {"domain", no_argument, 0, 'd'},
266         {"file", required_argument, 0, 'F'},
267         {"fqdn", no_argument, 0, 'f'},
268         {"help", no_argument, 0, 'h'},
269         {"long", no_argument, 0, 'f'},
270         {"short", no_argument, 0, 's'},
271         {"version", no_argument, 0, 'V'},
272         {"verbose", no_argument, 0, 'v'},
273         {"alias", no_argument, 0, 'a'},
274         {"ip-address", no_argument, 0, 'i'},
275         {"nis", no_argument, 0, 'y'},
276         {"yp", no_argument, 0, 'y'},
277 #if HAVE_AFDECnet
278         {"node", no_argument, 0, 'n'},
279 #endif /* HAVE_AFDECnet */
280         {0, 0, 0, 0}
281     };
282 #if I18N
283     setlocale (LC_ALL, "");
284     bindtextdomain("net-tools", "/usr/share/locale");
285     textdomain("net-tools");
286 #endif
287     program_name = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
288
289     if (!strcmp(program_name, "ypdomainname") ||
290         !strcmp(program_name, "domainname") ||
291         !strcmp(program_name, "nisdomainname"))
292         what = 3;
293     if (!strcmp(program_name, "dnsdomainname"))
294         what = 2;
295 #if HAVE_AFDECnet
296     if (!strcmp(program_name, "nodename"))
297         what = 4;
298 #endif /* HAVE_AFDECnet */
299
300     while ((c = getopt_long(argc, argv, "adfF:h?isVvyn", long_options, &option_index)) != EOF)
301         switch (c) {
302         case 'd':
303             what = 2;
304             break;
305         case 'a':
306         case 'f':
307         case 'i':
308         case 's':
309             what = 1;
310             type = c;
311             break;
312         case 'y':
313             what = 3;
314             break;
315 #if HAVE_AFDECnet
316         case 'n':
317             what = 4;
318             break;
319 #endif /* HAVE_AFDECnet */
320         case 'F':
321             file = optarg;
322             break;
323         case 'v':
324             opt_v++;
325             break;
326         case 'V':
327             version();
328             break; // not reached
329         case '?':
330         case 'h':
331         default:
332             usage();
333             break; // not reached
334         };
335
336
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);
344         }
345         type = 'd';
346         /* NOBREAK */
347     case 0:
348         if (file) {
349             setfilename(file, SETHOST);
350             break;
351         }
352         if (optind < argc) {
353             sethname(argv[optind]);
354             break;
355         }
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;
369         }
370         if (optind < argc) {
371             setdname(argv[optind]);
372             break;
373         }
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;
384         }
385         if (optind < argc) {
386             setnname(argv[optind]);
387             break;
388         }
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 */
395     }
396     exit(0);
397 }