3 This code is not copyright, and is placed in the public domain. Feel free to
4 use and modify. Please send modifications and/or suggestions + bug fixes to
6 Klas Heggemann <klas@nada.kth.se>
11 static const char rcsid[] =
12 "$FreeBSD: src/usr.sbin/bootparamd/bootparamd/bootparamd.c,v 1.10 1999/08/28 01:15:39 peter Exp $";
16 #include <rpcsvc/yp_prot.h>
17 #include <rpcsvc/ypclnt.h>
18 #include "bootparam_prot.h"
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 extern int debug, dolog;
29 extern unsigned long route_addr;
30 extern char *bootpfile;
35 static char buffer[MAXLEN];
36 static char hostname[MAX_MACHINE_NAME];
37 static char askname[MAX_MACHINE_NAME];
38 static char path[MAX_PATH_LEN];
39 static char domain_name[MAX_MACHINE_NAME];
41 int getthefile __P((char *, char *, char *, int));
42 int checkhost __P((char *, char *, int));
45 bootparamproc_whoami_1(whoami)
46 bp_whoami_arg *whoami;
49 static bp_whoami_res res;
51 fprintf(stderr,"whoami got question for %d.%d.%d.%d\n",
52 255 & whoami->client_address.bp_address_u.ip_addr.net,
53 255 & whoami->client_address.bp_address_u.ip_addr.host,
54 255 & whoami->client_address.bp_address_u.ip_addr.lh,
55 255 & whoami->client_address.bp_address_u.ip_addr.impno);
57 syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
58 255 & whoami->client_address.bp_address_u.ip_addr.net,
59 255 & whoami->client_address.bp_address_u.ip_addr.host,
60 255 & whoami->client_address.bp_address_u.ip_addr.lh,
61 255 & whoami->client_address.bp_address_u.ip_addr.impno);
63 bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr,
65 he = gethostbyaddr((char *)&haddr,sizeof(haddr),AF_INET);
66 if ( ! he ) goto failed;
68 if (debug) warnx("this is host %s", he->h_name);
69 if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name);
71 strncpy(askname, he->h_name, sizeof(askname));
72 askname[sizeof(askname)-1] = 0;
74 if (checkhost(askname, hostname, sizeof hostname) ) {
75 res.client_name = hostname;
76 getdomainname(domain_name, MAX_MACHINE_NAME);
77 res.domain_name = domain_name;
79 if ( res.router_address.address_type != IP_ADDR_TYPE ) {
80 res.router_address.address_type = IP_ADDR_TYPE;
81 bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4);
83 if (debug) fprintf(stderr,
84 "Returning %s %s %d.%d.%d.%d\n",
87 255 & res.router_address.bp_address_u.ip_addr.net,
88 255 & res.router_address.bp_address_u.ip_addr.host,
89 255 & res.router_address.bp_address_u.ip_addr.lh,
90 255 & res.router_address.bp_address_u.ip_addr.impno);
91 if (dolog) syslog(LOG_NOTICE,
92 "Returning %s %s %d.%d.%d.%d\n",
95 255 & res.router_address.bp_address_u.ip_addr.net,
96 255 & res.router_address.bp_address_u.ip_addr.host,
97 255 & res.router_address.bp_address_u.ip_addr.lh,
98 255 & res.router_address.bp_address_u.ip_addr.impno);
103 if (debug) warnx("whoami failed");
104 if (dolog) syslog(LOG_NOTICE,"whoami failed\n");
110 bootparamproc_getfile_1(getfile)
111 bp_getfile_arg *getfile;
113 char *where, *index();
114 static bp_getfile_res res;
117 warnx("getfile got question for \"%s\" and file \"%s\"",
118 getfile->client_name, getfile->file_id);
121 syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n",
122 getfile->client_name, getfile->file_id);
125 he = gethostbyname(getfile->client_name);
126 if (! he ) goto failed;
128 strncpy(askname, he->h_name, sizeof(askname));
129 askname[sizeof(askname)-1] = 0;
131 if (getthefile(askname, getfile->file_id,buffer,sizeof(buffer))) {
132 if ( (where = index(buffer,':')) ) {
133 /* buffer is re-written to contain the name of the info of file */
134 strncpy(hostname, buffer, where - buffer);
135 hostname[where - buffer] = '\0';
138 he = gethostbyname(hostname);
139 if ( !he ) goto failed;
140 bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
141 res.server_name = hostname;
142 res.server_path = path;
143 res.server_address.address_type = IP_ADDR_TYPE;
145 else { /* special for dump, answer with null strings */
146 if (!strcmp(getfile->file_id, "dump")) {
147 res.server_name = "";
148 res.server_path = "";
149 res.server_address.address_type = IP_ADDR_TYPE;
150 bzero(&res.server_address.bp_address_u.ip_addr,4);
154 fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n",
155 res.server_name, res.server_path,
156 255 & res.server_address.bp_address_u.ip_addr.net,
157 255 & res.server_address.bp_address_u.ip_addr.host,
158 255 & res.server_address.bp_address_u.ip_addr.lh,
159 255 & res.server_address.bp_address_u.ip_addr.impno);
161 syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n",
162 res.server_name, res.server_path,
163 255 & res.server_address.bp_address_u.ip_addr.net,
164 255 & res.server_address.bp_address_u.ip_addr.host,
165 255 & res.server_address.bp_address_u.ip_addr.lh,
166 255 & res.server_address.bp_address_u.ip_addr.impno);
170 if (debug) warnx("getfile failed for %s", getfile->client_name);
171 if (dolog) syslog(LOG_NOTICE,
172 "getfile failed for %s\n", getfile->client_name);
176 /* getthefile return 1 and fills the buffer with the information
177 of the file, e g "host:/export/root/client" if it can be found.
178 If the host is in the database, but the file is not, the buffer
179 will be empty. (This makes it possible to give the special
180 empty answer for the file "dump") */
183 getthefile(askname,fileid,buffer,blen)
185 char *fileid, *buffer;
192 static char *yp_domain;
194 int ch, pch, fid_len, res = 0;
196 char info[MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3];
198 bpf = fopen(bootpfile, "r");
200 errx(1, "no %s", bootpfile);
202 /* XXX see comment below */
203 while ( fscanf(bpf, "%255s", hostname) > 0 && !match ) {
204 if ( *hostname != '#' ) { /* comment */
205 if ( ! strcmp(hostname, askname) ) {
208 he = gethostbyname(hostname);
209 if (he && !strcmp(he->h_name, askname)) match = 1;
212 if (*hostname == '+' ) { /* NIS */
213 if (yp_get_default_domain(&yp_domain)) {
214 if (debug) warn("NIS");
217 if (yp_match(yp_domain, "bootparams", askname, strlen(askname),
218 &result, &resultlen))
220 if (strstr(result, fileid) == NULL) {
223 snprintf(buffer, blen,
224 "%s",strchr(strstr(result,fileid), '=') + 1);
225 if (strchr(buffer, ' ') != NULL)
226 *(char *)(strchr(buffer, ' ')) = '\0';
229 warnx("could not close %s", bootpfile);
232 /* skip to next entry */
234 pch = ch = getc(bpf);
235 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
236 pch = ch; ch = getc(bpf);
240 /* if match is true we read the rest of the line to get the
244 fid_len = strlen(fileid);
245 while ( ! res && (fscanf(bpf,"%s", info)) > 0) { /* read a string */
246 ch = getc(bpf); /* and a character */
247 if ( *info != '#' ) { /* Comment ? */
248 if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') {
249 where = info + fid_len + 1;
250 if ( isprint( *where )) {
251 strcpy(buffer, where); /* found file */
255 while (isspace(ch) && ch != '\n') ch = getc(bpf);
256 /* read to end of line */
257 if ( ch == '\n' ) { /* didn't find it */
258 res = -1; break; /* but host is there */
260 if ( ch == '\\' ) { /* more info */
261 ch = getc(bpf); /* maybe on next line */
262 if (ch == '\n') continue; /* read it in next loop */
263 ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */
264 } else ungetc(ch, bpf); /* but who know what a `\` is */
266 } else break; /* a commented rest-of-line */
269 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
270 if ( res == -1) buffer[0] = '\0'; /* host found, file not */
274 /* checkhost puts the hostname found in the database file in
275 the hostname-variable and returns 1, if askname is a valid
276 name for a host in the database */
279 checkhost(askname, hostname, len)
289 static char *yp_domain;
291 /* struct hostent *cmp_he;*/
293 bpf = fopen(bootpfile, "r");
295 errx(1, "no %s", bootpfile);
297 /* XXX there is no way in ISO C to specify the maximal length for a
298 conversion in a variable way */
299 while ( fscanf(bpf, "%254s", hostname) > 0 ) {
300 if ( *hostname != '#' ) { /* comment */
301 if ( ! strcmp(hostname, askname) ) {
302 /* return true for match of hostname */
306 /* check the alias list */
308 he = gethostbyname(hostname);
309 if (he && !strcmp(askname, he->h_name)) {
315 if (*hostname == '+' ) { /* NIS */
316 if (yp_get_default_domain(&yp_domain)) {
317 if (debug) warn("NIS");
320 if (!yp_match(yp_domain, "bootparams", askname, strlen(askname),
321 &result, &resultlen)) {
322 /* return true for match of hostname */
324 he = gethostbyname(askname);
325 if (he && !strcmp(askname, he->h_name)) {
327 snprintf(hostname, len, "%s", he->h_name);
331 warnx("could not close %s", bootpfile);
334 /* skip to next entry */
335 pch = ch = getc(bpf);
336 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
337 pch = ch; ch = getc(bpf);
340 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }