VM: restore >4k secondary cache functionality
[minix.git] / commands / hostaddr / hostaddr.c
blobd45f4a11487f7d45fdaf74ded9f51ab36e18e86d
1 /*
2 hostaddr.c
4 Fetch an ip and/or ethernet address and print it on one line.
6 Created: Jan 27, 1992 by Philip Homburg
7 */
9 #include <sys/types.h>
10 #include <sys/ioctl.h>
11 #include <sys/utsname.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
19 #ifdef __NBSD_LIBC
20 #include <netinet/in.h>
21 #endif
23 #include <net/netlib.h>
24 #include <net/hton.h>
25 #include <net/gen/ether.h>
26 #include <net/gen/eth_io.h>
27 #include <net/gen/if_ether.h>
28 #include <net/gen/in.h>
29 #include <net/gen/inet.h>
30 #include <net/gen/ip_io.h>
31 #include <net/gen/netdb.h>
32 #include <net/gen/socket.h>
33 #include <net/gen/nameser.h>
34 #include <net/gen/resolv.h>
35 #include <net/gen/dhcp.h>
37 #include <paths.h>
39 char *prog_name;
41 char DHCPCACHE[]=_PATH_DHCPCACHE;
43 int main( int argc, char *argv[] );
44 void usage( void );
46 int main(argc, argv)
47 int argc;
48 char *argv[];
50 int c;
51 int first_print;
52 int a_flag, e_flag, i_flag, h_flag;
53 char *E_arg, *I_arg;
54 int do_ether, do_ip, do_asc_ip, do_hostname;
55 char *eth_device, *ip_device;
56 int eth_fd, ip_fd;
57 int result;
58 nwio_ethstat_t nwio_ethstat;
59 nwio_ipconf_t nwio_ipconf;
60 struct hostent *hostent;
61 char *hostname, *domain;
62 char nodename[2*256];
63 dhcp_t dhcp;
65 first_print= 1;
66 prog_name= argv[0];
68 a_flag= e_flag= h_flag = i_flag= 0;
69 E_arg= I_arg= NULL;
71 while((c= getopt(argc, argv, "?aheE:iI:")) != -1)
73 switch(c)
75 case '?':
76 usage();
77 case 'a':
78 if (a_flag)
79 usage();
80 a_flag= 1;
81 break;
82 case 'h':
83 if (h_flag)
84 usage();
85 h_flag= 1;
86 break;
87 case 'e':
88 if (e_flag)
89 usage();
90 e_flag= 1;
91 break;
92 case 'E':
93 if (E_arg)
94 usage();
95 E_arg= optarg;
96 break;
97 case 'i':
98 if (i_flag)
99 usage();
100 i_flag= 1;
101 break;
102 case 'I':
103 if (I_arg)
104 usage();
105 I_arg= optarg;
106 break;
107 default:
108 usage();
111 if(optind != argc)
112 usage();
114 do_ether= e_flag;
115 if (E_arg)
116 eth_device= E_arg;
117 else
119 eth_device= getenv("ETH_DEVICE");
120 if (!eth_device)
121 eth_device= ETH_DEVICE;
124 do_ip= i_flag;
125 do_asc_ip= a_flag;
126 do_hostname= h_flag;
127 if (I_arg)
128 ip_device= I_arg;
129 else
131 ip_device= getenv("IP_DEVICE");
132 if (!ip_device)
133 ip_device= IP_DEVICE;
136 if (!do_ether && !do_ip && !do_asc_ip && !do_hostname)
137 do_ether= do_ip= do_asc_ip= 1;
139 if (do_ether)
141 eth_fd= open(eth_device, O_RDWR);
142 if (eth_fd == -1)
144 fprintf(stderr, "%s: Unable to open '%s': %s\n",
145 prog_name, eth_device, strerror(errno));
146 exit(1);
148 result= ioctl(eth_fd, NWIOGETHSTAT, &nwio_ethstat);
149 if (result == -1)
151 fprintf(stderr,
152 "%s: Unable to fetch ethernet address: %s\n",
153 prog_name, strerror(errno));
154 exit(1);
156 printf("%s%s", first_print ? "" : " ",
157 ether_ntoa(&nwio_ethstat.nwes_addr));
158 first_print= 0;
160 if (do_ip || do_asc_ip || do_hostname)
162 ip_fd= open(ip_device, O_RDWR);
163 if (ip_fd == -1)
165 fprintf(stderr, "%s: Unable to open '%s': %s\n",
166 prog_name, ip_device, strerror(errno));
167 exit(1);
169 result= ioctl(ip_fd, NWIOGIPCONF, &nwio_ipconf);
170 if (result == -1)
172 fprintf(stderr,
173 "%s: Unable to fetch IP address: %s\n",
174 prog_name,
175 strerror(errno));
176 exit(1);
180 setuid(getuid());
182 if (do_ip)
184 printf("%s%s", first_print ? "" : " ",
185 inet_ntoa(nwio_ipconf.nwic_ipaddr));
186 first_print= 0;
188 if (do_asc_ip || do_hostname)
190 int fd;
191 int r;
192 dhcp_t d;
193 u8_t *data;
194 size_t hlen, dlen;
196 hostname= NULL;
197 domain= NULL;
199 /* Use a reverse DNS lookup to get the host name. This is
200 * the preferred method, but often fails due to lazy admins.
202 hostent= gethostbyaddr((char *)&nwio_ipconf.nwic_ipaddr,
203 sizeof(nwio_ipconf.nwic_ipaddr), AF_INET);
204 if (hostent != NULL) hostname= hostent->h_name;
206 if (hostname != NULL)
208 /* Reverse DNS works. */
210 else if ((fd= open(DHCPCACHE, O_RDONLY)) == -1)
212 if (errno != ENOENT)
214 fprintf(stderr, "%s: %s: %s\n",
215 prog_name, DHCPCACHE, strerror(errno));
216 exit(1);
219 else
221 /* Try to get the hostname from the DHCP data. */
222 while ((r= read(fd, &d, sizeof(d))) == sizeof(d))
224 if (d.yiaddr == nwio_ipconf.nwic_ipaddr) break;
226 if (r < 0)
228 fprintf(stderr, "%s: %s: %s\n",
229 prog_name, DHCPCACHE, strerror(errno));
230 exit(1);
232 close(fd);
234 if (r == sizeof(d))
236 if (dhcp_gettag(&d, DHCP_TAG_HOSTNAME,
237 &data, &hlen))
238 hostname= (char *) data;
240 if (dhcp_gettag(&d, DHCP_TAG_DOMAIN,
241 &data, &dlen))
242 domain= (char *) data;
244 if (hostname != NULL) hostname[hlen] = 0;
245 if (domain != NULL) domain[dlen] = 0;
249 if (hostname != NULL)
251 if (strchr(hostname, '.') != NULL)
253 domain= strchr(hostname, '.');
254 *domain++ = 0;
257 else
259 /* No host name anywhere. Use the IP address. */
260 hostname= inet_ntoa(nwio_ipconf.nwic_ipaddr);
261 domain= NULL;
264 strcpy(nodename, hostname);
265 if (domain != NULL)
267 strcat(nodename, ".");
268 strcat(nodename, domain);
271 if (do_asc_ip)
273 printf("%s%s", first_print ? "" : " ", nodename);
274 first_print= 0;
276 if (do_hostname)
278 #if __minix_vmd
279 if (sysuname(_UTS_SET, _UTS_NODENAME,
280 nodename, strlen(nodename)+1) == -1)
282 fprintf(stderr, "%s: Unable to set nodename: %s\n",
283 prog_name, strerror(errno));
284 exit(1);
287 if (sysuname(_UTS_SET, _UTS_HOSTNAME,
288 hostname, strlen(hostname)+1) == -1)
290 fprintf(stderr, "%s: Unable to set hostname: %s\n",
291 prog_name, strerror(errno));
292 exit(1);
294 #else
295 FILE *fp;
297 if ((fp= fopen("/etc/hostname.file", "w")) == NULL
298 || fprintf(fp, "%s\n", nodename) == EOF
299 || fclose(fp) == EOF)
301 fprintf(stderr, "%s: /etc/hostname.file: %s\n",
302 prog_name, strerror(errno));
303 exit(1);
305 #endif
307 if (!first_print) printf("\n");
308 exit(0);
311 void usage()
313 fprintf(stderr,
314 "Usage: %s -[eiah] [-E <eth-device>] [-I <ip-device>]\n",
315 prog_name);
316 exit(1);