|
|
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: extern "C" char *memset(char*, int, int); ! 11: extern "C" long time(long *); ! 12: extern "C" long in_aton(char *); ! 13: extern "C" char *in_ntoa(long); ! 14: ! 15: #include "dbtypes.h" ! 16: ! 17: #define MINLINE 256 ! 18: ! 19: /* ! 20: * list of information about each open database (up to NDB of them) ! 21: * the system database is always at index 0 ! 22: */ ! 23: ! 24: #define NDB 64 ! 25: #define SYSDB 0 ! 26: ! 27: Db *db[NDB]; ! 28: ! 29: /* ! 30: * predeclared ! 31: */ ! 32: int parseuusys(Db *, int, Tuple *); ! 33: int parseinhost(Db *, int, Tuple *); ! 34: int parseinnet(Db *, int, Tuple *); ! 35: int parsedb(Db *, int, Tuple *); ! 36: void parsefile(Db *, int (*)(Db *, int, Tuple *), char *, Tuple *, char *); ! 37: void clearDb(Db *); ! 38: void releaseDb(Db *); ! 39: int checkfiles(Db *); ! 40: ! 41: /* ! 42: * command table ! 43: */ ! 44: struct cmdtbl { ! 45: int (*p)(Db *, int, Tuple *); ! 46: char *k; ! 47: } cmds[] = { ! 48: { parseuusys, "uusys" }, ! 49: { parseinhost, "inhost" }, ! 50: { parseinnet, "innet" }, ! 51: { parsedb, "include" }, ! 52: { 0, (char *)0 }, ! 53: }; ! 54: ! 55: /* ! 56: * Return a pointer to a loaded database for *uid. If (uid == 0), return a ! 57: * pointer to the system database. If the database is not loaded, return ! 58: * (Db *)0. *Hint provides the array location of the last user database, ! 59: * and is updated for each user database created/found. ! 60: */ ! 61: Db * ! 62: finddb(int *uid, int *hint) ! 63: { ! 64: int uidval; ! 65: int dbindex; ! 66: int hintval = *hint; ! 67: Db *d = 0; ! 68: ! 69: if (uid) { ! 70: uidval = *uid; ! 71: /* ! 72: * See if it's the same db as last time ! 73: */ ! 74: if ((hintval > SYSDB) && (hintval < NDB) && (db[hintval]) && ! 75: (db[hintval]->uid == uidval)) ! 76: d = db[hintval]; ! 77: else ! 78: /* ! 79: * Look for user db ! 80: */ ! 81: for (dbindex = SYSDB + 1; dbindex < NDB; dbindex++) { ! 82: if (db[dbindex]) { ! 83: if (uidval == db[dbindex]->uid) { ! 84: *hint = dbindex; ! 85: d = db[dbindex]; ! 86: break; ! 87: } ! 88: } ! 89: } ! 90: } else ! 91: d = db[SYSDB]; ! 92: ! 93: if (d) ! 94: d->lasttime = time ((long *) 0); ! 95: return d; ! 96: } ! 97: ! 98: /* ! 99: * Load the database in rootdir/filename. If uid == 0, load the database ! 100: * as the system database; otherwise, load the database for user with *uid. ! 101: * Return a pointer to the database loaded. If the database is a user ! 102: * database, update *hint with the array index of the database. ! 103: */ ! 104: Db * ! 105: newdb(int *uid, char *rootdir, char *filename, char *dbname, int *hint) ! 106: { ! 107: int oldindex; ! 108: int dbindex; ! 109: long oldtime; ! 110: int uidval = 0; ! 111: Db *d; ! 112: ! 113: if (uid) { ! 114: /* ! 115: * Find the first free slot or the oldest slot ! 116: */ ! 117: uidval = *uid; ! 118: oldindex = SYSDB + 1; ! 119: if (db[oldindex]) { ! 120: oldtime = db[oldindex]->lasttime; ! 121: for (dbindex = oldindex; dbindex < NDB; dbindex++) { ! 122: if (!db[dbindex]) ! 123: break; ! 124: if (db[dbindex]->lasttime < oldtime) { ! 125: oldindex = dbindex; ! 126: oldtime = db[dbindex]->lasttime; ! 127: } ! 128: } ! 129: } ! 130: if (db[oldindex]) ! 131: releaseDb(db[oldindex]); ! 132: dbindex = oldindex; ! 133: *hint = dbindex; ! 134: } else ! 135: dbindex = SYSDB; ! 136: ! 137: if (!(d = db[dbindex])) { ! 138: db[dbindex] = d = new Db; ! 139: memset((char *)d, 0, sizeof(Db)); ! 140: } ! 141: ! 142: d->uid = uidval; ! 143: d->rootdir = strdup(rootdir); ! 144: d->filename = strdup(filename); ! 145: d->dbname = strdup(dbname); ! 146: d->lasttime = time((long *)0); ! 147: return d; ! 148: } ! 149: ! 150: /* ! 151: * Start parsing with the root of the parse files. Return an ! 152: * ordered list of the entries. ! 153: */ ! 154: void ! 155: parsefiles(Db *d) ! 156: { ! 157: char dbattr[MAXDBNAME+4]; ! 158: ! 159: clearDb(d); ! 160: d->o = new Ordered(12); ! 161: strcpy(dbattr,d->dbname); ! 162: strcat(dbattr,",db"); ! 163: parsefile(d, parsedb, d->filename, (Tuple *)0, dbattr); ! 164: d->origin = lookup("local,origin", d->o); ! 165: logevent("db %s: parsed from %s/%s\n",d->dbname,d->rootdir,d->filename); ! 166: } ! 167: ! 168: /* ! 169: * Release all databases. System database is cleared, so it will be ! 170: * reparsed by main loop. ! 171: */ ! 172: void ! 173: releasedbs() ! 174: { ! 175: int dbindex; ! 176: ! 177: clearDb(db[SYSDB]); ! 178: for (dbindex = SYSDB+1; dbindex < NDB; dbindex++) { ! 179: if (db[dbindex]) { ! 180: releaseDb(db[dbindex]); ! 181: delete db[dbindex]; ! 182: db[dbindex] = 0; ! 183: } ! 184: } ! 185: } ! 186: ! 187: /* ! 188: * Completely release all space occupied by a database ! 189: */ ! 190: void ! 191: releaseDb(Db *db) ! 192: { ! 193: if (db->rootdir) ! 194: free(db->rootdir); ! 195: if (db->filename) ! 196: free(db->filename); ! 197: if (db->dbname) ! 198: free(db->dbname); ! 199: db->rootdir = db->filename = db->dbname = (char *) 0; ! 200: clearDb(db); ! 201: } ! 202: ! 203: /* ! 204: * Clear database data structures to prepare for reparsing the database ! 205: * from the same root db file ! 206: */ ! 207: void ! 208: clearDb(Db *db) ! 209: { ! 210: File *fp, *next; ! 211: ! 212: /* ! 213: * forget about old files ! 214: */ ! 215: for(fp = db->flist; fp; fp = next){ ! 216: if (fp->name) free(fp->name); ! 217: next = fp->next; ! 218: delete fp; ! 219: } ! 220: db->flist = 0; ! 221: ! 222: /* ! 223: * free old tuples ! 224: */ ! 225: freetuplelist(&db->dblist); ! 226: freetuplelist(&db->constlist); ! 227: ! 228: /* ! 229: * Delete the old set ! 230: */ ! 231: if(db->o) ! 232: delete db->o; ! 233: db->o = (Ordered *)0; ! 234: ! 235: /* ! 236: * Delete the origin ! 237: */ ! 238: if (db->origin) ! 239: delete db->origin; ! 240: db->origin = (Set *)0; ! 241: } ! 242: ! 243: /* ! 244: * see if any db files have changed. return non-zero if they have. ! 245: */ ! 246: int ! 247: checkfiles(Db *d) ! 248: { ! 249: struct stat s; ! 250: File *fp; ! 251: ! 252: if(d->flist==0) ! 253: return 1; ! 254: for(fp = d->flist; fp; fp = fp->next){ ! 255: if(stat(fp->name, &s)<0){ ! 256: if(fp->time) { ! 257: logevent("db %s: %s disappeared\n", d->dbname, ! 258: fp->name); ! 259: return 1; ! 260: } ! 261: } else if(fp->time != s.st_mtime) { ! 262: if(fp->time) ! 263: logevent("db %s: %s changed\n", d->dbname, ! 264: fp->name); ! 265: else ! 266: logevent("db %s: %s appeared\n", d->dbname, ! 267: fp->name); ! 268: return 1; ! 269: } ! 270: } ! 271: return 0; ! 272: } ! 273: ! 274: /* ! 275: * relative paths ! 276: */ ! 277: char * ! 278: path(char *cp, char *dp) ! 279: { ! 280: static char path[MAXPATH]; ! 281: ! 282: if(*cp=='/'){ ! 283: return cp; ! 284: } else { ! 285: strcpy(path, dp); ! 286: strcat(path, "/"); ! 287: strcat(path, cp); ! 288: return path; ! 289: } ! 290: } ! 291: ! 292: /* ! 293: * parse a file. `parser' is the routine used to do the parsing. ! 294: * `consttuple' is a tuple of atributes to add to each tuple in the ! 295: * file. `conststring' is a string of attributes to add to each ! 296: * tuple in the file. ! 297: */ ! 298: void ! 299: parsefile( ! 300: Db *d, ! 301: int (*parser)(Db *, int, Tuple *), ! 302: char *file, ! 303: Tuple *consttuple, ! 304: char *conststring ! 305: ) ! 306: { ! 307: int fd; ! 308: Tuple *ctp; ! 309: char filebuf[sizeof(Fbuffer)]; ! 310: struct stat s; ! 311: File *fp; ! 312: char *pp; ! 313: ! 314: if(conststring){ ! 315: ctp = new Tuple(conststring, &d->constlist); ! 316: ctp->cat(consttuple); ! 317: } else ! 318: ctp = consttuple; ! 319: ! 320: /* ! 321: * remember the file as one of the db files ! 322: */ ! 323: pp = path(file, d->rootdir); ! 324: for(fp = d->flist; fp; fp = fp->next) ! 325: if(strcmp(fp->name, pp)==0) ! 326: break; ! 327: if(fp==0){ ! 328: fp = new File; ! 329: fp->name = strdup(pp); ! 330: fp->next = d->flist; ! 331: d->flist = fp; ! 332: } ! 333: ! 334: /* ! 335: * open file and remember it's update time ! 336: */ ! 337: fd = open(pp, 0); ! 338: if(fd<0) { ! 339: fp->time = 0; ! 340: logevent("db %s: can't open %s\n", d->dbname, pp); ! 341: return; ! 342: } ! 343: fstat(fd, &s); ! 344: fp->time = s.st_mtime; ! 345: ! 346: /* ! 347: * run the file through a parser ! 348: */ ! 349: logevent("db %s:parsing %s\n", d->dbname, file); ! 350: Finit(fd, filebuf); ! 351: if((*parser)(d, fd, ctp)<0) { ! 352: logevent("db %s:error parsing %s\n", d->dbname, file); ! 353: return; ! 354: } ! 355: close(fd); ! 356: } ! 357: ! 358: /* ! 359: * Parse a data base file. Anything not starting with a # is a tuple. # lines ! 360: * are of the formats: ! 361: * # xyz - a comment ! 362: * #uusys file attributes - a request to parse a uucp systems file. ! 363: * the attributes are added to each line. ! 364: * #inhost file attributes - a request to parse an internet hosts file. ! 365: * the attributes are added to each line. ! 366: * #innet file attributes - a request to parse an internet networks file. ! 367: * the attributes are added to each line. ! 368: * #include file attributes - a request to parse a file like this one. ! 369: * the attributes are added to each line. ! 370: */ ! 371: parsedb(Db *d, int fd, Tuple *consttuple) ! 372: { ! 373: char *cp; ! 374: char *fields[4]; ! 375: struct cmdtbl *ctp; ! 376: Tuple *t; ! 377: ! 378: while((cp = Frdline(fd))!=(char *)0){ ! 379: while(*cp==' ' || *cp=='\t') ! 380: cp++; ! 381: switch(*cp){ ! 382: case '\0': ! 383: /* ! 384: * a blank line is a comment ! 385: */ ! 386: break; ! 387: case '#': ! 388: /* ! 389: * less than two fields after a # is a comment ! 390: */ ! 391: setfields("\t "); ! 392: if(getmfields(cp+1, fields, 3)<2) ! 393: break; ! 394: ! 395: /* ! 396: * look for includes ! 397: */ ! 398: for(ctp=cmds; ctp->k; ctp++){ ! 399: if(strcmp(fields[0], ctp->k)==0){ ! 400: parsefile(d, ctp->p, fields[1], ! 401: consttuple, fields[2]); ! 402: break; ! 403: } ! 404: } ! 405: ! 406: /* ! 407: * anything else is a comment ! 408: */ ! 409: break; ! 410: default: ! 411: t = new Tuple(cp, d->o, &d->dblist); ! 412: t->cat(consttuple); ! 413: break; ! 414: } ! 415: } ! 416: return 0; ! 417: } ! 418: ! 419: /* ! 420: * parse a hosts file ! 421: */ ! 422: parseinhost(Db *d, int fd, Tuple *consttuple) ! 423: { ! 424: char *line; ! 425: char *fields[16]; ! 426: int n, i, len; ! 427: char attributes[MINLINE]; ! 428: Tuple *t; ! 429: ! 430: while((line=Frdline(fd))!=(char *)0){ ! 431: setfields(" \t"); ! 432: n = getmfields(line, fields, 16); ! 433: if(n < 2 || *fields[0] == '#') ! 434: continue; ! 435: strcpy(attributes, fields[0]); ! 436: strcat(attributes, ",in "); ! 437: len = strlen(attributes); ! 438: for(i=1; i<n; i++){ ! 439: len += strlen(fields[i]) + 6; ! 440: if(len >= MINLINE) ! 441: break; ! 442: strcat(attributes, fields[i]); ! 443: if(strchr(fields[i], '.')!=(char *)0) ! 444: strcat(attributes, ".,dom "); ! 445: else ! 446: strcat(attributes, " "); ! 447: } ! 448: t = new Tuple(attributes, d->o, &d->dblist); ! 449: t->cat(consttuple); ! 450: } ! 451: return 0; ! 452: } ! 453: ! 454: /* ! 455: * parse a networks file ! 456: */ ! 457: parseinnet(Db *d, int fd, Tuple *consttuple) ! 458: { ! 459: char *line; ! 460: char *fields[16]; ! 461: int n, i, len; ! 462: char attributes[MINLINE]; ! 463: Tuple *t; ! 464: ! 465: while((line=Frdline(fd))!=(char *)0){ ! 466: setfields(" \t"); ! 467: n = getmfields(line, fields, 16); ! 468: if(n < 2 || *fields[0] == '#') ! 469: continue; ! 470: strcpy(attributes, fields[1]); ! 471: strcat(attributes, ",in "); ! 472: strcat(attributes, fields[0]); ! 473: strcat(attributes, " "); ! 474: len = strlen(attributes); ! 475: for(i=2; i<n; i++){ ! 476: len += strlen(fields[i]) + 1; ! 477: if(len >= MINLINE) ! 478: break; ! 479: strcat(attributes, fields[i]); ! 480: strcat(attributes, " "); ! 481: } ! 482: t = new Tuple(attributes, d->o, &d->dblist); ! 483: t->cat(consttuple); ! 484: } ! 485: return 0; ! 486: } ! 487: ! 488: /* ! 489: * parse the systems file ! 490: */ ! 491: parseuusys(Db *d, int fd, Tuple *consttuple) ! 492: { ! 493: char attributes[MINLINE]; ! 494: char *line, *cp, *type; ! 495: char *fields[16]; ! 496: int n; ! 497: Tuple *t, *ctp; ! 498: ! 499: static char lastn[32]; ! 500: static char lasta[32]; ! 501: static char *lastt; ! 502: ! 503: strcpy(attributes, "uucp,svc"); ! 504: ctp = new Tuple(attributes, &d->constlist); ! 505: ctp->cat(consttuple); ! 506: while((line=Frdline(fd))!=(char *)0){ ! 507: /* ! 508: * parse a single line ! 509: */ ! 510: setfields(" \t"); ! 511: n = getmfields(line, fields, 16); ! 512: if(n < 2 || *fields[0] == '#') ! 513: continue; ! 514: type = (char *)0; ! 515: if(n>=5) { ! 516: if(strncmp(fields[2], "DK", 2)==0){ ! 517: cp = strchr(fields[4], '.'); ! 518: if(cp!=(char *)0) ! 519: *cp = '\0'; ! 520: type = ",dk"; ! 521: } else if(strncmp(fields[2], "ACU", 3)==0){ ! 522: type = ",tel"; ! 523: } ! 524: } ! 525: if(type==lastt && fstrcmp(lastn, fields[0])==0 ! 526: && fstrcmp(lasta, fields[4])==0) ! 527: continue; ! 528: strcpy(attributes, fields[0]); ! 529: if(type){ ! 530: strcat(attributes, " "); ! 531: strcat(attributes, fields[4]); ! 532: strcat(attributes, type); ! 533: } ! 534: lastt = type; ! 535: strcpy(lastn, fields[0]); ! 536: if(n>=5 && fields[4]) ! 537: strcpy(lasta, fields[4]); ! 538: else ! 539: lasta[0] = '\0'; ! 540: t = new Tuple(attributes, d->o, &d->dblist); ! 541: t->cat(ctp); ! 542: } ! 543: return 0; ! 544: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.