Use setlocale at program initialisation.
[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.96 (1996-02-18)
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 
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
26  *
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.
32  */
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"
45
46 #if HAVE_AFDECnet
47 #include <netdnet/dn.h>
48 #endif
49
50 char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)";
51
52 static char *program_name;
53 static int opt_v;
54
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);
61
62 #define SETHOST         1
63 #define SETDOMAIN       2
64 #define SETNODE         3
65
66 #if HAVE_AFDECnet
67 static void setnname(char *nname)
68 {
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:
81         }
82         exit(1);
83     }
84 }
85 #endif /* HAVE_AFDECnet */
86
87 static void sethname(char *hname)
88 {
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:
101         }
102         exit(1);
103     };
104 }
105
106 static void setdname(char *dname)
107 {
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:
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     default:
177     }
178 }
179
180 static void setfilename(char *name, int what)
181 {
182     register FILE *fd;
183     register char *p;
184     char fline[MAXHOSTNAMELEN];
185
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 */
206             }
207         }
208         (void) fclose(fd);
209     } else {
210         fprintf(stderr, _("%s: can't open `%s'\n"),
211                 program_name, name);
212         exit(1);
213     }
214 }
215
216 static void version(void)
217 {
218     fprintf(stderr, "%s\n%s\n", Release, Version);
219     exit(5); /* E_VERSION */
220 }
221
222 static void usage(void)
223 {
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"));
249
250     exit(4); /* E_USAGE */
251 }
252
253
254 int main(int argc, char **argv)
255 {
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;
263
264     static const struct option long_options[] =
265     {
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}
282     };
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];
289
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 */
300
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();
333
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 }