man/pt_BR/ifconfig.8: remove untranslated paragraph
[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_AFINET6
48 #include <sys/socket.h> /* for PF_INET6 */
49 #include <sys/types.h>  /* for inet_ntop */
50 #endif
51
52 #if HAVE_AFDECnet
53 #include <netdnet/dn.h>
54 #endif
55
56 char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)";
57
58 static char *program_name;
59 static int opt_v;
60
61 static void sethname(char *);
62 static void setdname(char *);
63 static void showhname(char *, int);
64 static void usage(void);
65 static void version(void);
66 static void setfilename(char *, int);
67
68 #define SETHOST         1
69 #define SETDOMAIN       2
70 #define SETNODE         3
71
72 #if HAVE_AFDECnet
73 static void setnname(char *nname)
74 {
75     if (opt_v)
76         fprintf(stderr, _("Setting nodename to `%s'\n"),
77                 nname);
78     if (setnodename(nname, strlen(nname))) {
79         switch(errno) {
80         case EPERM:
81             fprintf(stderr, _("%s: you must be root to change the node name\n"), program_name);
82             break;
83         case EINVAL:
84             fprintf(stderr, _("%s: name too long\n"), program_name);
85             break;
86         default:
87             break;
88         }
89         exit(1);
90     }
91 }
92 #endif /* HAVE_AFDECnet */
93
94 static void sethname(char *hname)
95 {
96     if (opt_v)
97         fprintf(stderr, _("Setting hostname to `%s'\n"),
98                 hname);
99     if (sethostname(hname, strlen(hname))) {
100         switch (errno) {
101         case EPERM:
102             fprintf(stderr, _("%s: you must be root to change the host name\n"), program_name);
103             break;
104         case EINVAL:
105             fprintf(stderr, _("%s: name too long\n"), program_name);
106             break;
107         }
108         exit(1);
109     };
110 }
111
112 static void setdname(char *dname)
113 {
114     if (opt_v)
115         fprintf(stderr, _("Setting domainname to `%s'\n"),
116                 dname);
117     if (setdomainname(dname, strlen(dname))) {
118         switch (errno) {
119         case EPERM:
120             fprintf(stderr, _("%s: you must be root to change the domain name\n"), program_name);
121             break;
122         case EINVAL:
123             fprintf(stderr, _("%s: name too long\n"), program_name);
124             break;
125         }
126         exit(1);
127     };
128 }
129
130 static void showhname(char *hname, int c)
131 {
132     struct hostent *hp;
133 #if HAVE_AFINET6
134     struct in6_addr **ip6;
135 #endif
136     register char *p, **alias;
137     struct in_addr **ip;
138
139     if (opt_v)
140         fprintf(stderr, _("Resolving `%s' ...\n"), hname);
141     if (
142 #if HAVE_AFINET6
143         !(hp = gethostbyname2(hname, PF_INET6)) &&
144 #endif
145         !(hp = gethostbyname(hname))) {
146         herror(program_name);
147         exit(1);
148     }
149
150     if (opt_v) {
151         fprintf(stderr, _("Result: h_name=`%s'\n"),
152                 hp->h_name);
153
154         alias = hp->h_aliases;
155         while (alias[0])
156             fprintf(stderr, _("Result: h_aliases=`%s'\n"),
157                     *alias++);
158 #if HAVE_AFINET6
159             if (hp->h_addrtype == PF_INET6) {
160                 char addr[INET6_ADDRSTRLEN + 1];
161                 addr[INET6_ADDRSTRLEN] = '\0';
162                 ip6 = (struct in6_addr **) hp->h_addr_list;
163                 while (ip6[0]) {
164                     if (inet_ntop(PF_INET6, *ip6++, addr, INET6_ADDRSTRLEN))
165                         fprintf(stderr, _("Result: h_addr_list=`%s'\n"), addr);
166                     else if (errno == EAFNOSUPPORT)
167                         fprintf(stderr, _("%s: protocol family not supported\n"),
168                                 program_name);
169                     else if (errno == ENOSPC)
170                         fprintf(stderr, _("%s: name too long\n"), program_name);
171             }
172         } else
173 #endif
174         {
175             ip = (struct in_addr **) hp->h_addr_list;
176             while (ip[0])
177                 fprintf(stderr, _("Result: h_addr_list=`%s'\n"),
178                         inet_ntoa(**ip++));
179         }
180     }
181     if (!(p = strchr(hp->h_name, '.')) && (c == 'd'))
182         return;
183
184     switch (c) {
185     case 'a':
186         while (hp->h_aliases[0])
187             printf("%s ", *hp->h_aliases++);
188         printf("\n");
189         break;
190     case 'i':
191 #if HAVE_AFINET6
192         if (hp->h_addrtype == PF_INET6) {
193             char addr[INET6_ADDRSTRLEN + 1];
194             addr[INET6_ADDRSTRLEN] = '\0';
195             while (hp->h_addr_list[0]) {
196                 if (inet_ntop(PF_INET6, (struct in6_addr *)*hp->h_addr_list++,
197                               addr, INET6_ADDRSTRLEN)) {
198                     printf("%s ", addr);
199                 } else if (errno == EAFNOSUPPORT) {
200                     fprintf(stderr, _("\n%s: protocol family not supported\n"),
201                             program_name);
202                     exit(1);
203                 } else if (errno == ENOSPC) {
204                     fprintf(stderr, _("\n%s: name too long\n"), program_name);
205                     exit(1);
206                 }
207             }
208         } else
209 #endif
210         {
211             while (hp->h_addr_list[0])
212                 printf("%s ", inet_ntoa(*(struct in_addr *)*hp->h_addr_list++));
213         }
214         printf("\n");
215         break;
216     case 'd':
217         printf("%s\n", ++p);
218         break;
219     case 'f':
220         printf("%s\n", hp->h_name);
221         break;
222     case 's':
223         if (p != NULL)
224             *p = '\0';
225         printf("%s\n", hp->h_name);
226         break;
227     }
228 }
229
230 static void setfilename(char *name, int what)
231 {
232     register FILE *fd;
233     register char *p;
234     char fline[MAXHOSTNAMELEN];
235
236     if ((fd = fopen(name, "r")) != NULL) {
237         while (fgets(fline, sizeof(fline), fd) != NULL) {
238             if ((p = index(fline, '\n')) != NULL)
239                 *p = '\0';
240             if (opt_v)
241                 fprintf(stderr, ">> %s\n", fline);
242             if (fline[0] == '#')
243                 continue;
244             switch(what) {
245             case SETHOST:
246                 sethname(fline);
247                 break;
248             case SETDOMAIN:
249                 setdname(fline);
250                 break;
251 #if HAVE_AFDECnet
252             case SETNODE:
253                 setnname(fline);
254                 break;
255 #endif /* HAVE_AFDECnet */
256             }
257         }
258         (void) fclose(fd);
259     } else {
260         fprintf(stderr, _("%s: can't open `%s'\n"),
261                 program_name, name);
262         exit(1);
263     }
264 }
265
266 static void version(void)
267 {
268     fprintf(stderr, "%s\n%s\n", Release, Version);
269     exit(5); /* E_VERSION */
270 }
271
272 static void usage(void)
273 {
274     fprintf(stderr, _("Usage: hostname [-v] {hostname|-F file}      set hostname (from file)\n"));
275     fprintf(stderr, _("       domainname [-v] {nisdomain|-F file}   set NIS domainname (from file)\n"));
276 #if HAVE_AFDECnet
277     fprintf(stderr, _("       nodename [-v] {nodename|-F file}      set DECnet node name (from file)\n"));
278 #endif
279     fprintf(stderr, _("       hostname [-v] [-d|-f|-s|-a|-i|-y|-n]  display formatted name\n"));
280     fprintf(stderr, _("       hostname [-v]                         display hostname\n\n"));
281     fprintf(stderr, _("       hostname -V|--version|-h|--help       print info and exit\n\n"));
282     fprintf(stderr, _("    dnsdomainname=hostname -d, {yp,nis,}domainname=hostname -y\n\n"));
283     fprintf(stderr, _("    -s, --short           short host name\n"));
284     fprintf(stderr, _("    -a, --alias           alias names\n"));
285     fprintf(stderr, _("    -i, --ip-address      addresses for the hostname\n"));
286     fprintf(stderr, _("    -f, --fqdn, --long    long host name (FQDN)\n"));
287     fprintf(stderr, _("    -d, --domain          DNS domain name\n"));
288     fprintf(stderr, _("    -y, --yp, --nis       NIS/YP domainname\n"));
289 #if HAVE_AFDECnet
290     fprintf(stderr, _("    -n, --node            DECnet node name\n"));
291 #endif /* HAVE_AFDECnet */
292     fprintf(stderr, _("    -F, --file            read hostname or NIS domainname from given file\n\n"));
293     fprintf(stderr, _(
294 "   This command can read or set the hostname or the NIS domainname. You can\n"
295 "   also read the DNS domain or the FQDN (fully qualified domain name).\n"
296 "   Unless you are using bind or NIS for host lookups you can change the\n"
297 "   FQDN (Fully Qualified Domain Name) and the DNS domain name (which is\n"
298 "   part of the FQDN) in the /etc/hosts file.\n"));
299
300     exit(4); /* E_USAGE */
301 }
302
303
304 int main(int argc, char **argv)
305 {
306     int c;
307     char type = '\0';
308     int option_index = 0;
309     int what = 0;
310     char myname[MAXHOSTNAMELEN + 1] =
311     {0};
312     char *file = NULL;
313
314     static const struct option long_options[] =
315     {
316         {"domain", no_argument, 0, 'd'},
317         {"file", required_argument, 0, 'F'},
318         {"fqdn", no_argument, 0, 'f'},
319         {"help", no_argument, 0, 'h'},
320         {"long", no_argument, 0, 'f'},
321         {"short", no_argument, 0, 's'},
322         {"version", no_argument, 0, 'V'},
323         {"verbose", no_argument, 0, 'v'},
324         {"alias", no_argument, 0, 'a'},
325         {"ip-address", no_argument, 0, 'i'},
326         {"nis", no_argument, 0, 'y'},
327         {"yp", no_argument, 0, 'y'},
328 #if HAVE_AFDECnet
329         {"node", no_argument, 0, 'n'},
330 #endif /* HAVE_AFDECnet */
331         {0, 0, 0, 0}
332     };
333 #if I18N
334     setlocale (LC_ALL, "");
335     bindtextdomain("net-tools", "/usr/share/locale");
336     textdomain("net-tools");
337 #endif
338     program_name = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
339
340     if (!strcmp(program_name, "ypdomainname") ||
341         !strcmp(program_name, "domainname") ||
342         !strcmp(program_name, "nisdomainname"))
343         what = 3;
344     if (!strcmp(program_name, "dnsdomainname"))
345         what = 2;
346 #if HAVE_AFDECnet
347     if (!strcmp(program_name, "nodename"))
348         what = 4;
349 #endif /* HAVE_AFDECnet */
350
351     while ((c = getopt_long(argc, argv, "adfF:h?isVvyn", long_options, &option_index)) != EOF)
352         switch (c) {
353         case 'd':
354             what = 2;
355             break;
356         case 'a':
357         case 'f':
358         case 'i':
359         case 's':
360             what = 1;
361             type = c;
362             break;
363         case 'y':
364             what = 3;
365             break;
366 #if HAVE_AFDECnet
367         case 'n':
368             what = 4;
369             break;
370 #endif /* HAVE_AFDECnet */
371         case 'F':
372             file = optarg;
373             break;
374         case 'v':
375             opt_v++;
376             break;
377         case 'V':
378             version();
379             break; // not reached
380         case '?':
381         case 'h':
382         default:
383             usage();
384             break; // not reached
385         };
386
387
388     switch (what) {
389     case 2:
390         if (file || (optind < argc)) {
391             fprintf(stderr, _("%s: You can't change the DNS domain name with this command\n"), program_name);
392             fprintf(stderr, _("\nUnless you are using bind or NIS for host lookups you can change the DNS\n"));
393             fprintf(stderr, _("domain name (which is part of the FQDN) in the /etc/hosts file.\n"));
394             exit(1);
395         }
396         type = 'd';
397         /* NOBREAK */
398     case 0:
399         if (file) {
400             setfilename(file, SETHOST);
401             break;
402         }
403         if (optind < argc) {
404             sethname(argv[optind]);
405             break;
406         }
407     case 1:
408         gethostname(myname, sizeof(myname));
409         if (opt_v)
410             fprintf(stderr, _("gethostname()=`%s'\n"), myname);
411         if (!type)
412             printf("%s\n", myname);
413         else
414             showhname(myname, type);
415         break;
416     case 3:
417         if (file) {
418             setfilename(file, SETDOMAIN);
419             break;
420         }
421         if (optind < argc) {
422             setdname(argv[optind]);
423             break;
424         }
425         if (getdomainname(myname, sizeof(myname)) < 0) {
426             perror("getdomainname()");
427             exit(1);
428         }
429         if (opt_v)
430             fprintf(stderr, _("getdomainname()=`%s'\n"), myname);
431         printf("%s\n", myname);
432         break;
433 #if HAVE_AFDECnet
434     case 4:
435         if (file) {
436             setfilename(file, SETNODE);
437             break;
438         }
439         if (optind < argc) {
440             setnname(argv[optind]);
441             break;
442         }
443         getnodename(myname, sizeof(myname));
444         if (opt_v)
445             fprintf(stderr, _("getnodename()=`%s'\n"), myname);
446         printf("%s\n", myname);
447         break;
448 #endif /* HAVE_AFDECnet */
449     }
450     exit(0);
451 }