|
|
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.