Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /*- |
2 | * Copyright (c) 1986, 1990 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #ifndef lint | |
35 | static char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91"; | |
36 | #endif /* not lint */ | |
37 | ||
38 | #include <sys/param.h> | |
39 | #include <sys/socket.h> | |
40 | #include <sys/time.h> | |
41 | #include <sys/stat.h> | |
42 | #include <netinet/in.h> | |
43 | #include <arpa/nameser.h> | |
44 | #include <syslog.h> | |
45 | #include <signal.h> | |
46 | #include <resolv.h> | |
47 | #include <stdio.h> | |
48 | #include <errno.h> | |
49 | #include <ctype.h> | |
50 | #include <string.h> | |
51 | #undef nsaddr | |
52 | #include "pathnames.h" | |
53 | #include "ns.h" | |
54 | #include "db.h" | |
55 | ||
56 | struct zoneinfo *zones; /* zone information */ | |
57 | int nzones; /* number of zones in use */ | |
58 | int forward_only = 0; /* run only as a slave */ | |
59 | char *cache_file; | |
60 | char *localdomain; /* "default" for non-dotted names */ | |
61 | int maint_interval = 15*60; /* minimum ns_maint() interval */ | |
62 | ||
63 | extern int lineno; | |
64 | ||
65 | ||
66 | /* | |
67 | * Read boot file for configuration info. | |
68 | */ | |
69 | ||
70 | ns_init(bootfile) | |
71 | char *bootfile; | |
72 | { | |
73 | register struct zoneinfo *zp; | |
74 | struct zoneinfo *find_zone(); | |
75 | char buf[BUFSIZ], obuf[BUFSIZ], *source; | |
76 | extern char *calloc(); | |
77 | FILE *fp; | |
78 | int type; | |
79 | extern int needmaint; | |
80 | struct stat f_time; | |
81 | static int loads = 0; /* number of times loaded */ | |
82 | static int tmpnum = 0; /* unique number for tmp zone files */ | |
83 | #ifdef ALLOW_UPDATES | |
84 | char *cp, *flag; | |
85 | #endif | |
86 | ||
87 | #ifdef DEBUG | |
88 | if (debug) | |
89 | fprintf(ddt,"\nns_init(%s)\n", bootfile); | |
90 | #endif | |
91 | gettime(&tt); | |
92 | ||
93 | if ((fp = fopen(bootfile, "r")) == NULL) { | |
94 | syslog(LOG_ERR, "%s: %m", bootfile); | |
95 | exit(1); | |
96 | } | |
97 | lineno = 0; | |
98 | if (loads == 0) { | |
99 | if ((zones = | |
100 | (struct zoneinfo *)calloc(64, sizeof(struct zoneinfo))) | |
101 | == NULL) { | |
102 | syslog(LOG_ERR, | |
103 | "Not enough memory to allocate initial zones array"); | |
104 | exit(1); | |
105 | } | |
106 | nzones = 1; /* zone zero is cache data */ | |
107 | /* allocate cache hash table, formerly the root hash table. */ | |
108 | hashtab = savehash((struct hashbuf *)NULL); | |
109 | ||
110 | /* allocate root-hints/file-cache hash table */ | |
111 | fcachetab = savehash((struct hashbuf *)NULL); | |
112 | /* init zone data */ | |
113 | zones[0].z_type = Z_CACHE; | |
114 | } else { | |
115 | /* Mark previous zones as not yet found in boot file. */ | |
116 | for (zp = &zones[1]; zp < &zones[nzones]; zp++) | |
117 | zp->z_state &= ~Z_FOUND; | |
118 | if (localdomain) | |
119 | free(localdomain); | |
120 | localdomain = NULL; | |
121 | free_forwarders(); | |
122 | forward_only = 0; | |
123 | } | |
124 | ||
125 | #ifdef DEBUG | |
126 | if (debug >= 3) { | |
127 | fprintf(ddt,"\n content of zones before loading \n"); | |
128 | content_zone(nzones - 1); | |
129 | } | |
130 | #endif | |
131 | while (!feof(fp) && !ferror(fp)) { | |
132 | if (!getword(buf, sizeof(buf), fp)) | |
133 | continue; | |
134 | /* read named.boot keyword and process args */ | |
135 | if (strcasecmp(buf, "directory") == 0) { | |
136 | (void) getword(buf, sizeof(buf), fp); | |
137 | if (chdir(buf) < 0) { | |
138 | syslog(LOG_CRIT, "directory %s: %m\n", | |
139 | buf); | |
140 | exit(1); | |
141 | } | |
142 | continue; | |
143 | } else if (strcasecmp(buf, "sortlist") == 0) { | |
144 | get_sort_list(fp); | |
145 | continue; | |
146 | } else if (strcasecmp(buf, "forwarders") == 0) { | |
147 | get_forwarders(fp); | |
148 | continue; | |
149 | } else if (strcasecmp(buf, "slave") == 0) { | |
150 | forward_only++; | |
151 | endline(fp); | |
152 | continue; | |
153 | } else if (strcasecmp(buf, "domain") == 0) { | |
154 | if (getword(buf, sizeof(buf), fp)) | |
155 | localdomain = savestr(buf); | |
156 | endline(fp); | |
157 | continue; | |
158 | } else if (strcasecmp(buf, "cache") == 0) | |
159 | type = Z_CACHE; | |
160 | else if (strcasecmp(buf, "primary") == 0) | |
161 | type = Z_PRIMARY; | |
162 | else if (strcasecmp(buf, "secondary") == 0) | |
163 | type = Z_SECONDARY; | |
164 | else { | |
165 | syslog(LOG_ERR, "%s: line %d: unknown field '%s'\n", | |
166 | bootfile, lineno, buf); | |
167 | endline(fp); | |
168 | continue; | |
169 | } | |
170 | ||
171 | /* | |
172 | * read zone origin | |
173 | */ | |
174 | if (!getword(obuf, sizeof(obuf), fp)) { | |
175 | syslog(LOG_ERR, "%s: line %d: missing origin\n", | |
176 | bootfile, lineno); | |
177 | continue; | |
178 | } | |
179 | #ifdef DEBUG | |
180 | if (debug) | |
181 | fprintf(ddt, "zone origin %s", obuf); | |
182 | #endif | |
183 | if (obuf[0] == '.' && obuf[1] == '\0') | |
184 | obuf[0] = '\0'; | |
185 | /* | |
186 | * read source file or host address | |
187 | */ | |
188 | if (!getword(buf, sizeof(buf), fp)) { | |
189 | syslog(LOG_ERR, | |
190 | "%s: line %d: missing source or addr\n", | |
191 | bootfile, lineno); | |
192 | continue; | |
193 | } | |
194 | ||
195 | /* check for previous instance of this zone (reload) */ | |
196 | if ((zp = find_zone(obuf, type)) == 0) { | |
197 | if (type == Z_CACHE) { | |
198 | zp = &zones[0]; | |
199 | zp->z_origin = ""; | |
200 | goto gotzone; | |
201 | } | |
202 | for (zp = &zones[1]; zp < &zones[nzones]; zp++) | |
203 | if (zp->z_type == 0) | |
204 | goto gotzone; | |
205 | /* | |
206 | * this code assume that nzones never decreases | |
207 | */ | |
208 | if (nzones % 64 == 0) { | |
209 | #ifdef DEBUG | |
210 | if (debug > 1) | |
211 | fprintf(ddt, "Reallocating zones structure\n"); | |
212 | #endif DEBUG | |
213 | /* | |
214 | * Realloc() not used since it might damage zones | |
215 | * if an error occurs | |
216 | */ | |
217 | if ((zp = (struct zoneinfo *) | |
218 | malloc((64 + nzones) * sizeof(struct zoneinfo))) | |
219 | == NULL) { | |
220 | syslog(LOG_ERR, "no memory for more zones"); | |
221 | #ifdef DEBUG | |
222 | if (debug) | |
223 | fprintf(ddt, | |
224 | "Out of memory for new zones\n"); | |
225 | #endif DEBUG | |
226 | endline(fp); | |
227 | continue; | |
228 | } | |
229 | bcopy((char *)zones, (char *)zp, | |
230 | nzones * sizeof(struct zoneinfo)); | |
231 | bzero((char *)&zp[nzones], | |
232 | 64 * sizeof(struct zoneinfo)); | |
233 | free(zones); | |
234 | zones = zp; | |
235 | } | |
236 | zp = &zones[nzones++]; | |
237 | gotzone: | |
238 | zp->z_origin = savestr(obuf); | |
239 | zp->z_type = type; | |
240 | } | |
241 | zp->z_addrcnt = 0; | |
242 | ||
243 | switch (type) { | |
244 | case Z_CACHE: | |
245 | source = savestr(buf); | |
246 | #ifdef DEBUG | |
247 | if (debug) | |
248 | fprintf(ddt,", source = %s\n", source); | |
249 | #endif | |
250 | zp->z_refresh = 0; /* by default, no dumping */ | |
251 | if (getword(buf, sizeof(buf), fp)) { | |
252 | #ifdef notyet | |
253 | zp->z_refresh = atoi(buf); | |
254 | if (zp->z_refresh <= 0) { | |
255 | syslog(LOG_ERR, | |
256 | "%s: line %d: bad refresh time '%s', ignored\n", | |
257 | bootfile, lineno, buf); | |
258 | zp->z_refresh = 0; | |
259 | } else if (cache_file == NULL) | |
260 | cache_file = source; | |
261 | #else | |
262 | syslog(LOG_WARNING, | |
263 | "%s: line %d: cache refresh ignored\n", | |
264 | bootfile, lineno); | |
265 | #endif | |
266 | endline(fp); | |
267 | } | |
268 | /* | |
269 | * If we've loaded this file, and the file has | |
270 | * not been modified and contains no $include, | |
271 | * then there's no need to reload. | |
272 | */ | |
273 | if (zp->z_source && strcmp(source, zp->z_source) == 0 && | |
274 | (zp->z_state & Z_INCLUDE) == 0 && | |
275 | stat(zp->z_source, &f_time) == 0 && | |
276 | zp->z_ftime == f_time.st_mtime) { | |
277 | #ifdef DEBUG | |
278 | if (debug) | |
279 | fprintf(ddt, "cache is up to date\n"); | |
280 | #endif | |
281 | break; /* zone is already up to date */ | |
282 | } | |
283 | ||
284 | /* file has changed, or hasn't been loaded yet */ | |
285 | if (zp->z_source) { | |
286 | free(zp->z_source); | |
287 | remove_zone(fcachetab, 0); | |
288 | } | |
289 | zp->z_source = source; | |
290 | #ifdef DEBUG | |
291 | if (debug) | |
292 | fprintf(ddt, "reloading zone\n"); | |
293 | #endif | |
294 | (void) db_load(zp->z_source, zp->z_origin, zp, 0); | |
295 | break; | |
296 | ||
297 | case Z_PRIMARY: | |
298 | source = savestr(buf); | |
299 | #ifdef ALLOW_UPDATES | |
300 | if (getword(buf, sizeof(buf), fp)) { | |
301 | endline(fp); | |
302 | flag = buf; | |
303 | while (flag) { | |
304 | cp = index(flag, ','); | |
305 | if (cp) | |
306 | *cp++ = 0; | |
307 | if (strcasecmp(flag, "dynamic") == 0) | |
308 | zp->z_state |= Z_DYNAMIC; | |
309 | else if (strcasecmp(flag, "addonly") == 0) | |
310 | zp->z_state |= Z_DYNADDONLY; | |
311 | else { | |
312 | syslog(LOG_ERR, | |
313 | "%s: line %d: bad flag '%s'\n", | |
314 | bootfile, lineno, flag); | |
315 | } | |
316 | flag = cp; | |
317 | } | |
318 | } | |
319 | #else ALLOW_UPDATES | |
320 | endline(fp); | |
321 | #endif | |
322 | ||
323 | #ifdef DEBUG | |
324 | if (debug) | |
325 | fprintf(ddt,", source = %s\n", source); | |
326 | #endif | |
327 | /* | |
328 | * If we've loaded this file, and the file has | |
329 | * not been modified and contains no $include, | |
330 | * then there's no need to reload. | |
331 | */ | |
332 | if (zp->z_source && strcmp(source, zp->z_source) == 0 && | |
333 | (zp->z_state & Z_INCLUDE) == 0 && | |
334 | stat(zp->z_source, &f_time) == 0 && | |
335 | zp->z_ftime == f_time.st_mtime) { | |
336 | #ifdef DEBUG | |
337 | if (debug) | |
338 | fprintf(ddt, "zone is up to date\n"); | |
339 | #endif | |
340 | break; /* zone is already up to date */ | |
341 | } | |
342 | if (zp->z_source) { | |
343 | free(zp->z_source); | |
344 | remove_zone(hashtab, zp - zones); | |
345 | } | |
346 | zp->z_source = source; | |
347 | zp->z_auth = 0; | |
348 | #ifdef DEBUG | |
349 | if (debug) | |
350 | fprintf(ddt, "reloading zone\n"); | |
351 | #endif | |
352 | if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0) | |
353 | zp->z_auth = 1; | |
354 | #ifdef ALLOW_UPDATES | |
355 | /* Guarantee calls to ns_maint() */ | |
356 | zp->z_refresh = maint_interval; | |
357 | #else ALLOW_UPDATES | |
358 | zp->z_refresh = 0; /* no maintenance needed */ | |
359 | zp->z_time = 0; | |
360 | #endif ALLOW_UPDATES | |
361 | break; | |
362 | ||
363 | case Z_SECONDARY: | |
364 | source = 0; | |
365 | #ifdef DEBUG | |
366 | if (debug) | |
367 | fprintf(ddt,"\n\taddrs: "); | |
368 | #endif | |
369 | do { | |
370 | zp->z_addr[zp->z_addrcnt].s_addr = | |
371 | inet_addr(buf); | |
372 | if (zp->z_addr[zp->z_addrcnt].s_addr == | |
373 | (u_long)-1) { | |
374 | source = savestr(buf); | |
375 | endline(fp); | |
376 | break; | |
377 | } | |
378 | #ifdef DEBUG | |
379 | if (debug) | |
380 | fprintf(ddt,"%s, ",buf); | |
381 | #endif | |
382 | if (++zp->z_addrcnt > NSMAX - 1) { | |
383 | zp->z_addrcnt = NSMAX - 1; | |
384 | #ifdef DEBUG | |
385 | if (debug) | |
386 | fprintf(ddt, | |
387 | "\nns.h NSMAX reached\n"); | |
388 | #endif | |
389 | } | |
390 | } while (getword(buf, sizeof(buf), fp)); | |
391 | #ifdef DEBUG | |
392 | if (debug) | |
393 | fprintf(ddt,"addrcnt = %d\n", zp->z_addrcnt); | |
394 | #endif | |
395 | if (source == 0) { | |
396 | /* | |
397 | * We will always transfer this zone again | |
398 | * after a reload. | |
399 | */ | |
400 | sprintf(buf, "/%s/NsTmp%d", _PATH_TMPDIR, | |
401 | tmpnum++); | |
402 | source = savestr(buf); | |
403 | zp->z_state |= Z_TMP_FILE; | |
404 | } else | |
405 | zp->z_state &= ~Z_TMP_FILE; | |
406 | /* | |
407 | * If we had a backup file name, and it was changed, | |
408 | * free old zone and start over. If we don't have | |
409 | * current zone contents, try again now in case | |
410 | * we have a new server on the list. | |
411 | */ | |
412 | if (zp->z_source && strcmp(source, zp->z_source)) { | |
413 | #ifdef DEBUG | |
414 | if (debug) | |
415 | fprintf(ddt,"backup file changed\n"); | |
416 | #endif | |
417 | free(zp->z_source); | |
418 | zp->z_source = 0; | |
419 | zp->z_auth = 0; | |
420 | zp->z_serial = 0; /* force xfer */ | |
421 | remove_zone(hashtab, zp - zones); | |
422 | } | |
423 | if (zp->z_source) | |
424 | free(source); | |
425 | else | |
426 | zp->z_source = source; | |
427 | if (zp->z_auth == 0) | |
428 | zoneinit(zp); | |
429 | break; | |
430 | ||
431 | } | |
432 | zp->z_state |= Z_FOUND; | |
433 | #ifdef DEBUG | |
434 | if (debug) | |
435 | fprintf(ddt,"zone[%d] type %d: '%s'", | |
436 | zp-zones, type, | |
437 | *(zp->z_origin) == '\0' ? "." : zp->z_origin); | |
438 | #endif | |
439 | if (zp->z_refresh && zp->z_time == 0) | |
440 | zp->z_time = zp->z_refresh + tt.tv_sec; | |
441 | if (zp->z_time <= tt.tv_sec) | |
442 | needmaint = 1; | |
443 | #ifdef DEBUG | |
444 | if (debug) | |
445 | fprintf(ddt, " z_time %d, z_refresh %d\n", | |
446 | zp->z_time, zp->z_refresh); | |
447 | #endif | |
448 | } | |
449 | (void) fclose(fp); | |
450 | /* erase all old zones that were not found */ | |
451 | for (zp = &zones[1]; zp < &zones[nzones]; zp++) | |
452 | if (zp->z_type && (zp->z_state & Z_FOUND) == 0) { | |
453 | remove_zone(hashtab, zp - zones); | |
454 | bzero((char *) zp, sizeof(*zp)); | |
455 | #ifdef DEBUG | |
456 | if(debug >=2) | |
457 | fprintf(ddt,"\n zone no %d was removed \n", zp - zones); | |
458 | #endif | |
459 | } | |
460 | #ifdef DEBUG | |
461 | if(debug >= 2) { | |
462 | fprintf(ddt,"\n content of zones after loading \n"); | |
463 | content_zone(nzones-1); | |
464 | } | |
465 | #endif | |
466 | ||
467 | /* | |
468 | * Schedule calls to ns_maint(). | |
469 | */ | |
470 | if (needmaint == 0) | |
471 | sched_maint(); | |
472 | #ifdef DEBUG | |
473 | if (debug) | |
474 | fprintf(ddt,"exit ns_init()%s\n", needmaint ? | |
475 | ", need maintenance immediately" : ""); | |
476 | #endif | |
477 | loads++; | |
478 | } | |
479 | ||
480 | zoneinit(zp) | |
481 | register struct zoneinfo *zp; | |
482 | { | |
483 | extern int needmaint; | |
484 | struct stat sb; | |
485 | ||
486 | /* | |
487 | * Try to load zone from backup file, | |
488 | * if one was specified and it exists. | |
489 | * If not, or if the data are out of date, | |
490 | * we will refresh the zone from a primary | |
491 | * immediately. | |
492 | */ | |
493 | if (zp->z_source == NULL) | |
494 | return; | |
495 | if (stat(zp->z_source, &sb) == -1 || | |
496 | db_load(zp->z_source, zp->z_origin, zp, 0) != 0) { | |
497 | /* | |
498 | * Set zone to be refreshed immediately. | |
499 | */ | |
500 | zp->z_refresh = INIT_REFRESH; | |
501 | zp->z_retry = INIT_REFRESH; | |
502 | zp->z_time = tt.tv_sec; | |
503 | needmaint = 1; | |
504 | } else | |
505 | zp->z_auth = 1; | |
506 | } | |
507 | ||
508 | #ifdef ALLOW_UPDATES | |
509 | /* | |
510 | * Look for the authoritative zone with the longest matching RHS of dname | |
511 | * and return its zone # or zero if not found. | |
512 | */ | |
513 | findzone(dname, class) | |
514 | char *dname; | |
515 | int class; | |
516 | { | |
517 | char *dZoneName, *zoneName, *index(); | |
518 | int dZoneNameLen, zoneNameLen; | |
519 | int maxMatchLen = 0; | |
520 | int maxMatchZoneNum = 0; | |
521 | int zoneNum; | |
522 | ||
523 | #ifdef DEBUG | |
524 | if (debug >= 4) | |
525 | fprintf(ddt, "findzone(dname=%s, class=%d)\n", dname, class); | |
526 | if (debug >= 5) { | |
527 | fprintf(ddt, "zone dump:\n"); | |
528 | for (zoneNum = 1; zoneNum < nzones; zoneNum++) | |
529 | printzoneinfo(zoneNum); | |
530 | } | |
531 | #endif DEBUG | |
532 | ||
533 | dZoneName = index(dname, '.'); | |
534 | if (dZoneName == NULL) | |
535 | dZoneName = ""; /* root */ | |
536 | else | |
537 | dZoneName++; /* There is a '.' in dname, so use remainder of | |
538 | string as the zone name */ | |
539 | dZoneNameLen = strlen(dZoneName); | |
540 | for (zoneNum = 1; zoneNum < nzones; zoneNum++) { | |
541 | zoneName = (zones[zoneNum]).z_origin; | |
542 | zoneNameLen = strlen(zoneName); | |
543 | /* The zone name may or may not end with a '.' */ | |
544 | if (zoneName[zoneNameLen - 1] == '.') | |
545 | zoneNameLen--; | |
546 | if (dZoneNameLen != zoneNameLen) | |
547 | continue; | |
548 | #ifdef DEBUG | |
549 | if (debug >= 5) | |
550 | fprintf(ddt, "about to strncasecmp('%s', '%s', %d)\n", | |
551 | dZoneName, zoneName, dZoneNameLen); | |
552 | #endif | |
553 | if (strncasecmp(dZoneName, zoneName, dZoneNameLen) == 0) { | |
554 | #ifdef DEBUG | |
555 | if (debug >= 5) | |
556 | fprintf(ddt, "match\n"); | |
557 | #endif | |
558 | /* | |
559 | * See if this is as long a match as any so far. | |
560 | * Check if "<=" instead of just "<" so that if | |
561 | * root domain (whose name length is 0) matches, | |
562 | * we use it's zone number instead of just 0 | |
563 | */ | |
564 | if (maxMatchLen <= zoneNameLen) { | |
565 | maxMatchZoneNum = zoneNum; | |
566 | maxMatchLen = zoneNameLen; | |
567 | } | |
568 | } | |
569 | #ifdef DEBUG | |
570 | else | |
571 | if (debug >= 5) | |
572 | fprintf(ddt, "no match\n"); | |
573 | #endif | |
574 | } | |
575 | #ifdef DEBUG | |
576 | if (debug >= 4) | |
577 | fprintf(ddt, "findzone: returning %d\n", maxMatchZoneNum); | |
578 | #endif DEBUG | |
579 | return (maxMatchZoneNum); | |
580 | } | |
581 | #endif ALLOW_UPDATES | |
582 | ||
583 | soa_zinfo(zp, cp, eom) | |
584 | register struct zoneinfo *zp; | |
585 | register u_char *cp; | |
586 | u_char *eom; | |
587 | { | |
588 | cp += 3 * sizeof(u_short); | |
589 | cp += sizeof(u_long); | |
590 | cp += dn_skipname(cp, eom); | |
591 | cp += dn_skipname(cp, eom); | |
592 | GETLONG(zp->z_serial, cp); | |
593 | GETLONG(zp->z_refresh, cp); | |
594 | gettime(&tt); | |
595 | zp->z_time = tt.tv_sec + zp->z_refresh; | |
596 | GETLONG(zp->z_retry, cp); | |
597 | GETLONG(zp->z_expire, cp); | |
598 | GETLONG(zp->z_minimum, cp); | |
599 | } | |
600 | ||
601 | get_forwarders(fp) | |
602 | FILE *fp; | |
603 | { | |
604 | char buf[BUFSIZ]; | |
605 | register struct fwdinfo *fip = NULL, *ftp = NULL; | |
606 | extern struct sockaddr_in nsaddr; | |
607 | extern struct fwdinfo *fwdtab; | |
608 | ||
609 | #ifdef DEBUG | |
610 | if (debug) | |
611 | fprintf(ddt,"forwarders "); | |
612 | #endif | |
613 | ||
614 | /* on mulitple forwarder lines, move to end of the list */ | |
615 | if (fwdtab != NULL) | |
616 | for (fip = fwdtab; fip->next != NULL; fip = fip->next) | |
617 | ; | |
618 | ||
619 | while (getword(buf, sizeof(buf), fp)) { | |
620 | if (strlen(buf) == 0) | |
621 | break; | |
622 | #ifdef DEBUG | |
623 | if (debug) | |
624 | fprintf(ddt," %s",buf); | |
625 | #endif | |
626 | if (ftp == NULL) | |
627 | ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo)); | |
628 | if (isdigit(buf[0]) && | |
629 | (ftp->fwdaddr.sin_addr.s_addr = inet_addr(buf)) != | |
630 | (u_long)-1) { | |
631 | ftp->fwdaddr.sin_port = nsaddr.sin_port; | |
632 | ftp->fwdaddr.sin_family = AF_INET; | |
633 | } else { | |
634 | syslog(LOG_ERR, "'%s' (ignored, NOT dotted quad)", buf); | |
635 | #ifdef DEBUG | |
636 | if (debug) | |
637 | fprintf(ddt," (ignored, NOT dotted quad)"); | |
638 | #endif | |
639 | continue; | |
640 | } | |
641 | ftp->next = NULL; | |
642 | if (fwdtab == NULL) | |
643 | fwdtab = ftp; /* First time only */ | |
644 | else | |
645 | fip->next = ftp; | |
646 | fip = ftp; | |
647 | ftp = NULL; | |
648 | } | |
649 | if (ftp) | |
650 | free((char *)ftp); | |
651 | ||
652 | #ifdef DEBUG | |
653 | if (debug) | |
654 | fprintf(ddt,"\n"); | |
655 | if (debug > 2) | |
656 | for (ftp = fwdtab; ftp != NULL; ftp = ftp->next) | |
657 | fprintf(ddt,"ftp x%x %s next x%x\n", ftp, | |
658 | inet_ntoa(ftp->fwdaddr.sin_addr), ftp->next); | |
659 | #endif | |
660 | } | |
661 | ||
662 | free_forwarders() | |
663 | { | |
664 | extern struct fwdinfo *fwdtab; | |
665 | register struct fwdinfo *ftp, *fnext; | |
666 | ||
667 | for (ftp = fwdtab; ftp != NULL; ftp = fnext) { | |
668 | fnext = ftp->next; | |
669 | free((char *)ftp); | |
670 | } | |
671 | fwdtab = NULL; | |
672 | } | |
673 | ||
674 | struct zoneinfo * | |
675 | find_zone(name, type) | |
676 | char *name; | |
677 | int type; | |
678 | { | |
679 | register struct zoneinfo *zp; | |
680 | ||
681 | for (zp = &zones[1]; zp < &zones[nzones]; zp++) | |
682 | if (zp->z_type == type && strcasecmp(name, zp->z_origin) == 0) { | |
683 | #ifdef DEBUG | |
684 | if (debug > 1) | |
685 | fprintf(ddt, ", old zone (%d)", zp - zones); | |
686 | #endif | |
687 | return (zp); | |
688 | } | |
689 | #ifdef DEBUG | |
690 | if(debug > 1) | |
691 | fprintf(ddt, ", new zone"); | |
692 | #endif | |
693 | return ((struct zoneinfo *)NULL); | |
694 | } | |
695 | ||
696 | /* prints out the content of zones */ | |
697 | content_zone(end) | |
698 | int end; | |
699 | { | |
700 | int i; | |
701 | for (i = 1; i <= end; i++) | |
702 | printzoneinfo(i); | |
703 | } |