Annotation of researchv10no/ipc/mgrs/ns/parsefiles.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.