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 * $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.2 2003/06/17 04:29:52 dillon Exp $
15 #include <rpcsvc/yp_prot.h>
16 #include <rpcsvc/ypclnt.h>
17 #include "bootparam_prot.h"
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 extern int debug, dolog;
28 extern unsigned long route_addr;
29 extern char *bootpfile;
34 static char buffer[MAXLEN];
35 static char hostname[MAX_MACHINE_NAME];
36 static char askname[MAX_MACHINE_NAME];
37 static char path[MAX_PATH_LEN];
38 static char domain_name[MAX_MACHINE_NAME];
40 int getthefile __P((char *, char *, char *, int));
41 int checkhost __P((char *, char *, int));
44 bootparamproc_whoami_1(whoami)
45 bp_whoami_arg *whoami;
48 static bp_whoami_res res;
50 fprintf(stderr,"whoami got question for %d.%d.%d.%d\n",
51 255 & whoami->client_address.bp_address_u.ip_addr.net,
52 255 & whoami->client_address.bp_address_u.ip_addr.host,
53 255 & whoami->client_address.bp_address_u.ip_addr.lh,
54 255 & whoami->client_address.bp_address_u.ip_addr.impno);
56 syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
57 255 & whoami->client_address.bp_address_u.ip_addr.net,
58 255 & whoami->client_address.bp_address_u.ip_addr.host,
59 255 & whoami->client_address.bp_address_u.ip_addr.lh,
60 255 & whoami->client_address.bp_address_u.ip_addr.impno);
62 bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr,
64 he = gethostbyaddr((char *)&haddr,sizeof(haddr),AF_INET);
65 if ( ! he ) goto failed;
67 if (debug) warnx("this is host %s", he->h_name);
68 if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name);
70 strncpy(askname, he->h_name, sizeof(askname));
71 askname[sizeof(askname)-1] = 0;
73 if (checkhost(askname, hostname, sizeof hostname) ) {
74 res.client_name = hostname;
75 getdomainname(domain_name, MAX_MACHINE_NAME);
76 res.domain_name = domain_name;
78 if ( res.router_address.address_type != IP_ADDR_TYPE ) {
79 res.router_address.address_type = IP_ADDR_TYPE;
80 bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4);
82 if (debug) fprintf(stderr,
83 "Returning %s %s %d.%d.%d.%d\n",
86 255 & res.router_address.bp_address_u.ip_addr.net,
87 255 & res.router_address.bp_address_u.ip_addr.host,
88 255 & res.router_address.bp_address_u.ip_addr.lh,
89 255 & res.router_address.bp_address_u.ip_addr.impno);
90 if (dolog) syslog(LOG_NOTICE,
91 "Returning %s %s %d.%d.%d.%d\n",
94 255 & res.router_address.bp_address_u.ip_addr.net,
95 255 & res.router_address.bp_address_u.ip_addr.host,
96 255 & res.router_address.bp_address_u.ip_addr.lh,
97 255 & res.router_address.bp_address_u.ip_addr.impno);
102 if (debug) warnx("whoami failed");
103 if (dolog) syslog(LOG_NOTICE,"whoami failed\n");
109 bootparamproc_getfile_1(getfile)
110 bp_getfile_arg *getfile;
112 char *where, *index();
113 static bp_getfile_res res;
116 warnx("getfile got question for \"%s\" and file \"%s\"",
117 getfile->client_name, getfile->file_id);
120 syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n",
121 getfile->client_name, getfile->file_id);
124 he = gethostbyname(getfile->client_name);
125 if (! he ) goto failed;
127 strncpy(askname, he->h_name, sizeof(askname));
128 askname[sizeof(askname)-1] = 0;
130 if (getthefile(askname, getfile->file_id,buffer,sizeof(buffer))) {
131 if ( (where = index(buffer,':')) ) {
132 /* buffer is re-written to contain the name of the info of file */
133 strncpy(hostname, buffer, where - buffer);
134 hostname[where - buffer] = '\0';
137 he = gethostbyname(hostname);
138 if ( !he ) goto failed;
139 bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
140 res.server_name = hostname;
141 res.server_path = path;
142 res.server_address.address_type = IP_ADDR_TYPE;
144 else { /* special for dump, answer with null strings */
145 if (!strcmp(getfile->file_id, "dump")) {
146 res.server_name = "";
147 res.server_path = "";
148 res.server_address.address_type = IP_ADDR_TYPE;
149 bzero(&res.server_address.bp_address_u.ip_addr,4);
153 fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n",
154 res.server_name, res.server_path,
155 255 & res.server_address.bp_address_u.ip_addr.net,
156 255 & res.server_address.bp_address_u.ip_addr.host,
157 255 & res.server_address.bp_address_u.ip_addr.lh,
158 255 & res.server_address.bp_address_u.ip_addr.impno);
160 syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n",
161 res.server_name, res.server_path,
162 255 & res.server_address.bp_address_u.ip_addr.net,
163 255 & res.server_address.bp_address_u.ip_addr.host,
164 255 & res.server_address.bp_address_u.ip_addr.lh,
165 255 & res.server_address.bp_address_u.ip_addr.impno);
169 if (debug) warnx("getfile failed for %s", getfile->client_name);
170 if (dolog) syslog(LOG_NOTICE,
171 "getfile failed for %s\n", getfile->client_name);
175 /* getthefile return 1 and fills the buffer with the information
176 of the file, e g "host:/export/root/client" if it can be found.
177 If the host is in the database, but the file is not, the buffer
178 will be empty. (This makes it possible to give the special
179 empty answer for the file "dump") */
182 getthefile(askname,fileid,buffer,blen)
184 char *fileid, *buffer;
191 static char *yp_domain;
193 int ch, pch, fid_len, res = 0;
195 char info[MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3];
197 bpf = fopen(bootpfile, "r");
199 errx(1, "no %s", bootpfile);
201 /* XXX see comment below */
202 while ( fscanf(bpf, "%255s", hostname) > 0 && !match ) {
203 if ( *hostname != '#' ) { /* comment */
204 if ( ! strcmp(hostname, askname) ) {
207 he = gethostbyname(hostname);
208 if (he && !strcmp(he->h_name, askname)) match = 1;
211 if (*hostname == '+' ) { /* NIS */
212 if (yp_get_default_domain(&yp_domain)) {
213 if (debug) warn("NIS");
216 if (yp_match(yp_domain, "bootparams", askname, strlen(askname),
217 &result, &resultlen))
219 if (strstr(result, fileid) == NULL) {
222 snprintf(buffer, blen,
223 "%s",strchr(strstr(result,fileid), '=') + 1);
224 if (strchr(buffer, ' ') != NULL)
225 *(char *)(strchr(buffer, ' ')) = '\0';
228 warnx("could not close %s", bootpfile);
231 /* skip to next entry */
233 pch = ch = getc(bpf);
234 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
235 pch = ch; ch = getc(bpf);
239 /* if match is true we read the rest of the line to get the
243 fid_len = strlen(fileid);
244 while ( ! res && (fscanf(bpf,"%s", info)) > 0) { /* read a string */
245 ch = getc(bpf); /* and a character */
246 if ( *info != '#' ) { /* Comment ? */
247 if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') {
248 where = info + fid_len + 1;
249 if ( isprint( *where )) {
250 strcpy(buffer, where); /* found file */
254 while (isspace(ch) && ch != '\n') ch = getc(bpf);
255 /* read to end of line */
256 if ( ch == '\n' ) { /* didn't find it */
257 res = -1; break; /* but host is there */
259 if ( ch == '\\' ) { /* more info */
260 ch = getc(bpf); /* maybe on next line */
261 if (ch == '\n') continue; /* read it in next loop */
262 ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */
263 } else ungetc(ch, bpf); /* but who know what a `\` is */
265 } else break; /* a commented rest-of-line */
268 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
269 if ( res == -1) buffer[0] = '\0'; /* host found, file not */
273 /* checkhost puts the hostname found in the database file in
274 the hostname-variable and returns 1, if askname is a valid
275 name for a host in the database */
278 checkhost(askname, hostname, len)
288 static char *yp_domain;
290 /* struct hostent *cmp_he;*/
292 bpf = fopen(bootpfile, "r");
294 errx(1, "no %s", bootpfile);
296 /* XXX there is no way in ISO C to specify the maximal length for a
297 conversion in a variable way */
298 while ( fscanf(bpf, "%254s", hostname) > 0 ) {
299 if ( *hostname != '#' ) { /* comment */
300 if ( ! strcmp(hostname, askname) ) {
301 /* return true for match of hostname */
305 /* check the alias list */
307 he = gethostbyname(hostname);
308 if (he && !strcmp(askname, he->h_name)) {
314 if (*hostname == '+' ) { /* NIS */
315 if (yp_get_default_domain(&yp_domain)) {
316 if (debug) warn("NIS");
319 if (!yp_match(yp_domain, "bootparams", askname, strlen(askname),
320 &result, &resultlen)) {
321 /* return true for match of hostname */
323 he = gethostbyname(askname);
324 if (he && !strcmp(askname, he->h_name)) {
326 snprintf(hostname, len, "%s", he->h_name);
330 warnx("could not close %s", bootpfile);
333 /* skip to next entry */
334 pch = ch = getc(bpf);
335 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
336 pch = ch; ch = getc(bpf);
339 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }