Annotation of GNUtools/libg++/libio/dbz/dbzmain.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * dbz - use and test dbz in various ways
                      3:  *
                      4:  * -Log-
                      5:  */
                      6: 
                      7: #include <stdio.h>
                      8: #include <sys/types.h>
                      9: #include <sys/stat.h>
                     10: #include <string.h>
                     11: #include <dbz.h>
                     12: 
                     13: #ifdef FUNNYSEEKS
                     14: #include <unistd.h>
                     15: #else
                     16: #define        SEEK_SET        0
                     17: #endif
                     18: 
                     19: #define        STREQ(a, b)     (*(a) == *(b) && strcmp((a), (b)) == 0)
                     20: 
                     21: #ifndef lint
                     22: static char RCSid[] = "$Header: /rel/cvsfiles/devo/libio/dbz/dbzmain.c,v 1.2 1993/10/25 20:02:41 bothner Exp $";
                     23: #endif
                     24: 
                     25: char *progname;
                     26: 
                     27: char *inname = "(no file)";            /* filename for messages etc. */
                     28: long lineno;                           /* line number for messages etc. */
                     29: 
                     30: char *basename;
                     31: char *pagname;
                     32: char *dirname;
                     33: char *str2dup();
                     34: FILE *base;
                     35: 
                     36: int op = 'b';                  /* what to do, default build a new table */
                     37: int baseinput = 1;             /* is the base file also the input? */
                     38: 
                     39: char *from = NULL;             /* old table to use for dbzagain() */
                     40: int omitzero = 0;              /* omit lines tagged with 0 */
                     41: long every = 0;                        /* report every n lines */
                     42: int syncs = 0;                 /* dbzsync() on each report */
                     43: int quick = 0;                 /* quick checking, not too thorough */
                     44: int sweep = 0;                 /* sweep file checking all offsets */
                     45: int useincore = 1;             /* should we use incore facility? */
                     46: long xxx = 0;                  /* debugging variable */
                     47: int printx = 0;                        /* print xxx after all is done */
                     48: int unique = 1;                        /* before store(), check with fetch() */
                     49: int usefresh = 0;              /* use dbzfresh? */
                     50: long siz = 0;                  /* -p size */
                     51: char map = 'C';                        /* -p map */
                     52: long tag = 0;                  /* -p tag mask */
                     53: int exact = 0;                 /* do not run dbzsize(siz) */
                     54: int dbzint = 1;                        /* use new interface? */
                     55: char fs = '\t';                        /* field separator, default tab */
                     56: int unopen = 0;                        /* make base unopenable during dbminit? */
                     57: char *change = NULL;           /* chdir here before dbmclose */
                     58: 
                     59: #define        DEFBUF  1024            /* default line-buffer size */
                     60: int buflen = DEFBUF;           /* line length limit */
                     61: char lbuf[DEFBUF];
                     62: char *line = lbuf;
                     63: char cbuf[DEFBUF];
                     64: char *cmp = cbuf;
                     65: 
                     66: void fail();
                     67: void dofile();
                     68: void runs();
                     69: void dosweep();
                     70: void mkfiles();
                     71: void crfile();
                     72: void doline();
                     73: void process();
                     74: 
                     75: #ifdef HAVERFCIZE
                     76: extern char *rfc822ize();
                     77: #else
                     78: #define        rfc822ize(n)    (n)
                     79: #endif
                     80: 
                     81: extern char *malloc();
                     82: 
                     83: /*
                     84:  - main - parse arguments and handle options
                     85:  */
                     86: main(argc, argv)
                     87: int argc;
                     88: char *argv[];
                     89: {
                     90:        int c;
                     91:        int errflg = 0;
                     92:        extern int optind;
                     93:        extern char *optarg;
                     94:        int doruns = 0;
                     95:        extern long atol();
                     96: 
                     97:        progname = argv[0];
                     98: 
                     99:        while ((c = getopt(argc, argv, "axcmt:l:R0E:SqOiX:Yuf:p:eMUC:d")) != EOF)
                    100:                switch (c) {
                    101:                case 'a':       /* append to existing table */
                    102:                        if (op != 'b')
                    103:                                fail("only one of -a -x -c -m can be given", "");
                    104:                        op = 'a';
                    105:                        baseinput = 0;
                    106:                        break;
                    107:                case 'x':       /* extract from existing table */
                    108:                        if (op != 'b')
                    109:                                fail("only one of -a -x -c -m can be given", "");
                    110:                        op = 'x';
                    111:                        baseinput = 0;
                    112:                        break;
                    113:                case 'c':       /* check existing table */
                    114:                        if (op != 'b')
                    115:                                fail("only one of -a -x -c -m can be given", "");
                    116:                        op = 'c';
                    117:                        break;
                    118:                case 'm':       /* extract missing (complement of -x) */
                    119:                        if (op != 'b')
                    120:                                fail("only one of -a -x -c -m can be given", "");
                    121:                        op = 'm';
                    122:                        baseinput = 0;
                    123:                        break;
                    124:                case 't':       /* set field separator */
                    125:                        if (strlen(optarg) > 1)
                    126:                                fail("only one field separator allowed", "");
                    127:                        fs = *optarg;
                    128:                        break;
                    129:                case 'l':       /* override line-length limit */
                    130:                        buflen = atoi(optarg) + 1;
                    131:                        if (buflen <= 2)
                    132:                                fail("bad -l value `%s'", optarg);
                    133:                        line = malloc(buflen);
                    134:                        cmp = malloc(buflen);
                    135:                        if (line == NULL || cmp == NULL)
                    136:                                fail("cannot allocate %s-byte buffers", optarg);
                    137:                        break;
                    138:                case 'R':       /* print run statistics */
                    139:                        doruns = 1;
                    140:                        break;
                    141:                case '0':       /* omit lines tagged (by fake -t) with 0 */
                    142:                        omitzero = 1;
                    143:                        break;
                    144:                case 'E':       /* report every n items */
                    145:                        every = atol(optarg);
                    146:                        break;
                    147:                case 'S':       /* dbzsync() on each -E report */
                    148:                        syncs = 1;
                    149:                        break;
                    150:                case 'q':       /* quick check or extract */
                    151:                        quick = 1;
                    152:                        break;
                    153:                case 'O':       /* sweep file checking all offsets */
                    154:                        sweep = 1;
                    155:                        break;
                    156:                case 'i':       /* don't use incore */
                    157:                        useincore = 0;
                    158:                        break;
                    159:                case 'X':       /* set xxx */
                    160:                        xxx = atoi(optarg);
                    161:                        break;
                    162:                case 'Y':       /* print xxx afterward */
                    163:                        printx = 1;
                    164:                        break;
                    165:                case 'u':       /* don't check uniqueness */
                    166:                        unique = 0;
                    167:                        break;
                    168:                case 'f':       /* init from existing table's parameters */
                    169:                        from = optarg;
                    170:                        break;
                    171:                case 'p':       /* parameters for dbzfresh */
                    172:                        if (sscanf(optarg, "%ld %1s %lx", &siz, &map, &tag) != 3) {
                    173:                                map = '?';
                    174:                                tag = 0;
                    175:                                if (sscanf(optarg, "%ld", &siz) != 1)
                    176:                                        fail("bad -n value `%s'", optarg);
                    177:                        }
                    178:                        usefresh = 1;
                    179:                        break;
                    180:                case 'e':       /* -p size is exact, don't dbzsize() it */
                    181:                        exact = 1;
                    182:                        break;
                    183:                case 'M':       /* use old dbm interface + rfc822ize */
                    184:                        dbzint = 0;
                    185:                        break;
                    186:                case 'U':       /* make base unopenable during init */
                    187:                        unopen = 1;
                    188:                        break;
                    189:                case 'C':       /* change directories before dbmclose */
                    190:                        change = optarg;
                    191:                        break;
                    192:                case 'd':       /* Debugging. */
                    193:                        if (dbzdebug(1) < 0)
                    194:                                fail("dbz debugging not available", "");
                    195:                        break;
                    196:                case '?':
                    197:                default:
                    198:                        errflg++;
                    199:                        break;
                    200:                }
                    201:        if (errflg || optind >= argc || (optind+1 < argc && baseinput)) {
                    202:                fprintf(stderr, "usage: %s ", progname);
                    203:                fprintf(stderr, "[-a] [-x] [-c] database [file] ...\n");
                    204:                exit(2);
                    205:        }
                    206: 
                    207:        (void) dbzincore(useincore);
                    208:        basename = argv[optind];
                    209:        pagname = str2dup(basename, ".pag");
                    210:        dirname = str2dup(basename, ".dir");
                    211:        mkfiles();
                    212:        optind++;
                    213: 
                    214:        if (baseinput)          /* implies no further arguments */
                    215:                process(base, basename);
                    216:        else if (optind >= argc)
                    217:                process(stdin, "stdin");
                    218:        else
                    219:                for (; optind < argc; optind++)
                    220:                        dofile(argv[optind]);
                    221: 
                    222:        if (change != NULL)
                    223:                (void) chdir(change);
                    224:        if (dbmclose() < 0)
                    225:                fail("dbmclose failed", "");
                    226:        if (doruns)
                    227:                runs(pagname);
                    228:        if (sweep)
                    229:                dosweep(basename, pagname);
                    230:        if (printx)
                    231:                printf("%ld\n", xxx);
                    232: #ifdef DBZ_FINISH
                    233:        DBZ_FINISH;
                    234: #endif
                    235:        exit(0);
                    236: }
                    237: 
                    238: /*
                    239:  - dofile - open a file and invoke process()
                    240:  */
                    241: void
                    242: dofile(name)
                    243: char *name;
                    244: {
                    245:        register FILE *in;
                    246: 
                    247:        if (STREQ(name, "-"))
                    248:                process(stdin, "-");
                    249:        else {
                    250:                in = fopen(name, "r");
                    251:                if (in == NULL)
                    252:                        fail("cannot open `%s'", name);
                    253:                process(in, name);
                    254:                (void) fclose(in);
                    255:        }
                    256: }
                    257: 
                    258: /*
                    259:  - mkfiles - create empty files and open them up
                    260:  */
                    261: void
                    262: mkfiles()
                    263: {
                    264:        if (op == 'b' && !dbzint) {
                    265:                crfile(dirname);
                    266:                crfile(pagname);
                    267:        }
                    268: 
                    269:        base = fopen(basename, (op == 'a') ? "a" : "r");
                    270:        if (base == NULL)
                    271:                fail("cannot open `%s'", basename);
                    272:        if (unopen)
                    273:                (void) chmod(basename, 0);
                    274:        if (from != NULL) {
                    275:                if (dbzagain(basename, from) < 0)
                    276:                        fail("dbzagain(`%s'...) failed", basename);
                    277:        } else if (op == 'b' && dbzint) {
                    278:                if (!exact)
                    279:                        siz = dbzsize(siz);
                    280:                if (dbzfresh(basename, siz, (int)fs, map, tag) < 0)
                    281:                        fail("dbzfresh(`%s'...) failed", basename);
                    282:        } else if (dbminit(basename) < 0)
                    283:                fail("dbminit(`%s') failed", basename);
                    284:        if (unopen)
                    285:                (void) chmod(basename, 0600);   /* hard to restore original */
                    286: }
                    287: 
                    288: /*
                    289:  - crfile - create a file
                    290:  */
                    291: void
                    292: crfile(name)
                    293: char *name;
                    294: {
                    295:        register int f;
                    296: 
                    297:        f = creat(name, 0666);
                    298:        if (f < 0)
                    299:                fail("cannot create `%s'", name);
                    300:        (void) close(f);
                    301: }
                    302: 
                    303: /*
                    304:  - process - process input file
                    305:  */
                    306: void
                    307: process(in, name)
                    308: FILE *in;
                    309: char *name;
                    310: {
                    311:        register off_t place;
                    312: 
                    313:        inname = name;
                    314:        lineno = 0;
                    315: 
                    316:        for (;;) {
                    317:                place = ftell(in);
                    318:                if (fgets(line, buflen, in) == NULL)
                    319:                        return;
                    320:                lineno++;
                    321:                if (every > 0 && lineno%every == 0) {
                    322:                        fprintf(stderr, "%ld\n", lineno);
                    323:                        if (dbzsync() < 0)
                    324:                                fail("dbzsync failed", "");
                    325:                }
                    326:                doline(line, place);
                    327:        }
                    328:        /* NOTREACHED */
                    329: }
                    330: 
                    331: /*
                    332:  - doline - process input line
                    333:  */
                    334: void
                    335: doline(lp, inoffset)
                    336: char *lp;
                    337: off_t inoffset;
                    338: {
                    339:        register char *p;
                    340:        register char pc;
                    341:        datum key, value;
                    342:        off_t place = inoffset;
                    343:        register int shouldfind;
                    344:        register int llen;
                    345:        char keytext[DBZMAXKEY+1];
                    346: 
                    347:        p = NULL;
                    348:        if (fs != '\0')
                    349:                p = strchr(lp, fs);
                    350:        if (p == NULL)
                    351:                p = lp + strlen(lp);
                    352:        if (p > lp && *(p-1) == '\n')
                    353:                p--;
                    354:        if (p - lp > DBZMAXKEY)
                    355:                fail("key of `%.40s...' too long", lp);
                    356:        pc = *p;
                    357:        *p = '\0';
                    358:        (void) strcpy(keytext, lp);
                    359:        *p = pc;
                    360:        key.dptr = (dbzint) ? keytext : rfc822ize(keytext);
                    361:        key.dsize = strlen(keytext)+1;
                    362: 
                    363:        switch (op) {
                    364:        case 'a':
                    365:                place = ftell(base);
                    366:                llen = strlen(lp);
                    367:                if (fwrite(lp, 1, llen, base) != llen)
                    368:                        fail("write error in `%s'", basename);
                    369:                /* FALLTHROUGH */
                    370:        case 'b':
                    371:                if (omitzero && p != NULL && *(p+1) == '0')
                    372:                        return;
                    373:                if (unique) {
                    374:                        value = (dbzint) ? dbzfetch(key) : fetch(key);
                    375:                        if (value.dptr != NULL)
                    376:                                fail("`%.40s...' already present", lp);
                    377:                }
                    378:                value.dptr = (char *)&place;
                    379:                value.dsize = (int)sizeof(off_t);
                    380:                if (((dbzint) ? dbzstore(key, value) : store(key, value)) < 0)
                    381:                        fail("store failed on `%.40s...'", lp);
                    382:                break;
                    383:        case 'c':
                    384:                value = (dbzint) ? dbzfetch(key) : fetch(key);
                    385:                shouldfind = (omitzero && p != NULL && *(p+1) == '0') ? 0 : 1;
                    386:                if (!shouldfind && (value.dptr != NULL || value.dsize != 0))
                    387:                        fail("`%.40s...' found, shouldn't be", lp);
                    388:                if (shouldfind && (value.dptr == NULL ||
                    389:                                        value.dsize != sizeof(off_t)))
                    390:                        fail("can't find `%.40s...'", lp);
                    391:                if (shouldfind && !quick) {
                    392:                        (void) memcpy((char *)&place, value.dptr, sizeof(off_t));
                    393:                        if (place != inoffset)
                    394:                                fail("offset mismatch on `%.40s...'", lp);
                    395:                        if (fseek(base, place, SEEK_SET) == -1)
                    396:                                fail("fseek failed on `%.40s...'", lp);
                    397:                        if (fgets(cmp, buflen, base) == NULL)
                    398:                                fail("can't read line for `%.40s...'", lp);
                    399:                        if (!STREQ(lp, cmp))
                    400:                                fail("compare failed on `%.40s...'", lp);
                    401:                }
                    402:                break;
                    403:        case 'x':
                    404:                value = (dbzint) ? dbzfetch(key) : fetch(key);
                    405:                if (value.dptr != NULL && !quick) {
                    406:                        (void) memcpy((char *)&place, value.dptr, sizeof(off_t));
                    407:                        if (fseek(base, place, SEEK_SET) == -1)
                    408:                                fail("fseek failed on `%.40s...'", lp);
                    409:                        if (fgets(cmp, buflen, base) == NULL)
                    410:                                fail("can't read line for `%.40s...'", lp);
                    411:                        fputs(cmp, stdout);
                    412:                } else if (value.dptr != NULL)
                    413:                        fputs(lp, stdout);
                    414:                break;
                    415:        case 'm':
                    416:                value = (dbzint) ? dbzfetch(key) : fetch(key);
                    417:                if (value.dptr == NULL) {
                    418:                        fputs(keytext, stdout);
                    419:                        putchar('\n');
                    420:                }
                    421:                break;
                    422:        default:
                    423:                fail("unknown operator -- can't happen", "");
                    424:                break;
                    425:        }
                    426: }
                    427: 
                    428: /*
                    429:  - runs - print run statistics
                    430:  */
                    431: void
                    432: runs(file)
                    433: char *file;
                    434: {
                    435:        register FILE *fd;
                    436:        off_t it;
                    437:        register long run;
                    438: 
                    439:        fd = fopen(file, "r");
                    440:        if (fd == NULL)
                    441:                fail("cannot reopen `%s'", file);
                    442:        run = 0;
                    443:        while (fread((char *)&it, sizeof(off_t), 1, fd) == 1) {
                    444:                if (it != 0)
                    445:                        run++;
                    446:                else if (run > 0) {
                    447:                        printf("%ld\n", run);
                    448:                        run = 0;
                    449:                }
                    450:        }
                    451:        (void) fclose(fd);
                    452: }
                    453: 
                    454: /*
                    455:  - dosweep - sweep pag file checking for valid offsets
                    456:  */
                    457: void
                    458: dosweep(fn, pn)
                    459: char *fn;
                    460: char *pn;
                    461: {
                    462:        register FILE *pf;
                    463:        off_t it;
                    464:        char nl;
                    465:        register FILE *hf;
                    466: 
                    467:        hf = fopen(fn, "r");
                    468:        if (hf == NULL)
                    469:                fail("cannot reopen `%s'", fn);
                    470:        pf = fopen(pn, "r");
                    471:        if (pf == NULL)
                    472:                fail("cannot reopen `%s'", pn);
                    473:        while (fread((char *)&it, sizeof(off_t), 1, pf) == 1) {
                    474:                it = (it & ((off_t)0x80000000)) ? (it&~((off_t)0xff000000)) : it;
                    475:                if (it != 0 && it != 1) {       /* 0 empty, 1 known okay */
                    476:                        it--;           /* get rid of bias */
                    477:                        (void) fseek(hf, it-1, SEEK_SET);
                    478:                        nl = getc(hf);
                    479:                        if (nl != '\n')
                    480:                                fprintf(stderr, "offset 0%lo does not point to line\n",
                    481:                                                                (long)it);
                    482:                }
                    483:        }
                    484:        (void) fclose(hf);
                    485:        (void) fclose(pf);
                    486: }
                    487: 
                    488: /*
                    489:  - fail - complain and die
                    490:  */
                    491: void
                    492: fail(s1, s2)
                    493: char *s1;
                    494: char *s2;
                    495: {
                    496:        fprintf(stderr, "%s: (file `%s', line %ld) ", progname, inname, lineno);
                    497:        fprintf(stderr, s1, s2);
                    498:        fprintf(stderr, "\n");
                    499:        exit(1);
                    500: }
                    501: 
                    502: /*
                    503:  - str2dup - concatenate strings and malloc result
                    504:  */
                    505: char *
                    506: str2dup(s1, s2)
                    507: char *s1;
                    508: char *s2;
                    509: {
                    510:        register char *p;
                    511: 
                    512:        p = malloc((size_t)strlen(s1) + strlen(s2) + 1);
                    513:        if (p == NULL)
                    514:                fail("can't allocate space for strings", "");
                    515:        (void) strcpy(p, s1);
                    516:        (void) strcat(p, s2);
                    517:        return(p);
                    518: }

unix.superglobalmegacorp.com

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