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[] =
17 #include <rpcsvc/yp_prot.h>
18 #include <rpcsvc/ypclnt.h>
20 #include "bootparam_prot.h"
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 extern int debug, dolog;
31 extern in_addr_t route_addr;
32 extern char *bootpfile;
37 static char buffer[MAXLEN];
38 static char hostname[MAX_MACHINE_NAME];
39 static char askname[MAX_MACHINE_NAME];
40 static char path[MAX_PATH_LEN];
41 static char domain_name[MAX_MACHINE_NAME];
43 int getthefile(char *, char *, char *, int);
44 int checkhost(char *, char *, int);
47 bootparamproc_whoami_1_svc(whoami, req)
48 bp_whoami_arg *whoami;
52 static bp_whoami_res res;
54 fprintf(stderr,"whoami got question for %d.%d.%d.%d\n",
55 255 & whoami->client_address.bp_address_u.ip_addr.net,
56 255 & whoami->client_address.bp_address_u.ip_addr.host,
57 255 & whoami->client_address.bp_address_u.ip_addr.lh,
58 255 & whoami->client_address.bp_address_u.ip_addr.impno);
60 syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
61 255 & whoami->client_address.bp_address_u.ip_addr.net,
62 255 & whoami->client_address.bp_address_u.ip_addr.host,
63 255 & whoami->client_address.bp_address_u.ip_addr.lh,
64 255 & whoami->client_address.bp_address_u.ip_addr.impno);
66 bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr,
68 he = gethostbyaddr((char *)&haddr,sizeof(haddr),AF_INET);
69 if ( ! he ) goto failed;
71 if (debug) warnx("this is host %s", he->h_name);
72 if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name);
74 strncpy(askname, he->h_name, sizeof(askname));
75 askname[sizeof(askname)-1] = 0;
77 if (checkhost(askname, hostname, sizeof hostname) ) {
78 res.client_name = hostname;
79 getdomainname(domain_name, MAX_MACHINE_NAME);
80 res.domain_name = domain_name;
82 if ( res.router_address.address_type != IP_ADDR_TYPE ) {
83 res.router_address.address_type = IP_ADDR_TYPE;
84 bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, sizeof(in_addr_t));
86 if (debug) fprintf(stderr,
87 "Returning %s %s %d.%d.%d.%d\n",
90 255 & res.router_address.bp_address_u.ip_addr.net,
91 255 & res.router_address.bp_address_u.ip_addr.host,
92 255 & res.router_address.bp_address_u.ip_addr.lh,
93 255 & res.router_address.bp_address_u.ip_addr.impno);
94 if (dolog) syslog(LOG_NOTICE,
95 "Returning %s %s %d.%d.%d.%d\n",
98 255 & res.router_address.bp_address_u.ip_addr.net,
99 255 & res.router_address.bp_address_u.ip_addr.host,
100 255 & res.router_address.bp_address_u.ip_addr.lh,
101 255 & res.router_address.bp_address_u.ip_addr.impno);
106 if (debug) warnx("whoami failed");
107 if (dolog) syslog(LOG_NOTICE,"whoami failed\n");
113 bootparamproc_getfile_1_svc(getfile, req)
114 bp_getfile_arg *getfile;
118 static bp_getfile_res res;
121 warnx("getfile got question for \"%s\" and file \"%s\"",
122 getfile->client_name, getfile->file_id);
125 syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n",
126 getfile->client_name, getfile->file_id);
129 he = gethostbyname(getfile->client_name);
130 if (! he ) goto failed;
132 strncpy(askname, he->h_name, sizeof(askname));
133 askname[sizeof(askname)-1] = 0;
135 if (getthefile(askname, getfile->file_id,buffer,sizeof(buffer))) {
136 if ( (where = strchr(buffer,':')) ) {
137 /* buffer is re-written to contain the name of the info of file */
138 strncpy(hostname, buffer, where - buffer);
139 hostname[where - buffer] = '\0';
142 he = gethostbyname(hostname);
143 if ( !he ) goto failed;
144 bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
145 res.server_name = hostname;
146 res.server_path = path;
147 res.server_address.address_type = IP_ADDR_TYPE;
149 else { /* special for dump, answer with null strings */
150 if (!strcmp(getfile->file_id, "dump")) {
151 res.server_name = "";
152 res.server_path = "";
153 res.server_address.address_type = IP_ADDR_TYPE;
154 bzero(&res.server_address.bp_address_u.ip_addr,4);
158 fprintf(stderr, "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);
165 syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n",
166 res.server_name, res.server_path,
167 255 & res.server_address.bp_address_u.ip_addr.net,
168 255 & res.server_address.bp_address_u.ip_addr.host,
169 255 & res.server_address.bp_address_u.ip_addr.lh,
170 255 & res.server_address.bp_address_u.ip_addr.impno);
174 if (debug) warnx("getfile failed for %s", getfile->client_name);
175 if (dolog) syslog(LOG_NOTICE,
176 "getfile failed for %s\n", getfile->client_name);
180 /* getthefile return 1 and fills the buffer with the information
181 of the file, e g "host:/export/root/client" if it can be found.
182 If the host is in the database, but the file is not, the buffer
183 will be empty. (This makes it possible to give the special
184 empty answer for the file "dump") */
187 getthefile(askname,fileid,buffer,blen)
189 char *fileid, *buffer;
197 static char *yp_domain;
200 int ch, pch, fid_len, res = 0;
203 _Static_assert(INFOLEN >= MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3,
204 "INFOLEN isn't large enough");
205 char info[INFOLEN + 1];
207 bpf = fopen(bootpfile, "r");
209 errx(1, "no %s", bootpfile);
211 /* XXX see comment below */
212 while ( fscanf(bpf, "%255s", hostname) > 0 && !match ) {
213 if ( *hostname != '#' ) { /* comment */
214 if ( ! strcmp(hostname, askname) ) {
217 he = gethostbyname(hostname);
218 if (he && !strcmp(he->h_name, askname)) match = 1;
221 if (*hostname == '+' ) { /* NIS */
223 if (yp_get_default_domain(&yp_domain)) {
224 if (debug) warn("NIS");
227 if (yp_match(yp_domain, "bootparams", askname, strlen(askname),
228 &result, &resultlen))
230 if (strstr(result, fileid) == NULL) {
233 snprintf(buffer, blen,
234 "%s",strchr(strstr(result,fileid), '=') + 1);
235 if (strchr(buffer, ' ') != NULL)
236 *(char *)(strchr(buffer, ' ')) = '\0';
239 warnx("could not close %s", bootpfile);
242 return(0); /* ENOTSUP */
245 /* skip to next entry */
247 pch = ch = getc(bpf);
248 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
249 pch = ch; ch = getc(bpf);
253 /* if match is true we read the rest of the line to get the
257 fid_len = strlen(fileid);
258 #define AS_FORMAT(d) "%" #d "s"
259 #define REXPAND(d) AS_FORMAT(d) /* Force another preprocessor expansion */
260 while ( ! res && (fscanf(bpf, REXPAND(INFOLEN), info)) > 0) {
261 ch = getc(bpf); /* and a character */
262 if ( *info != '#' ) { /* Comment ? */
263 if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') {
264 where = info + fid_len + 1;
265 if ( isprint( *where )) {
266 strcpy(buffer, where); /* found file */
270 while (isspace(ch) && ch != '\n') ch = getc(bpf);
271 /* read to end of line */
272 if ( ch == '\n' ) { /* didn't find it */
273 res = -1; break; /* but host is there */
275 if ( ch == '\\' ) { /* more info */
276 ch = getc(bpf); /* maybe on next line */
277 if (ch == '\n') continue; /* read it in next loop */
278 ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */
279 } else ungetc(ch, bpf); /* but who know what a `\` is */
281 } else break; /* a commented rest-of-line */
284 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
285 if ( res == -1) buffer[0] = '\0'; /* host found, file not */
289 /* checkhost puts the hostname found in the database file in
290 the hostname-variable and returns 1, if askname is a valid
291 name for a host in the database */
294 checkhost(askname, hostname, len)
305 static char *yp_domain;
308 /* struct hostent *cmp_he;*/
310 bpf = fopen(bootpfile, "r");
312 errx(1, "no %s", bootpfile);
314 /* XXX there is no way in ISO C to specify the maximal length for a
315 conversion in a variable way */
316 while ( fscanf(bpf, "%254s", hostname) > 0 ) {
317 if ( *hostname != '#' ) { /* comment */
318 if ( ! strcmp(hostname, askname) ) {
319 /* return true for match of hostname */
323 /* check the alias list */
325 he = gethostbyname(hostname);
326 if (he && !strcmp(askname, he->h_name)) {
332 if (*hostname == '+' ) { /* NIS */
334 if (yp_get_default_domain(&yp_domain)) {
335 if (debug) warn("NIS");
338 if (!yp_match(yp_domain, "bootparams", askname, strlen(askname),
339 &result, &resultlen)) {
340 /* return true for match of hostname */
342 he = gethostbyname(askname);
343 if (he && !strcmp(askname, he->h_name)) {
345 snprintf(hostname, len, "%s", he->h_name);
349 warnx("could not close %s", bootpfile);
352 return(0); /* ENOTSUP */
355 /* skip to next entry */
356 pch = ch = getc(bpf);
357 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
358 pch = ch; ch = getc(bpf);
361 if (fclose(bpf)) { warnx("could not close %s", bootpfile); }