Remove some unnecessary casts.
[dragonfly.git] / usr.sbin / bootparamd / bootparamd / bootparamd.c
... / ...
CommitLineData
1/*
2
3This code is not copyright, and is placed in the public domain. Feel free to
4use and modify. Please send modifications and/or suggestions + bug fixes to
5
6 Klas Heggemann <klas@nada.kth.se>
7
8*/
9
10/*
11 * $FreeBSD: src/usr.sbin/bootparamd/bootparamd/bootparamd.c,v 1.10 1999/08/28 01:15:39 peter Exp $
12 * $DragonFly: src/usr.sbin/bootparamd/bootparamd/bootparamd.c,v 1.4 2003/11/15 23:33:35 eirikn Exp $
13 */
14#include <rpc/rpc.h>
15#include <rpcsvc/yp_prot.h>
16#include <rpcsvc/ypclnt.h>
17#include "bootparam_prot.h"
18#include <ctype.h>
19#include <err.h>
20#include <netdb.h>
21#include <stdio.h>
22#include <string.h>
23#include <syslog.h>
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/socket.h>
27extern int debug, dolog;
28extern unsigned long route_addr;
29extern char *bootpfile;
30
31#define MAXLEN 800
32
33struct hostent *he;
34static char buffer[MAXLEN];
35static char hostname[MAX_MACHINE_NAME];
36static char askname[MAX_MACHINE_NAME];
37static char path[MAX_PATH_LEN];
38static char domain_name[MAX_MACHINE_NAME];
39
40int getthefile(char *, char *, char *, int);
41int checkhost(char *, char *, int);
42
43bp_whoami_res *
44bootparamproc_whoami_1(bp_whoami_arg *whoami)
45{
46 long haddr;
47 static bp_whoami_res res;
48 if (debug)
49 fprintf(stderr,"whoami got question for %d.%d.%d.%d\n",
50 255 & whoami->client_address.bp_address_u.ip_addr.net,
51 255 & whoami->client_address.bp_address_u.ip_addr.host,
52 255 & whoami->client_address.bp_address_u.ip_addr.lh,
53 255 & whoami->client_address.bp_address_u.ip_addr.impno);
54 if (dolog)
55 syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
56 255 & whoami->client_address.bp_address_u.ip_addr.net,
57 255 & whoami->client_address.bp_address_u.ip_addr.host,
58 255 & whoami->client_address.bp_address_u.ip_addr.lh,
59 255 & whoami->client_address.bp_address_u.ip_addr.impno);
60
61 bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr,
62 sizeof(haddr));
63 he = gethostbyaddr(&haddr,sizeof(haddr),AF_INET);
64 if ( ! he ) goto failed;
65
66 if (debug) warnx("this is host %s", he->h_name);
67 if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name);
68
69 strncpy(askname, he->h_name, sizeof(askname));
70 askname[sizeof(askname)-1] = 0;
71
72 if (checkhost(askname, hostname, sizeof hostname) ) {
73 res.client_name = hostname;
74 getdomainname(domain_name, MAX_MACHINE_NAME);
75 res.domain_name = domain_name;
76
77 if ( res.router_address.address_type != IP_ADDR_TYPE ) {
78 res.router_address.address_type = IP_ADDR_TYPE;
79 bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4);
80 }
81 if (debug) fprintf(stderr,
82 "Returning %s %s %d.%d.%d.%d\n",
83 res.client_name,
84 res.domain_name,
85 255 & res.router_address.bp_address_u.ip_addr.net,
86 255 & res.router_address.bp_address_u.ip_addr.host,
87 255 & res.router_address.bp_address_u.ip_addr.lh,
88 255 & res.router_address.bp_address_u.ip_addr.impno);
89 if (dolog) syslog(LOG_NOTICE,
90 "Returning %s %s %d.%d.%d.%d\n",
91 res.client_name,
92 res.domain_name,
93 255 & res.router_address.bp_address_u.ip_addr.net,
94 255 & res.router_address.bp_address_u.ip_addr.host,
95 255 & res.router_address.bp_address_u.ip_addr.lh,
96 255 & res.router_address.bp_address_u.ip_addr.impno);
97
98 return(&res);
99 }
100 failed:
101 if (debug) warnx("whoami failed");
102 if (dolog) syslog(LOG_NOTICE,"whoami failed\n");
103 return(NULL);
104}
105
106
107bp_getfile_res *
108bootparamproc_getfile_1(bp_getfile_arg *getfile)
109{
110 char *where, *index();
111 static bp_getfile_res res;
112
113 if (debug)
114 warnx("getfile got question for \"%s\" and file \"%s\"",
115 getfile->client_name, getfile->file_id);
116
117 if (dolog)
118 syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n",
119 getfile->client_name, getfile->file_id);
120
121 he = NULL;
122 he = gethostbyname(getfile->client_name);
123 if (! he ) goto failed;
124
125 strncpy(askname, he->h_name, sizeof(askname));
126 askname[sizeof(askname)-1] = 0;
127
128 if (getthefile(askname, getfile->file_id,buffer,sizeof(buffer))) {
129 if ( (where = index(buffer,':')) ) {
130 /* buffer is re-written to contain the name of the info of file */
131 strncpy(hostname, buffer, where - buffer);
132 hostname[where - buffer] = '\0';
133 where++;
134 strcpy(path, where);
135 he = gethostbyname(hostname);
136 if ( !he ) goto failed;
137 bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
138 res.server_name = hostname;
139 res.server_path = path;
140 res.server_address.address_type = IP_ADDR_TYPE;
141 }
142 else { /* special for dump, answer with null strings */
143 if (!strcmp(getfile->file_id, "dump")) {
144 res.server_name = "";
145 res.server_path = "";
146 res.server_address.address_type = IP_ADDR_TYPE;
147 bzero(&res.server_address.bp_address_u.ip_addr,4);
148 } else goto failed;
149 }
150 if (debug)
151 fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n",
152 res.server_name, res.server_path,
153 255 & res.server_address.bp_address_u.ip_addr.net,
154 255 & res.server_address.bp_address_u.ip_addr.host,
155 255 & res.server_address.bp_address_u.ip_addr.lh,
156 255 & res.server_address.bp_address_u.ip_addr.impno);
157 if (dolog)
158 syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n",
159 res.server_name, res.server_path,
160 255 & res.server_address.bp_address_u.ip_addr.net,
161 255 & res.server_address.bp_address_u.ip_addr.host,
162 255 & res.server_address.bp_address_u.ip_addr.lh,
163 255 & res.server_address.bp_address_u.ip_addr.impno);
164 return(&res);
165 }
166 failed:
167 if (debug) warnx("getfile failed for %s", getfile->client_name);
168 if (dolog) syslog(LOG_NOTICE,
169 "getfile failed for %s\n", getfile->client_name);
170 return(NULL);
171}
172
173/* getthefile return 1 and fills the buffer with the information
174 of the file, e g "host:/export/root/client" if it can be found.
175 If the host is in the database, but the file is not, the buffer
176 will be empty. (This makes it possible to give the special
177 empty answer for the file "dump") */
178
179int
180getthefile(char *askname, char *fileid, char *buffer, int blen)
181{
182 FILE *bpf;
183 char *where;
184 static char *result;
185 int resultlen;
186 static char *yp_domain;
187
188 int ch, pch, fid_len, res = 0;
189 int match = 0;
190 char info[MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3];
191
192 bpf = fopen(bootpfile, "r");
193 if ( ! bpf )
194 errx(1, "no %s", bootpfile);
195
196 /* XXX see comment below */
197 while ( fscanf(bpf, "%255s", hostname) > 0 && !match ) {
198 if ( *hostname != '#' ) { /* comment */
199 if ( ! strcmp(hostname, askname) ) {
200 match = 1;
201 } else {
202 he = gethostbyname(hostname);
203 if (he && !strcmp(he->h_name, askname)) match = 1;
204 }
205 }
206 if (*hostname == '+' ) { /* NIS */
207 if (yp_get_default_domain(&yp_domain)) {
208 if (debug) warn("NIS");
209 return(0);
210 }
211 if (yp_match(yp_domain, "bootparams", askname, strlen(askname),
212 &result, &resultlen))
213 return (0);
214 if (strstr(result, fileid) == NULL) {
215 buffer[0] = '\0';
216 } else {
217 snprintf(buffer, blen,
218 "%s",strchr(strstr(result,fileid), '=') + 1);
219 if (strchr(buffer, ' ') != NULL)
220 *(char *)(strchr(buffer, ' ')) = '\0';
221 }
222 if (fclose(bpf))
223 warnx("could not close %s", bootpfile);
224 return(1);
225 }
226 /* skip to next entry */
227 if ( match ) break;
228 pch = ch = getc(bpf);
229 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
230 pch = ch; ch = getc(bpf);
231 }
232 }
233
234 /* if match is true we read the rest of the line to get the
235 info of the file */
236
237 if (match) {
238 fid_len = strlen(fileid);
239 while ( ! res && (fscanf(bpf,"%s", info)) > 0) { /* read a string */
240 ch = getc(bpf); /* and a character */
241 if ( *info != '#' ) { /* Comment ? */
242 if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') {
243 where = info + fid_len + 1;
244 if ( isprint( *where )) {
245 strcpy(buffer, where); /* found file */
246 res = 1; break;
247 }
248 } else {
249 while (isspace(ch) && ch != '\n') ch = getc(bpf);
250 /* read to end of line */
251 if ( ch == '\n' ) { /* didn't find it */
252 res = -1; break; /* but host is there */
253 }
254 if ( ch == '\\' ) { /* more info */
255 ch = getc(bpf); /* maybe on next line */
256 if (ch == '\n') continue; /* read it in next loop */
257 ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */
258 } else ungetc(ch, bpf); /* but who know what a `\` is */
259 } /* needed for. */
260 } else break; /* a commented rest-of-line */
261 }
262 }
263 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
264 if ( res == -1) buffer[0] = '\0'; /* host found, file not */
265 return(match);
266}
267
268/* checkhost puts the hostname found in the database file in
269 the hostname-variable and returns 1, if askname is a valid
270 name for a host in the database */
271
272int
273checkhost(char *askname, char *hostname, int len)
274{
275 int ch, pch;
276 FILE *bpf;
277 int res = 0;
278 static char *result;
279 int resultlen;
280 static char *yp_domain;
281
282/* struct hostent *cmp_he;*/
283
284 bpf = fopen(bootpfile, "r");
285 if ( ! bpf )
286 errx(1, "no %s", bootpfile);
287
288 /* XXX there is no way in ISO C to specify the maximal length for a
289 conversion in a variable way */
290 while ( fscanf(bpf, "%254s", hostname) > 0 ) {
291 if ( *hostname != '#' ) { /* comment */
292 if ( ! strcmp(hostname, askname) ) {
293 /* return true for match of hostname */
294 res = 1;
295 break;
296 } else {
297 /* check the alias list */
298 he = NULL;
299 he = gethostbyname(hostname);
300 if (he && !strcmp(askname, he->h_name)) {
301 res = 1;
302 break;
303 }
304 }
305 }
306 if (*hostname == '+' ) { /* NIS */
307 if (yp_get_default_domain(&yp_domain)) {
308 if (debug) warn("NIS");
309 return(0);
310 }
311 if (!yp_match(yp_domain, "bootparams", askname, strlen(askname),
312 &result, &resultlen)) {
313 /* return true for match of hostname */
314 he = NULL;
315 he = gethostbyname(askname);
316 if (he && !strcmp(askname, he->h_name)) {
317 res = 1;
318 snprintf(hostname, len, "%s", he->h_name);
319 }
320 }
321 if (fclose(bpf))
322 warnx("could not close %s", bootpfile);
323 return(res);
324 }
325 /* skip to next entry */
326 pch = ch = getc(bpf);
327 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
328 pch = ch; ch = getc(bpf);
329 }
330 }
331 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
332 return(res);
333}