|
|
1.1 root 1: /*
2: * Copyright (c) 1986 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)db_load.c 4.27 (Berkeley) 6/18/88";
20: #endif /* not lint */
21:
22: /*
23: * Load data base from ascii backupfile. Format similar to RFC 883.
24: */
25:
26: #include <sys/param.h>
27: #include <sys/time.h>
28: #include <sys/stat.h>
29: #include <netinet/in.h>
30: #include <stdio.h>
31: #include <syslog.h>
32: #include <ctype.h>
33: #include <netdb.h>
34: #include <arpa/nameser.h>
35: #include "ns.h"
36: #include "db.h"
37:
38: extern char *index();
39: extern int max_cache_ttl;
40:
41: /*
42: * Map class and type names to number
43: */
44: struct map {
45: char token[8];
46: int val;
47: };
48:
49: struct map m_class[] = {
50: "in", C_IN,
51: #ifdef notdef
52: "any", C_ANY, /* any is a QCLASS, not CLASS */
53: #endif
54: "chaos", C_CHAOS,
55: };
56: #define NCLASS (sizeof(m_class)/sizeof(struct map))
57:
58: struct map m_type[] = {
59: "a", T_A,
60: "ns", T_NS,
61: "cname", T_CNAME,
62: "soa", T_SOA,
63: "mb", T_MB,
64: "mg", T_MG,
65: "mr", T_MR,
66: "null", T_NULL,
67: "wks", T_WKS,
68: "ptr", T_PTR,
69: "hinfo", T_HINFO,
70: "minfo", T_MINFO,
71: "mx", T_MX,
72: "uinfo", T_UINFO,
73: "uid", T_UID,
74: "gid", T_GID,
75: #ifdef notdef
76: "any", T_ANY, /* any is a QTYPE, not TYPE */
77: #endif
78: #ifdef ALLOW_T_UNSPEC
79: "unspec", T_UNSPEC,
80: #endif ALLOW_T_UNSPEC
81: };
82: #define NTYPE (sizeof(m_type)/sizeof(struct map))
83:
84: /*
85: * Parser token values
86: */
87: #define CURRENT 1
88: #define DOT 2
89: #define AT 3
90: #define DNAME 4
91: #define INCLUDE 5
92: #define ORIGIN 6
93: #define ERROR 7
94:
95: int lineno; /* current line number */
96:
97: struct valuelist {
98: struct valuelist *next, *prev;
99: char *name;
100: char *proto;
101: short port;
102: } *servicelist, *protolist;
103:
104: /*
105: * Load the database from 'filename'. Origin is appended to all domain
106: * names in the file.
107: */
108: db_load(filename, in_origin, zp)
109: char *filename, *in_origin;
110: struct zoneinfo *zp;
111: {
112: register u_char *cp;
113: register struct map *mp;
114: char domain[MAXDNAME];
115: char origin[MAXDNAME];
116: char tmporigin[MAXDNAME];
117: u_char buf[BUFSIZ];
118: u_char data[MAXDATA];
119: char *op;
120: int c;
121: int class, type, ttl, dbflags, dataflags;
122: struct databuf *dp;
123: FILE *fp;
124: int slineno, i, errs = 0, didinclude = 0;
125: register u_long n;
126: struct stat sb;
127:
128: #ifdef DEBUG
129: if (debug)
130: fprintf(ddt,"db_load(%s, %s, %d)\n",
131: filename, in_origin, zp - zones);
132: #endif
133:
134: (void) strcpy(origin, in_origin);
135: if ((fp = fopen(filename, "r")) == NULL) {
136: if (zp->z_type != Z_SECONDARY)
137: syslog(LOG_ERR, "%s: %m", filename);
138: #ifdef DEBUG
139: if (debug)
140: fprintf(ddt,"db_load: error opening file %s\n", filename);
141: #endif
142: return (-1);
143: }
144: if (zp->z_type == Z_CACHE) {
145: dbflags = DB_NODATA | DB_NOHINTS;
146: dataflags = DB_F_HINT;
147: } else {
148: dbflags = DB_NODATA;
149: dataflags = 0;
150: }
151: gettime(&tt);
152: if (fstat(fileno(fp), &sb) < 0) {
153: syslog(LOG_ERR, "%s: %m", filename);
154: sb.st_mtime = (int)tt.tv_sec;
155: }
156: slineno = lineno;
157: lineno = 1;
158: domain[0] = '\0';
159: class = C_IN;
160: while ((c = gettoken(fp)) != EOF) {
161: switch (c) {
162: case INCLUDE:
163: if (!getword(buf, sizeof(buf), fp)) /* file name */
164: break;
165: if (!getword(tmporigin, sizeof(tmporigin), fp))
166: strcpy(tmporigin, origin);
167: else {
168: makename(tmporigin, origin);
169: endline(fp);
170: }
171: didinclude = 1;
172: errs += db_load(buf, tmporigin, zp);
173: continue;
174:
175: case ORIGIN:
176: (void) strcpy(buf, origin);
177: if (!getword(origin, sizeof(origin), fp))
178: break;
179: #ifdef DEBUG
180: if (debug > 3)
181: fprintf(ddt,"db_load: origin %s, buf %s\n",
182: origin, buf);
183: #endif
184: makename(origin, buf);
185: #ifdef DEBUG
186: if (debug > 3)
187: fprintf(ddt,"db_load: origin now %s\n", origin);
188: #endif
189: continue;
190:
191: case DNAME:
192: if (!getword(domain, sizeof(domain), fp))
193: break;
194: n = strlen(domain) - 1;
195: if (domain[n] == '.')
196: domain[n] = '\0';
197: else if (*origin) {
198: (void) strcat(domain, ".");
199: (void) strcat(domain, origin);
200: }
201: goto gotdomain;
202:
203: case AT:
204: (void) strcpy(domain, origin);
205: goto gotdomain;
206:
207: case DOT:
208: domain[0] = '\0';
209: /* fall thru ... */
210: case CURRENT:
211: gotdomain:
212: if (!getword(buf, sizeof(buf), fp)) {
213: if (c == CURRENT)
214: continue;
215: break;
216: }
217: cp = buf;
218: ttl = 0;
219: if (isdigit(*cp)) {
220: n = 0;
221: do
222: n = n * 10 + (*cp++ - '0');
223: while (isdigit(*cp));
224: if (zp->z_type == Z_CACHE) {
225: /* this allows the cache entry to age */
226: /* while sitting on disk (powered off) */
227: if (n > max_cache_ttl)
228: n = max_cache_ttl;
229: n += sb.st_mtime;
230: }
231: ttl = n;
232: if (!getword(buf, sizeof(buf), fp))
233: break;
234: }
235: for (mp = m_class; mp < m_class+NCLASS; mp++)
236: if (!strcasecmp(buf, mp->token)) {
237: class = mp->val;
238: (void) getword(buf, sizeof(buf), fp);
239: break;
240: }
241: for (mp = m_type; mp < m_type+NTYPE; mp++)
242: if (!strcasecmp(buf, mp->token)) {
243: type = mp->val;
244: goto fndtype;
245: }
246: #ifdef DEBUG
247: if (debug)
248: fprintf(ddt,"Line %d: Unknown type: %s.\n",
249: lineno, buf);
250: #endif
251: errs++;
252: syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",
253: lineno, buf);
254: break;
255: fndtype:
256: #ifdef ALLOW_T_UNSPEC
257: /* Don't do anything here for T_UNSPEC...
258: * read input separately later
259: */
260: if (type != T_UNSPEC) {
261: #endif ALLOW_T_UNSPEC
262: if (!getword(buf, sizeof(buf), fp))
263: break;
264: #ifdef DEBUG
265: if (debug >= 3)
266: fprintf(ddt,
267: "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
268: domain, class, type, ttl, buf);
269: #endif
270: #ifdef ALLOW_T_UNSPEC
271: }
272: #endif ALLOW_T_UNSPEC
273: /*
274: * Convert the ascii data 'buf' to the proper format
275: * based on the type and pack into 'data'.
276: */
277: switch (type) {
278: case T_A:
279: n = ntohl((u_long)inet_addr((char *)buf));
280: cp = data;
281: PUTLONG(n, cp);
282: n = sizeof(u_long);
283: break;
284:
285: case T_HINFO:
286: n = strlen(buf);
287: if (n > 255) {
288: syslog(LOG_WARNING,
289: "%s: line %d: CPU type too long",
290: filename, lineno);
291: n = 255;
292: }
293: data[0] = n;
294: bcopy(buf, (char *)data + 1, (int)n);
295: n++;
296: if (!getword(buf, sizeof(buf), fp))
297: break;
298: i = strlen(buf);
299: if (i > 255) {
300: syslog(LOG_WARNING,
301: "%s: line %d: OS type too long",
302: filename, lineno);
303: i = 255;
304: }
305: data[n] = i;
306: bcopy(buf, data + n + 1, i);
307: n += i + 1;
308: endline(fp);
309: break;
310:
311: case T_SOA:
312: case T_MINFO:
313: (void) strcpy(data, buf);
314: makename(data, origin);
315: cp = data + strlen(data) + 1;
316: if (!getword(cp, sizeof(data) - (cp - data),fp)) {
317: n = cp - data;
318: break;
319: }
320: makename(cp, origin);
321: cp += strlen(cp) + 1;
322: if (type == T_MINFO) {
323: n = cp - data;
324: break;
325: }
326: if (getnonblank(fp) != '(')
327: goto err;
328: zp->z_serial = getnum(fp);
329: n = (u_long) zp->z_serial;
330: PUTLONG(n, cp);
331: zp->z_refresh = getnum(fp);
332: n = (u_long) zp->z_refresh;
333: PUTLONG(n, cp);
334: zp->z_time = sb.st_mtime + zp->z_refresh;
335: zp->z_retry = getnum(fp);
336: n = (u_long) zp->z_retry;
337: PUTLONG(n, cp);
338: zp->z_expire = getnum(fp);
339: n = (u_long) zp->z_expire;
340: PUTLONG (n, cp);
341: zp->z_minimum = getnum(fp);
342: n = (u_long) zp->z_minimum;
343: PUTLONG (n, cp);
344: n = cp - data;
345: if (getnonblank(fp) != ')')
346: goto err;
347: endline(fp);
348: break;
349:
350: case T_UID:
351: case T_GID:
352: n = 0;
353: cp = buf;
354: while (isdigit(*cp))
355: n = n * 10 + (*cp++ - '0');
356: if (cp == buf)
357: goto err;
358: cp = data;
359: PUTLONG(n, cp);
360: n = sizeof(long);
361: break;
362:
363: case T_WKS:
364: /* Address */
365: n = ntohl((u_long)inet_addr((char *)buf));
366: cp = data;
367: PUTLONG(n, cp);
368: *cp = getprotocol(fp, filename);
369: /* Protocol */
370: n = sizeof(u_long) + sizeof(char);
371: /* Services */
372: n = getservices((int)n, data, fp, filename);
373: break;
374:
375: case T_NS:
376: case T_CNAME:
377: case T_MB:
378: case T_MG:
379: case T_MR:
380: case T_PTR:
381: (void) strcpy(data, buf);
382: makename(data, origin);
383: n = strlen(data) + 1;
384: break;
385:
386: case T_UINFO:
387: cp = (u_char *)index(buf, '&');
388: bzero(data, sizeof(data));
389: if ( cp != NULL) {
390: (void) strncpy(data, buf, cp - buf);
391: op = index(domain, '.');
392: if ( op != NULL)
393: (void) strncat(data,
394: domain,op-domain);
395: else
396: (void) strcat(data, domain);
397: (void) strcat(data, ++cp);
398: } else
399: (void) strcpy(data, buf);
400: n = strlen(data) + 1;
401: break;
402: case T_MX:
403: n = 0;
404: cp = buf;
405: while (isdigit(*cp))
406: n = n * 10 + (*cp++ - '0');
407: /* catch bad values */
408: if ((cp == buf) || (n > 64535))
409: goto err;
410:
411: cp = data;
412: PUTSHORT((u_short)n, cp);
413:
414: if (!getword(buf, sizeof(buf), fp))
415: break;
416: (void) strcpy(cp,buf);
417: makename(cp, origin);
418: /* get pointer to place in data */
419: cp += strlen(cp) +1;
420:
421: /* now save length */
422: n = (cp - data);
423: break;
424: #ifdef ALLOW_T_UNSPEC
425: case T_UNSPEC:
426: {
427: int rcode;
428: fgets(buf, sizeof(buf), fp);
429: #ifdef DEBUG
430: if (debug)
431: fprintf(ddt, "loading T_UNSPEC\n");
432: #endif DEBUG
433: if (rcode = atob(buf, strlen(buf), data, MAXDATA, &n)) {
434: if (rcode == CONV_OVERFLOW) {
435: #ifdef DEBUG
436: if (debug)
437: fprintf(ddt,
438: "Load T_UNSPEC: input buffer overflow\n");
439: #endif DEBUG
440: errs++;
441: syslog(LOG_ERR,
442: "Load T_UNSPEC: input buffer overflow");
443: } else {
444: #ifdef DEBUG
445: if (debug)
446: fprintf(ddt,
447: "Load T_UNSPEC: Data in bad atob format\n");
448: #endif DEBUG
449: errs++;
450: syslog(LOG_ERR,
451: "Load T_UNSPEC: Data in bad atob format");
452: }
453: }
454: }
455: break;
456: #endif ALLOW_T_UNSPEC
457:
458: default:
459: goto err;
460: }
461: dp = savedata(class, type, (u_long)ttl, data, (int)n);
462: dp->d_zone = zp - zones;
463: dp->d_flags = dataflags;
464: if ((c = db_update(domain, dp, dp, dbflags,
465: (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {
466: #ifdef DEBUG
467: if (debug && (c != DATAEXISTS))
468: fprintf(ddt,"update failed\n");
469: #endif
470: }
471: continue;
472:
473: case ERROR:
474: break;
475: }
476: err:
477: errs++;
478: syslog(LOG_ERR, "%s: line %d: database format error (%s)",
479: filename, lineno, buf);
480: #ifdef DEBUG
481: if (debug)
482: fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",
483: filename, lineno, buf, n);
484: #endif
485: while ((c = getc(fp)) != EOF && c != '\n')
486: ;
487: if (c == '\n')
488: lineno++;
489: }
490: (void) fclose(fp);
491: if (didinclude)
492: zp->z_ftime = 0;
493: else
494: zp->z_ftime = sb.st_mtime;
495: zp->z_lastupdate = sb.st_mtime;
496: lineno = slineno;
497: return (errs);
498: }
499:
500: int gettoken(fp)
501: register FILE *fp;
502: {
503: register int c;
504: char op[32];
505:
506: for (;;) {
507: c = getc(fp);
508: top:
509: switch (c) {
510: case EOF:
511: return (EOF);
512:
513: case '$':
514: if (getword(op, sizeof(op), fp)) {
515: if (!strcasecmp("include", op))
516: return (INCLUDE);
517: if (!strcasecmp("origin", op))
518: return (ORIGIN);
519: }
520: #ifdef DEBUG
521: if (debug)
522: fprintf(ddt,"Line %d: Unknown $ option: $%s\n",
523: lineno, op);
524: #endif
525: syslog(LOG_ERR,"Line %d: Unknown $ option: $%s\n",
526: lineno, op);
527: return (ERROR);
528:
529: case ';':
530: while ((c = getc(fp)) != EOF && c != '\n')
531: ;
532: goto top;
533:
534: case ' ':
535: case '\t':
536: return (CURRENT);
537:
538: case '.':
539: return (DOT);
540:
541: case '@':
542: return (AT);
543:
544: case '\n':
545: lineno++;
546: continue;
547:
548: default:
549: (void) ungetc(c, fp);
550: return (DNAME);
551: }
552: }
553: }
554:
555: /*
556: * Get next word, skipping blanks & comments.
557: */
558: getword(buf, size, fp)
559: char *buf;
560: int size;
561: FILE *fp;
562: {
563: register char *cp;
564: register int c;
565:
566: for (cp = buf; (c = getc(fp)) != EOF; ) {
567: if (c == ';') {
568: while ((c = getc(fp)) != EOF && c != '\n')
569: ;
570: c = '\n';
571: }
572: if (c == '\n') {
573: if (cp != buf)
574: ungetc(c, fp);
575: else
576: lineno++;
577: break;
578: }
579: if (isspace(c)) {
580: while (isspace(c = getc(fp)) && c != '\n')
581: ;
582: ungetc(c, fp);
583: if (cp != buf) /* Trailing whitespace */
584: break;
585: continue; /* Leading whitespace */
586: }
587: if (c == '"') {
588: while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
589: if (c == '\\') {
590: if ((c = getc(fp)) == EOF)
591: c = '\\';
592: if (c == '\n')
593: lineno++;
594: }
595: if (cp >= buf+size-1)
596: break;
597: *cp++ = c;
598: }
599: if (c == '\n') {
600: lineno++;
601: break;
602: }
603: continue;
604: }
605: if (c == '\\') {
606: if ((c = getc(fp)) == EOF)
607: c = '\\';
608: if (c == '\n')
609: lineno++;
610: }
611: if (cp >= buf+size-1)
612: break;
613: *cp++ = c;
614: }
615: *cp = '\0';
616: return (cp != buf);
617: }
618:
619: getnum(fp)
620: FILE *fp;
621: {
622: register int c, n;
623: int seendigit = 0;
624: int seendecimal = 0;
625:
626: for (n = 0; (c = getc(fp)) != EOF; ) {
627: if (isspace(c)) {
628: if (c == '\n')
629: lineno++;
630: if (seendigit)
631: break;
632: continue;
633: }
634: if (c == ';') {
635: while ((c = getc(fp)) != EOF && c != '\n')
636: ;
637: if (c == '\n')
638: lineno++;
639: if (seendigit)
640: break;
641: continue;
642: }
643: if (!isdigit(c)) {
644: if (seendecimal || c != '.') {
645: syslog(LOG_ERR, "line %d: expected a number",
646: lineno);
647: #ifdef DEBUG
648: if (debug)
649: fprintf(ddt,"line %d: expected a number",
650: lineno);
651: #endif
652: exit(1);
653: } else {
654: if (!seendigit)
655: n = 1;
656: n = n * 1000 ;
657: seendigit = 1;
658: seendecimal = 1;
659: }
660: continue;
661: }
662: n = n * 10 + (c - '0');
663: seendigit = 1;
664: }
665: return (n);
666: }
667:
668: getnonblank(fp)
669: FILE *fp;
670: {
671: register int c;
672:
673: while ( (c = getc(fp)) != EOF ) {
674: if (isspace(c)) {
675: if (c == '\n')
676: lineno++;
677: continue;
678: }
679: if (c == ';') {
680: while ((c = getc(fp)) != EOF && c != '\n')
681: ;
682: if (c == '\n')
683: lineno++;
684: continue;
685: }
686: return(c);
687: }
688: syslog(LOG_ERR, "line %d: unexpected EOF", lineno);
689: #ifdef DEBUG
690: if (debug)
691: fprintf(ddt, "line %d: unexpected EOF", lineno);
692: #endif
693: return (EOF);
694: }
695:
696: /*
697: * Take name and fix it according to following rules:
698: * "." means root.
699: * "@" means current origin.
700: * "name." means no changes.
701: * "name" means append origin.
702: */
703: makename(name, origin)
704: char *name, *origin;
705: {
706: int n;
707:
708: if (origin[0] == '.')
709: origin++;
710: n = strlen(name);
711: if (n == 1) {
712: if (name[0] == '.') {
713: name[0] = '\0';
714: return;
715: }
716: if (name[0] == '@') {
717: (void) strcpy(name, origin);
718: return;
719: }
720: }
721: if (n > 0) {
722: if (name[n - 1] == '.')
723: name[n - 1] = '\0';
724: else if (origin[0] != '\0') {
725: name[n] = '.';
726: (void) strcpy(name + n + 1, origin);
727: }
728: }
729: }
730:
731: endline(fp)
732: register FILE *fp;
733: {
734: register int c;
735: while (c = getc(fp))
736: if (c == '\n') {
737: (void) ungetc(c,fp);
738: break;
739: } else if (c == EOF)
740: break;
741: }
742:
743: #define MAXPORT 256
744: #define MAXLEN 24
745:
746: getprotocol(fp, src)
747: FILE *fp;
748: char *src;
749: {
750: int k;
751: char b[MAXLEN];
752:
753: (void) getword(b, sizeof(b), fp);
754:
755: k = findservice(b, &protolist);
756: if(k == -1) {
757: (void) sscanf(b,"%d",&k);
758: if(k <= 0)
759: syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
760: src, lineno, b);
761: }
762: return(k);
763: }
764:
765: int
766: getservices(n, data, fp, src)
767: int n;
768: char *data, *src;
769: FILE *fp;
770: {
771: int j, ch;
772: int k;
773: int maxl;
774: int bracket;
775: char b[MAXLEN];
776: char bm[MAXPORT/8];
777:
778: for (j = 0; j < MAXPORT/8; j++)
779: bm[j] = 0;
780: maxl = 0;
781: bracket = 0;
782: while (getword(b, sizeof(b), fp) || bracket) {
783: if (feof(fp) || ferror(fp))
784: break;
785: if (strlen(b) == 0)
786: continue;
787: if ( b[0] == '(') {
788: bracket++;
789: continue;
790: }
791: if ( b[0] == ')') {
792: bracket = 0;
793: while ((ch = getc(fp)) != EOF && ch != '\n')
794: ;
795: if (ch == '\n')
796: lineno++;
797: break;
798: }
799: k = findservice(b, &servicelist);
800: if (k == -1) {
801: (void) sscanf(b,"%d",&k);
802: if (k <= 0) {
803: syslog(LOG_WARNING,
804: "%s: line %d: Unknown service '%s'", src, lineno, b);
805: continue;
806: }
807: }
808: if ((k < MAXPORT) && (k)) {
809: bm[k/8] |= (0x80>>(k%8));
810: if (k > maxl)
811: maxl=k;
812: }
813: else {
814: syslog(LOG_WARNING,
815: "%s: line %d: port no. (%d) too big\n",
816: src, lineno, k);
817: #ifdef DEBUG
818: if (debug)
819: fprintf(ddt,
820: "%s: line %d: port no. (%d) too big\n",
821: src, lineno, k);
822: #endif
823: }
824: }
825: if (bracket)
826: syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
827: src, lineno);
828: maxl = maxl/8+1;
829: bcopy(bm, data+n, maxl);
830: return(maxl+n);
831: }
832:
833: get_sort_list(fp)
834: FILE *fp;
835: {
836: struct netinfo *tp;
837: struct netinfo *ntp = NULL;
838: struct netinfo *ntip = NULL;
839: char buf[BUFSIZ];
840:
841: extern struct netinfo *fnettab;
842:
843: #ifdef DEBUG
844: if (debug)
845: fprintf(ddt,"sortlist ");
846: #endif
847: if (fnettab) {
848: #ifdef DEBUG
849: /* We can only handle the sortlist at startup. see ns_main */
850: if (debug)
851: fprintf(ddt," (reloading, therefore ignored)\n");
852: #endif
853: (void) endline(fp);
854: return;
855: }
856:
857: while (getword(buf, sizeof(buf), fp)) {
858: if (strlen(buf) == 0)
859: break;
860: #ifdef DEBUG
861: if (debug)
862: fprintf(ddt," %s",buf);
863: #endif
864: if (ntp == NULL)
865: ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
866: ntp->my_addr.s_addr = inet_addr(buf);
867: if ( ntp->my_addr.s_addr == (unsigned)-1) {
868: /* resolve name to address - XXX */
869: continue;
870: }
871: ntp->next = NULL;
872: ntp->mask = net_mask(ntp->my_addr);
873: ntp->net = ntp->my_addr.s_addr & ntp->mask;
874:
875: /* Check for duplicates, then add to linked list */
876: for (tp = fnettab; tp != NULL; tp = tp->next) {
877: if ((ntp->mask == tp->mask) &&
878: (ntp->net == tp->net))
879: continue;
880: }
881: if (fnettab == NULL)
882: fnettab = ntp;
883: else
884: ntip->next = ntp;
885: ntip = ntp;
886: ntp = NULL;
887: }
888: if (ntp)
889: free((char *)ntp);
890:
891: #ifdef DEBUG
892: if (debug)
893: fprintf(ddt,"\n");
894: if (debug > 2)
895: for (ntp = fnettab; ntp != NULL; ntp = ntp->next) {
896: fprintf(ddt,"ntp x%x net x%x mask x%x", ntp,
897: ntp->net, ntp->mask);
898: fprintf(ddt," my_addr x%x", ntp->my_addr);
899: fprintf(ddt," %s",inet_ntoa(ntp->my_addr));
900: fprintf(ddt," next x%x\n", ntp->next);
901: }
902: #endif
903: }
904:
905: buildservicelist()
906: {
907: struct servent *sp;
908: struct valuelist *slp;
909:
910: setservent(1);
911: while (sp = getservent()) {
912: slp = (struct valuelist *)malloc(sizeof(struct valuelist));
913: slp->name = savestr(sp->s_name);
914: slp->proto = savestr(sp->s_proto);
915: slp->port = ntohs((u_short)sp->s_port);
916: slp->next = servicelist;
917: slp->prev = NULL;
918: if (servicelist) {
919: servicelist->prev = slp;
920: }
921: servicelist = slp;
922: }
923: endservent();
924: }
925:
926: buildprotolist()
927: {
928: struct protoent *pp;
929: struct valuelist *slp;
930:
931: setprotoent(1);
932: while (pp = getprotoent()) {
933: slp = (struct valuelist *)malloc(sizeof(struct valuelist));
934: slp->name = savestr(pp->p_name);
935: slp->port = pp->p_proto;
936: slp->next = protolist;
937: slp->prev = NULL;
938: if (protolist) {
939: protolist->prev = slp;
940: }
941: protolist = slp;
942: }
943: endprotoent();
944: }
945:
946: findservice(s, list)
947: register char *s;
948: register struct valuelist **list;
949: {
950: register struct valuelist *lp = *list;
951:
952: for (; lp != NULL; lp = lp->next)
953: if (strcasecmp(lp->name, s) == 0) {
954: if (lp != *list) {
955: lp->prev->next = lp->next;
956: if (lp->next)
957: lp->next->prev = lp->prev;
958: (*list)->prev = lp;
959: lp->next = *list;
960: *list = lp;
961: }
962: return(lp->port);
963: }
964: return(-1);
965: }
966:
967: struct servent *
968: cgetservbyport(port, proto)
969: u_short port;
970: char *proto;
971: {
972: register struct valuelist **list = &servicelist;
973: register struct valuelist *lp = *list;
974: static struct servent serv;
975:
976: port = htons(port);
977: for (; lp != NULL; lp = lp->next) {
978: if (port != lp->port)
979: continue;
980: if (strcasecmp(lp->proto, proto) == 0) {
981: if (lp != *list) {
982: lp->prev->next = lp->next;
983: if (lp->next)
984: lp->next->prev = lp->prev;
985: (*list)->prev = lp;
986: lp->next = *list;
987: *list = lp;
988: }
989: serv.s_name = lp->name;
990: serv.s_port = htons((u_short)lp->port);
991: serv.s_proto = lp->proto;
992: return(&serv);
993: }
994: }
995: return(0);
996: }
997:
998: struct protoent *
999: cgetprotobynumber(proto)
1000: register int proto;
1001: {
1002:
1003: register struct valuelist **list = &protolist;
1004: register struct valuelist *lp = *list;
1005: static struct protoent prot;
1006:
1007: for (; lp != NULL; lp = lp->next)
1008: if (lp->port == proto) {
1009: if (lp != *list) {
1010: lp->prev->next = lp->next;
1011: if (lp->next)
1012: lp->next->prev = lp->prev;
1013: (*list)->prev = lp;
1014: lp->next = *list;
1015: *list = lp;
1016: }
1017: prot.p_name = lp->name;
1018: prot.p_proto = lp->port;
1019: return(&prot);
1020: }
1021: return(0);
1022: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.