|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.