|
|
1.1 root 1: #include <fio.h>
2: #include <libc.h>
3: #include <string.h>
4: #include <sysent.h>
5: #include <sys/types.h>
6: #include <sys/stat.h>
7: extern "C" int stat (const char*, struct stat*); /* added by pg so that
8: * this could compile
9: */
10: #include "dbtypes.h"
11:
12: #define MINLINE 256
13:
14: /*
15: * predeclared
16: */
17: int parseuusys(Ordered *, int, Tuple *);
18: int parseinhost(Ordered *, int, Tuple *);
19: int parseinnet(Ordered *, int, Tuple *);
20: int parsedb(Ordered *, int, Tuple *);
21: void parsefile(Ordered *, int (*)(Ordered *, int, Tuple *), char *, Tuple *,
22: char *);
23: int checkfiles();
24:
25: /*
26: * command table
27: */
28: struct cmdtbl {
29: int (*p)(Ordered *, int, Tuple *);
30: char *k;
31: } cmds[] = {
32: { parseuusys, "uusys" },
33: { parseinhost, "inhost" },
34: { parseinnet, "innet" },
35: { parsedb, "include" },
36: { 0, (char *)0 },
37: };
38:
39: /*
40: * list of all constant tuples and all data base tuples
41: */
42: static Tuple *dblist;
43: static Tuple *constlist;
44:
45: /*
46: * list of parsed files and their update times (up to 32 files)
47: */
48: #define NF 32
49: struct File {
50: File *next;
51: char *name;
52: long time;
53: };
54: File *flist;
55:
56: /*
57: * Start parsing with the root of the parse files. Return an
58: * ordered list of the entries.
59: */
60: Ordered *
61: parsefiles(char *root, Ordered *o)
62: {
63: File *fp, *next;
64:
65: /*
66: * First see if any files have changed.
67: */
68: if(checkfiles()==0)
69: return o;
70:
71: /*
72: * forget about old files
73: */
74: for(fp = flist; fp; fp = next){
75: free(fp->name);
76: next = fp->next;
77: delete fp;
78: }
79: flist = 0;
80:
81: /*
82: * free old tuples
83: */
84: freetuplelist(&dblist);
85: freetuplelist(&constlist);
86:
87: /*
88: * create a new ordered set
89: */
90: if(o)
91: delete o;
92: o = new Ordered(12);
93:
94: parsefile(o, parsedb, root, (Tuple *)0, (char *)0);
95: logevent("db parsed\n");
96: return o;
97: }
98:
99: /*
100: * see if any db files have changed. return non-zero if they have.
101: */
102: checkfiles()
103: {
104: struct stat s;
105: File *fp;
106:
107: if(flist==0)
108: return 1;
109: for(fp = flist; fp; fp = fp->next){
110: if(stat(fp->name, &s)<0){
111: if(fp->time) {
112: logevent("%s disappeared\n", fp->name);
113: return 1;
114: }
115: } else if(fp->time != s.st_mtime) {
116: if(fp->time)
117: logevent("%s changed\n", fp->name);
118: else
119: logevent("%s appeared\n", fp->name);
120: return 1;
121: }
122: }
123: return 0;
124: }
125:
126: /*
127: * relative paths
128: */
129: char *
130: path(char *cp, char *dp)
131: {
132: static char path[MAXPATH];
133:
134: if(*cp=='/'){
135: return cp;
136: } else {
137: strcpy(path, dp);
138: strcat(path, "/");
139: strcat(path, cp);
140: return path;
141: }
142: }
143:
144: /*
145: * parse a file. `parser' is the routine used to do the parsing.
146: * `consttuple' is a tuple of atributes to add to each tuple in the
147: * file. `conststring' is a string of attributes to add to each
148: * tuple in the file.
149: */
150: void
151: parsefile(
152: Ordered *o,
153: int (*parser)(Ordered *, int, Tuple *),
154: char *file,
155: Tuple *consttuple,
156: char *conststring
157: )
158: {
159: int fd;
160: Tuple *ctp;
161: char filebuf[sizeof(Fbuffer)];
162: struct stat s;
163: File *fp;
164: char *pp;
165:
166: if(conststring){
167: ctp = new Tuple(conststring, &constlist);
168: ctp->cat(consttuple);
169: } else
170: ctp = consttuple;
171:
172: /*
173: * remember the file as one of the db files
174: */
175: pp = path(file, "/usr/ipc/lib/");
176: for(fp = flist; fp; fp = fp->next)
177: if(strcmp(fp->name, pp)==0)
178: break;
179: if(fp==0){
180: fp = new File;
181: fp->name = strdup(pp);
182: fp->next = flist;
183: flist = fp;
184: }
185:
186: /*
187: * open file and remember it's update time
188: */
189: fd = open(pp, 0);
190: if(fd<0) {
191: fp->time = 0;
192: logevent("can't open %s\n", file);
193: return;
194: }
195: fstat(fd, &s);
196: fp->time = s.st_mtime;
197:
198: /*
199: * run the file through a parser
200: */
201: Finit(fd, filebuf);
202: if((*parser)(o, fd, ctp)<0) {
203: logevent("error parsing %s\n", file);
204: return;
205: }
206: close(fd);
207: }
208:
209: /*
210: * Parse a data base file. Anything not starting with a # is a tuple. # lines
211: * are of the formats:
212: * # xyz - a comment
213: * #uusys file attributes - a request to parse a uucp systems file.
214: * the attributes are added to each line.
215: * #inhost file attributes - a request to parse an internet hosts file.
216: * the attributes are added to each line.
217: * #innet file attributes - a request to parse an internet networks file.
218: * the attributes are added to each line.
219: * #include file attributes - a request to parse a file like this one.
220: * the attributes are added to each line.
221: */
222: parsedb(Ordered *o, int fd, Tuple *consttuple)
223: {
224: char *cp;
225: char *fields[4];
226: struct cmdtbl *ctp;
227: Tuple *t;
228:
229: while((cp = Frdline(fd))!=(char *)0){
230: while(*cp==' ' || *cp=='\t')
231: cp++;
232: switch(*cp){
233: case '\0':
234: /*
235: * a blank line is a comment
236: */
237: break;
238: case '#':
239: /*
240: * less than two fields after a # is a comment
241: */
242: setfields("\t ");
243: if(getmfields(cp+1, fields, 3)<2)
244: break;
245:
246: /*
247: * look for includes
248: */
249: for(ctp=cmds; ctp->k; ctp++){
250: if(strcmp(fields[0], ctp->k)==0){
251: parsefile(o, ctp->p, fields[1],
252: consttuple, fields[2]);
253: break;
254: }
255: }
256:
257: /*
258: * anything else is a comment
259: */
260: break;
261: default:
262: t = new Tuple(cp, o, &dblist);
263: t->cat(consttuple);
264: break;
265: }
266: }
267: return 0;
268: }
269:
270: /*
271: * parse a hosts file
272: */
273: parseinhost(Ordered *o, int fd, Tuple *consttuple)
274: {
275: char *line;
276: char *fields[16];
277: int n, i;
278: char attributes[MINLINE];
279: Tuple *t;
280:
281: while((line=Frdline(fd))!=(char *)0){
282: setfields(" \t");
283: n = getmfields(line, fields, 16);
284: if(n < 2 || *fields[0] == '#')
285: continue;
286: strcpy(attributes, fields[0]);
287: strcat(attributes, ",in ");
288: for(i=1; i<n; i++){
289: strcat(attributes, fields[i]);
290: if(strchr(fields[i], '.')!=(char *)0)
291: strcat(attributes, ".,dom ");
292: else
293: strcat(attributes, " ");
294: }
295: t = new Tuple(attributes, o, &dblist);
296: t->cat(consttuple);
297: }
298: return 0;
299: }
300:
301: /*
302: * parse a networks file
303: */
304: parseinnet(Ordered *o, int fd, Tuple *consttuple)
305: {
306: char *line;
307: char *fields[16];
308: int n, i;
309: char attributes[MINLINE];
310: Tuple *t;
311:
312: while((line=Frdline(fd))!=(char *)0){
313: setfields(" \t");
314: n = getmfields(line, fields, 16);
315: if(n < 2 || *fields[0] == '#')
316: continue;
317: strcpy(attributes, fields[1]);
318: strcat(attributes, ",in ");
319: strcat(attributes, fields[0]);
320: strcat(attributes, " ");
321: for(i=2; i<n; i++){
322: strcat(attributes, fields[i]);
323: strcat(attributes, " ");
324: }
325: t = new Tuple(attributes, o, &dblist);
326: t->cat(consttuple);
327: }
328: return 0;
329: }
330:
331: /*
332: * parse the systems file
333: */
334: parseuusys(Ordered *o, int fd, Tuple *consttuple)
335: {
336: char attributes[MINLINE];
337: char *line, *cp, *type;
338: char *fields[16];
339: int n;
340: Tuple *t, *ctp;
341:
342: static char lastn[32];
343: static char lasta[32];
344: static char *lastt;
345:
346: strcpy(attributes, "uucp,svc");
347: ctp = new Tuple(attributes, &constlist);
348: ctp->cat(consttuple);
349: while((line=Frdline(fd))!=(char *)0){
350: /*
351: * parse a single line
352: */
353: setfields(" \t");
354: n = getmfields(line, fields, 16);
355: if(n < 2 || *fields[0] == '#')
356: continue;
357: type = (char *)0;
358: if(n>=5) {
359: if(strncmp(fields[2], "DK", 2)==0){
360: cp = strchr(fields[4], '.');
361: if(cp!=(char *)0)
362: *cp = '\0';
363: type = ",dk";
364: } else if(strncmp(fields[2], "ACU", 3)==0){
365: type = ",tel";
366: }
367: }
368: if(type==lastt && fstrcmp(lastn, fields[0])==0
369: && fstrcmp(lasta, fields[4])==0)
370: continue;
371: strcpy(attributes, fields[0]);
372: if(type){
373: strcat(attributes, " ");
374: strcat(attributes, fields[4]);
375: strcat(attributes, type);
376: }
377: lastt = type;
378: strcpy(lastn, fields[0]);
379: if(n>=5 && fields[4])
380: strcpy(lasta, fields[4]);
381: else
382: lasta[0] = '\0';
383: t = new Tuple(attributes, o, &dblist);
384: t->cat(ctp);
385: }
386: return 0;
387: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.