|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include <ingres.h> ! 3: # include <aux.h> ! 4: # include <catalog.h> ! 5: # include <access.h> ! 6: # include <batch.h> ! 7: # include <opsys.h> ! 8: # include <lock.h> ! 9: # include <symbol.h> ! 10: # include <resp.h> ! 11: # include <sys/dir.h> ! 12: # include <sccs.h> ! 13: # include <signal.h> ! 14: # include <setjmp.h> ! 15: ! 16: SCCSID(@(#)restore.c 8.5 1/31/86) ! 17: ! 18: /* ! 19: ** INGRES crash recovery processor ! 20: ** to recover a database you must be the dba or the ingres superuser ! 21: ** RESTORE attempts to complete updates from batch files left in a ! 22: ** database. After finishing all the batch files it calls PURGE. ! 23: */ ! 24: ! 25: # ifndef PURGE ! 26: # ifdef xV7_UNIX ! 27: # define PURGE "purge" ! 28: # else xV7_UNIX ! 29: # define PURGE "/usr/bin/purge" ! 30: # endif xV7_UNIX ! 31: # endif PURGE ! 32: ! 33: /* first file to close on error */ ! 34: # define CLOSEFILES 3 ! 35: ! 36: extern int Status; ! 37: extern char *Usercode; ! 38: char Utemp[2]; ! 39: char *Fileset; ! 40: char Berror; /* batch error */ ! 41: char Error; ! 42: extern char Ask; ! 43: extern char Superuser; ! 44: extern char All; ! 45: extern char Qrymod; ! 46: int Direc = CLOSEFILES - 1; ! 47: extern int Wait_action; ! 48: short tTvect[100]; ! 49: short tTdbu[100]; ! 50: struct resp Resp; ! 51: DESC Btreesec; ! 52: int Btree_fd; ! 53: jmp_buf Jmpbuffer; /* buffer for nonlocal goto's on an error condition */ ! 54: ! 55: ! 56: #ifndef rewinddir ! 57: typedef DIR FILE; ! 58: #endif ! 59: extern DIR *opendir(); ! 60: extern struct direct *readdir(); ! 61: ! 62: main(argc, argv) ! 63: int argc; ! 64: char *argv[]; ! 65: { ! 66: register int fd; ! 67: register int i; ! 68: register char *dbname; ! 69: extern char *Proc_name; ! 70: auto int stat; ! 71: extern (*ExitFn)(); ! 72: extern rubproc(), exit(); ! 73: char *nargv[20]; ! 74: char **avp; ! 75: char **fvp; ! 76: extern char *Flagvect[]; ! 77: extern char *getnxtdb(); ! 78: char *lookucode(); ! 79: ! 80: Proc_name = "RESTORE"; ! 81: ! 82: /* check param list */ ! 83: argv[argc] = NULL; ! 84: # ifdef xTTR1 ! 85: tTrace(argv, 'T', tTvect, 100); ! 86: tTrace(argv, 'Z', tTdbu, 100); ! 87: # endif ! 88: ! 89: initialize(argc, argv); ! 90: ! 91: /* do it to it */ ! 92: ExitFn = rubproc; ! 93: signal(SIGQUIT, exit); ! 94: while (dbname = getnxtdb()) ! 95: { ! 96: Berror = Error = 0; ! 97: ! 98: /* first restart point for this database */ ! 99: setjmp(Jmpbuffer); ! 100: if (Error) /* if set, will cause skip to next database */ ! 101: continue; ! 102: printf("\nRestoring database: %s\t", dbname); ! 103: ! 104: acc_init(); ! 105: printf("owner: %s\n", lookucode(Admin.adhdr.adowner)); ! 106: ! 107: /* set exclusive lock on data base */ ! 108: db_lock(M_EXCL); ! 109: ! 110: restore(); /* recover batch update and modify files */ ! 111: printf("\tRecovery of batch files complete.\n"); ! 112: ! 113: /* ! 114: ** second restart point for this database ! 115: ** the batch files are completed and now the system ! 116: ** relations need checking ! 117: */ ! 118: setjmp(Jmpbuffer); ! 119: if (Error) /* again, may cause skipping to next database */ ! 120: continue; ! 121: printf("\tChecking system relations\n"); ! 122: ! 123: ! 124: /* ! 125: ** check the relation relation ! 126: ** this will mean checking for file existence, ! 127: ** and whether the relstat bits are supported by ! 128: ** the information in the other catalogs. ! 129: */ ! 130: checkrel(); ! 131: ! 132: /* ! 133: ** check the attribute relation ! 134: ** for each tuple in the attribute relation, there must ! 135: ** be a tuple in the relation relation. ! 136: ** the indexes relation doesn't need to be reverse checked ! 137: ** into the relation relation since the order things are ! 138: ** handled else where in the system is in the correct ! 139: ** order. All the other catalogs need to be reverse checked. ! 140: */ ! 141: checkatts(); ! 142: ! 143: /* only check the qrymod catalogs if qrymod is turned on */ ! 144: if (Qrymod) ! 145: { ! 146: /* check the protect relation */ ! 147: checkprotect(); ! 148: ! 149: /* check the integrities relation */ ! 150: checkinteg(); ! 151: ! 152: /* ! 153: ** check the tree relation ! 154: ** must be done last since it depends upon ! 155: ** a state of the system relations provided ! 156: ** by the other check... routines. ! 157: */ ! 158: checktree(); ! 159: } ! 160: ! 161: /* finished, close up the database and go on to the next */ ! 162: closecatalog(TRUE); ! 163: unldb(); ! 164: acc_close(); ! 165: ! 166: /* call PURGE if no errors */ ! 167: if (!Berror && !Error) ! 168: { ! 169: printf("\tCalling purge: "); ! 170: fflush(stdout); ! 171: if ((i = fork()) == -1) ! 172: printf("Can't fork\n"); ! 173: else if (!i) ! 174: { ! 175: avp = nargv; ! 176: *avp++ = "Purge"; ! 177: for (fvp = Flagvect; *fvp != NULL; ) ! 178: *avp++ = *fvp++; ! 179: *avp++ = dbname; ! 180: *avp++ = 0; ! 181: # ifdef xTTR2 ! 182: if (tTf(0, 1)) ! 183: for (avp = nargv, i = 0; *avp != NULL; avp++, i++) ! 184: printf("%d %s\n", i, *avp); ! 185: # endif ! 186: for (i=3; i <= NOFILE; i++) ! 187: close(i); ! 188: execv(ztack(Pathname, "/bin/purge"), nargv); ! 189: # ifdef xV7_UNIX ! 190: execvp(PURGE, nargv); ! 191: # else xV7_UNIX ! 192: execv(PURGE, nargv); ! 193: # endif xV7_UNIX ! 194: printf("Cannot exec %s\n", PURGE); ! 195: exit(-1); ! 196: } ! 197: else ! 198: wait(&stat); ! 199: } ! 200: } ! 201: } ! 202: /* ! 203: ** RESTORE -- find the batch files and process them ! 204: */ ! 205: restore() ! 206: { ! 207: DESC descr; ! 208: register DIR *dirp; ! 209: register struct direct *dp; ! 210: register int i; ! 211: extern char *Fileset; ! 212: extern uperr(), (*ExitFn)(); ! 213: int (*tmpfn)(); ! 214: char *lookucode(); ! 215: char *fname; ! 216: # ifndef rewinddir ! 217: char fnambuf[DIRSIZ+1]; ! 218: # endif ! 219: ! 220: if ( (dirp = opendir(".")) == NULL ) ! 221: syserr("Can't open data base directory"); ! 222: bmove(Usercode, Utemp, UCODE_SZ); ! 223: Batch_recovery = 1; ! 224: tmpfn = ExitFn; ! 225: ExitFn = uperr; ! 226: ! 227: /* restart point */ ! 228: setjmp(Jmpbuffer); ! 229: for ( dp = readdir(dirp) ; dp != NULL ; dp = readdir(dirp) ) ! 230: { ! 231: # ifdef rewinddir ! 232: fname = dp->d_name; ! 233: # else ! 234: strncpy(fnambuf, dp->d_name, DIRSIZ); ! 235: fnamebuf[DIRSIZ] = '\0'; ! 236: fname = fnamebuf; ! 237: # endif ! 238: if ( !strcmp(".",fname) || !strcmp("..",fname) ) ! 239: continue; ! 240: if (bequal("_SYSbatch", fname, 9)) ! 241: { ! 242: Fileset = &fname[9]; ! 243: Batch_fp = open(batchname(), O_RDONLY); ! 244: Batch_cnt = BATCHSIZE; ! 245: getbatch(&Batchhd, sizeof(Batchhd)); ! 246: printf("\tFound batch file: %s\n", fname); ! 247: printf("\tRelation: %s\tUser: %s\n", Batchhd.rel_name, ! 248: lookucode(Batchhd.userid)); ! 249: close(Batch_fp); ! 250: bmove(Batchhd.userid, Usercode, UCODE_SZ); ! 251: if(ask("\tUpdate? ")) ! 252: update(); ! 253: } ! 254: if (bequal(MODBATCH, fname, sizeof(MODBATCH) - 1)) ! 255: { ! 256: Fileset = &fname[sizeof(MODBATCH) - 1]; ! 257: if ((Batch_fp = open(dp->d_name, O_RDONLY)) < 0) ! 258: syserr("Can't open %s", dp->d_name); ! 259: Batch_cnt = 0; ! 260: if((i = getbatch(&descr, sizeof(descr))) != sizeof(descr)) ! 261: syserr(" cant read %d",i); ! 262: printf("\tFound incomplete modify of %.12s, user = %s\n", ! 263: descr.reldum.relid, lookucode(descr.reldum.relowner)); ! 264: ! 265: bmove(descr.reldum.relowner, Usercode, sizeof(descr.reldum.relowner)); ! 266: close(Batch_fp); ! 267: if (ask("\tComplete? ")) ! 268: modupdate(); ! 269: } ! 270: } ! 271: bmove(Utemp, Usercode, UCODE_SZ); ! 272: ExitFn = tmpfn; ! 273: closedir(dirp); ! 274: } ! 275: /* ! 276: ** handles syserr's in the update processor ! 277: */ ! 278: uperr() ! 279: { ! 280: ! 281: if (Batch_fp) ! 282: close(Batch_fp); ! 283: Berror++; ! 284: longjmp(Jmpbuffer,1); ! 285: } ! 286: ! 287: ! 288: ! 289: /* ! 290: ** Catch errors in other places ! 291: */ ! 292: rubproc() ! 293: { ! 294: register int i; ! 295: register struct desxx *p; ! 296: extern struct desxx Desxx[]; ! 297: extern int Acc_init; ! 298: ! 299: Error++; ! 300: printf("Unable to restore!\n"); ! 301: ! 302: /* restore user code */ ! 303: bmove(Utemp, Usercode, sizeof Utemp); ! 304: ! 305: /* close all possible files */ ! 306: if (Acc_init) ! 307: { ! 308: closecatalog(TRUE); ! 309: unldb(); ! 310: acc_close(); ! 311: } ! 312: ! 313: /* close users file */ ! 314: getuser(0); ! 315: ! 316: /* get everything else */ ! 317: for (i = Direc + 1; i <= NOFILE; i++) ! 318: close(i); ! 319: } ! 320: /* ! 321: ** looks up user by usercode in users file ! 322: */ ! 323: char * ! 324: lookucode(ucode) ! 325: char ucode[2]; ! 326: { ! 327: static char buf[MAXLINE + 1]; ! 328: register char *p; ! 329: ! 330: if (getuser(ucode, buf)) ! 331: syserr("cannot identify user %.2s", ucode); ! 332: for (p = buf; *p != ':'; p++); ! 333: *p = 0; ! 334: return (buf); ! 335: } ! 336: /* ! 337: ** CHECKATTS ! 338: ** Checks that all attributes are in a relation ! 339: */ ! 340: checkatts() ! 341: { ! 342: extern DESC Reldes, Attdes; ! 343: register int i; ! 344: register int once; ! 345: TID tid, limtid, reltid; ! 346: char key[MAXTUP]; ! 347: struct attribute atttup; ! 348: struct relation reltup; ! 349: char lastrel[MAXNAME + 2]; ! 350: ! 351: once = 0; ! 352: opencatalog("relation", OR_WRITE); ! 353: opencatalog("attribute", OR_WRITE); ! 354: clearkeys(&Attdes); ! 355: lastrel[0] = '\0'; ! 356: if (find(&Attdes, NOKEY, &tid, &limtid)) ! 357: syserr("CHECKATT: find"); ! 358: ! 359: while (!(i = get(&Attdes, &tid, &limtid, &atttup, TRUE))) ! 360: { ! 361: if (bequal(atttup.attrelid, lastrel, MAXNAME + 2)) ! 362: continue; ! 363: ! 364: clearkeys(&Reldes); ! 365: setkey(&Reldes, key, atttup.attrelid, ATTRELID); ! 366: setkey(&Reldes, key, atttup.attowner, ATTOWNER); ! 367: ! 368: if (i = getequal(&Reldes, key, &reltup, &reltid)) ! 369: { ! 370: if (i < 0) ! 371: syserr("ATTCHECK: getequal"); ! 372: if (!once++) ! 373: printf("\tNo relation for attribute(s):\n"); ! 374: printf("\t"); ! 375: printup(&Attdes, &atttup); ! 376: if (ask("\tDelete?")) ! 377: if (i = delete(&Attdes, &tid)) ! 378: syserr("ATTCHECK: delete=%d", i); ! 379: } ! 380: else ! 381: bmove(atttup.attrelid, lastrel, MAXNAME + 2); ! 382: } ! 383: ! 384: if (i < 0) ! 385: syserr("ATTCHECK: get=%d", i); ! 386: } ! 387: /* ! 388: ** CHECKREL -- check relation relation against every thing else ! 389: ** ! 390: ** Each tuple in the relation relation is read and each verifiable ! 391: ** characteristic is checked for accuracy. Including the existence ! 392: ** of the physical file (if not a view), the qrymod definition if ! 393: ** appropriate and the secondary indexing. ! 394: */ ! 395: ! 396: checkrel() ! 397: { ! 398: extern DESC Reldes; ! 399: register int i, j; ! 400: struct relation rel; ! 401: TID rtid, limtid; ! 402: char fname[MAXNAME + 3]; ! 403: ! 404: /* setup for search of entire relation */ ! 405: opencatalog("relation", OR_WRITE); ! 406: clearkeys(&Reldes); ! 407: if (find(&Reldes, NOKEY, &rtid, &limtid)) ! 408: syserr("CHECKREL: find"); ! 409: ! 410: /* loop until all tuples checked */ ! 411: for (;;) ! 412: { ! 413: /* for each tuple in the rel-rel */ ! 414: i = get(&Reldes, &rtid, &limtid, &rel, TRUE); ! 415: if (i > 0) ! 416: break; /* have finished */ ! 417: if (i < 0) ! 418: syserr("CHECKREL: get=%d", i); ! 419: ! 420: /* if not a view, check for the file */ ! 421: if ((rel.relstat & S_VIEW) != S_VIEW) ! 422: { ! 423: ingresname(rel.relid, rel.relowner, fname); ! 424: if ((j = open(fname, O_RDWR)) == -1) ! 425: { ! 426: printf("\tNo file for:\n\t"); ! 427: printup(&Reldes, &rel); ! 428: if (ask("\tDelete tuple? ")) ! 429: { ! 430: if(j = delete(&Reldes, &rtid)) ! 431: syserr("CHECKREL: delete=%d", j); ! 432: continue; ! 433: } ! 434: else ! 435: /* don't call purge the file might still be there */ ! 436: Error++; ! 437: } ! 438: else ! 439: close(j); ! 440: } ! 441: ! 442: /* does it think that it has a secondary index */ ! 443: if (rel.relindxd > 0) ! 444: { ! 445: /* does it really have an index? */ ! 446: if (!hasndx(rel.relid, rel.relowner)) ! 447: { ! 448: /* no, should it be fixed */ ! 449: printf("\tNo indexes entry for primary relation:\n\t"); ! 450: printup(&Reldes, &rel); ! 451: if (ask("\tAdjust? ")) ! 452: { ! 453: /* fix up relation relation entry */ ! 454: rel.relindxd = 0; ! 455: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 456: syserr("CHECKREL: replace=%d", i); ! 457: } ! 458: } ! 459: } ! 460: ! 461: /* does it think that it is a secondary index */ ! 462: if (rel.relindxd == SECINDEX) ! 463: { ! 464: /* check to make sure */ ! 465: if (!isndx(rel.relid, rel.relowner)) ! 466: { ! 467: /* none, what should be done? */ ! 468: printf("\tNo indexes entry for index:\n\t"); ! 469: printup(&Reldes, &rel); ! 470: if(ask("\tDelete? ")) ! 471: { ! 472: /* ! 473: ** get rid of rel-rel tuple for ! 474: ** secondary index, ! 475: ** purge will do rest of ! 476: ** removal if necessary ! 477: */ ! 478: if (i = delete(&Reldes, &rtid)) ! 479: syserr("CHECKREL: delete=%d", i); ! 480: continue; /* go on to next tuple */ ! 481: } ! 482: } ! 483: } ! 484: ! 485: /* if qrymod on in the database, check those catalogs too */ ! 486: if (Qrymod) ! 487: { ! 488: /* ! 489: ** cannot deal with S_VBASE since there is no way to ! 490: ** find the tree catalog entries without decoding the ! 491: ** 'treetree' fields. ! 492: ** ! 493: ** check to see if this is a view ! 494: */ ! 495: if ((rel.relstat & S_VIEW) && !havetree(rel.relid, rel.relowner, mdVIEW)) ! 496: { ! 497: /* no entry, should it be fixed? */ ! 498: printf("\tNo tree entry for this view:\n\t"); ! 499: printup(&Reldes, &rel); ! 500: if (ask("\tDelete tuple? ")) ! 501: { ! 502: /* delete relation entry */ ! 503: if (i = delete(&Reldes, &rtid)) ! 504: syserr("CHECKREL: delete=%d", i); ! 505: continue; /* skip to next entry in rel-rel */ ! 506: } ! 507: } ! 508: ! 509: /* check to see if has 'protect' entry */ ! 510: if ((rel.relstat & S_PROTUPS) && !isprot(rel.relid, rel.relowner, -1)) ! 511: { ! 512: /* no entry, should the bit be reset */ ! 513: printf("\tNo protect entry for:\n\t"); ! 514: printup(&Reldes, &rel); ! 515: if (ask("\tAdjust? ")) ! 516: { ! 517: /* fix the bit */ ! 518: rel.relstat &= ~S_PROTUPS; ! 519: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 520: syserr("CHECKREL: replace=%d", i); ! 521: } ! 522: } ! 523: ! 524: /* check to see if has 'integrities entry */ ! 525: if ((rel.relstat & S_INTEG) && !isinteg(rel.relid, rel.relowner, -1)) ! 526: { ! 527: /* no entry, should bit be reset */ ! 528: printf("\tNo integrities entry for:\n\t"); ! 529: printup(&Reldes, &rel); ! 530: if (ask("\tAdjust? ")) ! 531: { ! 532: /* fix up the bit */ ! 533: rel.relstat &= ~S_INTEG; ! 534: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 535: syserr("CHECKREL: replace=%d", i); ! 536: } ! 537: } ! 538: } ! 539: } ! 540: } ! 541: /* ! 542: ** HASNDX -- the relation indicated an index, check it out ! 543: ** ! 544: ** will search the index relation for all secondary indexes ! 545: ** and check to see that each secondary index named has an ! 546: ** entry in the relation relation. ! 547: */ ! 548: hasndx(id, own) ! 549: char id[MAXNAME]; ! 550: char own[2]; ! 551: { ! 552: register int hasindexes; ! 553: register int i, j; ! 554: extern DESC Reldes, Inddes; ! 555: TID rtid; ! 556: struct relation rkey, rel; ! 557: TID itid, ihitid; ! 558: struct index ikey, ind; ! 559: ! 560: /* presume that answer is negative */ ! 561: hasindexes = FALSE; ! 562: ! 563: /* set search for all tuples with 'id' and 'own' in indexes */ ! 564: opencatalog("indexes", OR_WRITE); ! 565: clearkeys(&Inddes); ! 566: setkey(&Inddes, &ikey, id, IRELIDP); ! 567: setkey(&Inddes, &ikey, own, IOWNERP); ! 568: if (find(&Inddes, EXACTKEY, &itid, &ihitid, &ikey)) ! 569: syserr("HASNDX: find"); ! 570: ! 571: /* for each possible tuple in the indexes relation */ ! 572: for (;;) ! 573: { ! 574: i = get(&Inddes, &itid, &ihitid, &ind, TRUE); ! 575: ! 576: /* check return values */ ! 577: if (i < 0) ! 578: syserr("HASNDX: get=%d\n", i); ! 579: if (i > 0) ! 580: break; /* finished */ ! 581: ! 582: /* if key doesn't match, skip to next tuple */ ! 583: if(kcompare(&Inddes, &ikey, &ind)) ! 584: continue; ! 585: hasindexes = TRUE; ! 586: ! 587: /* verify that primary entry for sec index exists */ ! 588: opencatalog("relation", OR_WRITE); ! 589: clearkeys(&Reldes); ! 590: setkey(&Reldes, &rkey, ind.irelidi, RELID); ! 591: setkey(&Reldes, &rkey, ind.iownerp, RELOWNER); ! 592: if (j = getequal(&Reldes, &rkey, &rel, &rtid, FALSE)) ! 593: { ! 594: /* one doesn't exist, should we ignore it */ ! 595: if (j < 0) ! 596: syserr("HASNDX: getequal=%d", j); ! 597: printf("\tNo secondary index for indexes entry:\n\t"); ! 598: printup(&Inddes, &ind); ! 599: if (ask("\tDelete? ")) ! 600: { ! 601: /* get rid of bad entry in indexes relation */ ! 602: if (j = delete(&Inddes, &itid)) ! 603: syserr("HASNDX: delete=%d", j); ! 604: hasindexes = FALSE; ! 605: } ! 606: } ! 607: } ! 608: return (hasindexes); ! 609: } ! 610: /* ! 611: ** ISNDX -- so you think that you're a secondary index, I'll check it out. ! 612: ** ! 613: ** searches the indexes relation for the name of the primary relation ! 614: ** and check to see if the primary is real. Will also update the ! 615: ** 'relindxd' field of the primary if it isn't correct. ! 616: */ ! 617: isndx(id, own) ! 618: char id[MAXNAME]; ! 619: char own[2]; ! 620: { ! 621: register int isindex; ! 622: register int i; ! 623: extern DESC Inddes; ! 624: TID itid; ! 625: struct index ind, ikey; ! 626: extern DESC Reldes; ! 627: TID rtid; ! 628: struct relation rel, rkey; ! 629: ! 630: /* search for tuple in index relation, should only be one */ ! 631: opencatalog("indexes", OR_WRITE); ! 632: clearkeys(&Inddes); ! 633: setkey(&Inddes, &ikey, id, IRELIDI); ! 634: setkey(&Inddes, &ikey, own, IOWNERP); ! 635: if (i = getequal(&Inddes, &ikey, &ind, &itid)) ! 636: { ! 637: /* there isn't a tuple in the indexes relation */ ! 638: if (i < 0) ! 639: syserr("ISNDX: getequal=%d", i); ! 640: isindex = FALSE; ! 641: } ! 642: else ! 643: { ! 644: isindex = TRUE; ! 645: ! 646: /* there is a tuple in the indexes relation */ ! 647: opencatalog("relation", OR_WRITE); ! 648: clearkeys(&Reldes); ! 649: setkey(&Reldes, &rkey, ind.irelidp, RELID); ! 650: setkey(&Reldes, &rkey, ind.iownerp, RELOWNER); ! 651: ! 652: /* see if the primary relation exists */ ! 653: if (i = getequal(&Reldes, &rkey, &rel, &rtid)) ! 654: { ! 655: /* no it doesn't */ ! 656: if (i < 0) ! 657: syserr("ISNDX: getequal=%d", i); ! 658: ! 659: /* what should be done about it */ ! 660: printf("\tNo primary relation for index:\n\t"); ! 661: printup(&Inddes, &ind); ! 662: if (ask("\tDelete?")) ! 663: { ! 664: /* ! 665: ** get rid of indexes tuple, ! 666: ** a FALSE return will also get rid ! 667: ** of the relation tuple ! 668: */ ! 669: if (i = delete(&Inddes, &itid)) ! 670: syserr("ISNDX: delete=%d", i); ! 671: isindex = FALSE; ! 672: } ! 673: } ! 674: else if (!(rel.relindxd > 0) || (rel.relstat & S_INDEX) == S_INDEX) ! 675: { ! 676: /* ! 677: ** the primary tuple exists but isn't marked correctly ! 678: */ ! 679: printf("\t%.12s is index for:\n\t", rel.relid); ! 680: printup(&Reldes, &rel); ! 681: if (ask("\tMark as indexed? ")) ! 682: { ! 683: rel.relstat |= S_INDEX; ! 684: rel.relindxd = SECBASE; ! 685: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 686: syserr("ISNDX: replace=%d", i); ! 687: } ! 688: } ! 689: } ! 690: return (isindex); ! 691: } ! 692: /* ! 693: ** HAVETREE -- check tree catalog for an entry with right name and owner ! 694: ** ! 695: ** The 'id' and 'own' parameters are used to look in the tree catalog ! 696: ** for at least on tuple that also has a 'treetype' of 'mdvalue'. ! 697: ** ! 698: ** If any tuples are found, havetree returns TRUE, else FALSE ! 699: */ ! 700: ! 701: havetree(id, own, mdvalue) ! 702: char id[MAXNAME]; ! 703: char own[2]; ! 704: int mdvalue; ! 705: { ! 706: extern DESC Treedes; ! 707: register int i; ! 708: struct tree tkey, trent; ! 709: TID ttid, thitid; ! 710: ! 711: /* search tree relation for tuple that matches */ ! 712: opencatalog("tree", OR_WRITE); ! 713: clearkeys(&Treedes); ! 714: setkey(&Treedes, &tkey, id, TREERELID); ! 715: setkey(&Treedes, &tkey, own, TREEOWNER); ! 716: setkey(&Treedes, &tkey, &mdvalue, TREETYPE); ! 717: ! 718: /* set search limit tids from the key */ ! 719: if (i = find(&Treedes, EXACTKEY, &ttid, &thitid, &tkey)) ! 720: syserr("HAVETREE: find=%d", i); ! 721: ! 722: for (;;) ! 723: { ! 724: i = get(&Treedes, &ttid, &thitid, &trent, TRUE); ! 725: ! 726: if (i < 0) ! 727: syserr("HAVETREE: get=%d", i); ! 728: if (i > 0) ! 729: break; /* finished, didn't find one */ ! 730: ! 731: if (kcompare(&Treedes, &tkey, &trent) == 0) ! 732: return (TRUE); ! 733: } ! 734: return (FALSE); ! 735: } ! 736: /* ! 737: ** ISPROT -- check in the 'protect' catalog for a tuple with right name, owner ! 738: ** ! 739: ** search the 'protect' catalog for at least on tuple with matches the ! 740: ** values in the parameters. If 'treeid' is >= 0 then it is not used as ! 741: ** a key. ! 742: ** ! 743: ** if one is found, returns TRUE, otherwise, returns FALSE ! 744: */ ! 745: ! 746: isprot(id, own, treeid) ! 747: char id[MAXNAME]; ! 748: char own[2]; ! 749: int treeid; ! 750: { ! 751: extern DESC Prodes; ! 752: register int i; ! 753: struct protect pkey, pent; ! 754: TID ptid, phitid; ! 755: ! 756: /* search the protect relation for at least on matching tuple */ ! 757: opencatalog("protect", OR_WRITE); ! 758: clearkeys(&Prodes); ! 759: setkey(&Prodes, &pkey, id, PRORELID); ! 760: setkey(&Prodes, &pkey, own, PRORELOWN); ! 761: if (treeid >= 0) ! 762: setkey(&Prodes, &pkey, &treeid, PROTREE); ! 763: ! 764: /* set search limit tids from the keys */ ! 765: if (i = find(&Prodes, EXACTKEY, &ptid, &phitid, &pkey)) ! 766: syserr("ISPROT: find=%d", i); ! 767: ! 768: for (;;) ! 769: { ! 770: i = get(&Prodes, &ptid, &phitid, &pent, TRUE); ! 771: ! 772: if (i < 0) ! 773: syserr("ISPROT: get=%d", i); ! 774: if (i > 0) ! 775: break; /* finished, didn't find one */ ! 776: ! 777: if (kcompare(&Prodes, &pkey, &pent) == 0) ! 778: return (TRUE); ! 779: } ! 780: return (FALSE); ! 781: } ! 782: /* ! 783: ** ISINTEG -- check for a tuple in 'integrities' ! 784: ** ! 785: ** searches the integrities relation for 'id' and 'own'. ! 786: ** ! 787: ** returns TRUE if one is found, else FALSE ! 788: */ ! 789: ! 790: isinteg(id, own, treeid) ! 791: char id[MAXNAME]; ! 792: char own[2]; ! 793: int treeid; ! 794: { ! 795: extern DESC Intdes; ! 796: register int i; ! 797: struct integrity inkey, integ; ! 798: TID intid, inhitid; ! 799: ! 800: /* search the entire relation for a tuple that matches */ ! 801: opencatalog("integrities", OR_WRITE); ! 802: clearkeys(&Intdes); ! 803: setkey(&Intdes, &inkey, id, INTRELID); ! 804: setkey(&Intdes, &inkey, own, INTRELOWNER); ! 805: if (treeid >= 0) ! 806: setkey(&Intdes, &inkey, &treeid, INTTREE); ! 807: ! 808: /* set the search limit tids from the key */ ! 809: if (i = find(&Intdes, EXACTKEY, &intid, &inhitid, &inkey)) ! 810: syserr("ISINTEG: find=%d", i); ! 811: ! 812: for (;;) ! 813: { ! 814: i = get(&Intdes, &intid, &inhitid, &integ, TRUE); ! 815: ! 816: if (i < 0) ! 817: syserr("ISINTEG: get=%d", i); ! 818: if (i > 0) ! 819: break; /* finished, didn't find one */ ! 820: ! 821: if (kcompare(&Intdes, &inkey, &integ) == 0) ! 822: return (TRUE); ! 823: } ! 824: return (FALSE); ! 825: } ! 826: /* ! 827: ** CHECKTREE -- check the tree catalog against the others ! 828: */ ! 829: ! 830: checktree() ! 831: { ! 832: extern DESC Treedes, Reldes; ! 833: register int i; ! 834: struct tree tkey, trent; ! 835: TID ttid, thitid; ! 836: struct relation rkey, rel; ! 837: TID rtid; ! 838: ! 839: /* search the entire tree catalog */ ! 840: opencatalog("tree", OR_WRITE); ! 841: clearkeys(&Treedes); ! 842: if (i = find(&Treedes, NOKEY, &ttid, &thitid)) ! 843: syserr("CHECKTREE: find=%d", i); ! 844: ! 845: /* for each tuple in 'tree' */ ! 846: for (;;) ! 847: { ! 848: i = get(&Treedes, &ttid, &thitid, &trent, TRUE); ! 849: if (i > 0) ! 850: break; /* finished */ ! 851: if (i < 0) ! 852: syserr("CHECKTREE: get=%d", i); ! 853: ! 854: /* verify that a tuple exists in the relation relation */ ! 855: opencatalog("relation", OR_WRITE); ! 856: clearkeys(&Reldes); ! 857: setkey(&Reldes, &rkey, trent.treerelid, RELID); ! 858: setkey(&Reldes, &rkey, trent.treeowner, RELOWNER); ! 859: ! 860: /* fetch the tuple */ ! 861: if (i = getequal(&Reldes, &rkey, &rel, &rtid)) ! 862: { ! 863: /* ! 864: ** Oops, a tuple doesn't exist in the relation ! 865: ** relation. ! 866: ** ! 867: ** maybe it's just a fatal error ! 868: */ ! 869: if (i < 0) ! 870: syserr("CHECKTREE: getequal=%d", i); ! 871: ! 872: /* not a fatal error, what to do about it? */ ! 873: printf("\tNo relation tuple for:\n\t"); ! 874: printup(&Treedes, &trent); ! 875: if (ask("\tDelete? ")) ! 876: { ! 877: if (i = delete(&Treedes, &ttid)) ! 878: syserr("CHECKTREE: delete=%d", i); ! 879: continue; /* go on to next tuple */ ! 880: } ! 881: } ! 882: else ! 883: { ! 884: /* ! 885: ** Ah. A tuple does exist. ! 886: ** ! 887: ** If the relstat bits are correct then we can stop ! 888: ** here since elsewhere the 'protect' and 'integrity' ! 889: ** entries were verified. ! 890: */ ! 891: switch (trent.treetype) ! 892: { ! 893: case mdVIEW: ! 894: /* mere existence is sufficient */ ! 895: break; ! 896: ! 897: case mdPROT: ! 898: if ((rel.relstat & S_PROTUPS) != S_PROTUPS) ! 899: { ! 900: printf("\tNo 'protect' entry for:\n\t"); ! 901: deltup: ! 902: printup(&Treedes, &trent); ! 903: if (ask("\tDelete? ")) ! 904: { ! 905: if (i = delete(&Treedes, &ttid)) ! 906: syserr("CHECKTREE: delete=%d", i); ! 907: continue; ! 908: } ! 909: } ! 910: break; ! 911: ! 912: case mdINTEG: ! 913: if ((rel.relstat & S_INTEG) != S_INTEG) ! 914: { ! 915: printf("\tNo 'integrities' entry for:\n\t"); ! 916: goto deltup; ! 917: } ! 918: break; ! 919: ! 920: default: ! 921: syserr("Unknown treetype: %d\n", trent.treetype); ! 922: } ! 923: } ! 924: } ! 925: } ! 926: /* ! 927: ** CHECKPROTECT ! 928: */ ! 929: ! 930: checkprotect() ! 931: { ! 932: register int i; ! 933: extern DESC Reldes, Prodes; ! 934: struct protect pkey, pent; ! 935: TID ptid, phitid; ! 936: struct relation rkey, rel; ! 937: TID rtid; ! 938: ! 939: /* for each entry in the 'protect' relation */ ! 940: opencatalog("protect", OR_WRITE); ! 941: clearkeys(&Prodes); ! 942: if (i = find(&Prodes, NOKEY, &ptid, &phitid)) ! 943: syserr("CHECKPROTECT: find=%d", i); ! 944: ! 945: for (;;) ! 946: { ! 947: i = get(&Prodes, &ptid, &phitid, &pent, TRUE); ! 948: if (i > 0) ! 949: break; /* finished */ ! 950: if (i < 0) ! 951: syserr("CHECKPROTECT: get=%d", i); ! 952: ! 953: /* verify that a tuple exists in 'relation' */ ! 954: opencatalog("relation", OR_WRITE); ! 955: clearkeys(&Reldes); ! 956: setkey(&Reldes, &rkey, pent.prorelid, RELID); ! 957: setkey(&Reldes, &rkey, pent.prorelown, RELOWNER); ! 958: ! 959: /* fetch the tuple if possible */ ! 960: if (i = getequal(&Reldes, &rkey, &rel, &rtid)) ! 961: { ! 962: /* ! 963: ** Oops. A tuple doesn't exits in 'relation' ! 964: ** ! 965: ** Maybe it's just a fatal error. ! 966: */ ! 967: if (i < 0) ! 968: syserr("CHECKPROTECT: getequal=%d", i); ! 969: ! 970: /* not a fatal error, what to do? */ ! 971: printf("\tNo relation for 'protect' entry:\n\t"); ! 972: printup(&Prodes, &pent); ! 973: if (ask("\tRemove 'protect' entry? ")) ! 974: { ! 975: if (i = delete(&Prodes, &ptid)) ! 976: syserr("CHECKPROTECT: delete=%d", i); ! 977: continue; /* go on to next tuple */ ! 978: } ! 979: } ! 980: else ! 981: { ! 982: /* 'relation' entry exists, check for the tree entry */ ! 983: if (pent.protree >= 0) ! 984: { ! 985: if (!havetree(pent.prorelid, pent.prorelown, mdPROT)) ! 986: { ! 987: /* no tuples in 'tree' */ ! 988: printf("\tNo tree for:\n\t"); ! 989: printup(&Prodes, &pent); ! 990: if (ask("\tDelete entry and fix relation status bits? ")) ! 991: { ! 992: if (i = delete(&Prodes, &pent)) ! 993: syserr("CHECKPROTECT: delete=%d", i); ! 994: rel.relstat &= ~S_PROTUPS; ! 995: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 996: syserr("CHECKPROTECT: replace=%d", i); ! 997: continue; /* go on to next tuple */ ! 998: } ! 999: } ! 1000: } ! 1001: if ((rel.relstat & S_PROTUPS) != S_PROTUPS) ! 1002: { ! 1003: /* bits not set correctly */ ! 1004: printf("\tIncorrect relation status bits for:\n\t"); ! 1005: printup(&Reldes, &rel); ! 1006: if (ask("\tAdjust? ")) ! 1007: { ! 1008: rel.relstat |= S_PROTUPS; ! 1009: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 1010: syserr("CHECKPROTECT: replace=%d", i); ! 1011: continue; /* go on to next tuple */ ! 1012: } ! 1013: } ! 1014: } ! 1015: } ! 1016: } ! 1017: /* ! 1018: ** CHECKINTEG ! 1019: */ ! 1020: ! 1021: checkinteg() ! 1022: { ! 1023: register int i; ! 1024: extern DESC Reldes, Intdes; ! 1025: struct integrity inkey, inent; ! 1026: TID intid, inhitid; ! 1027: struct relation rkey, rel; ! 1028: TID rtid; ! 1029: ! 1030: /* for each entry in 'integrities' */ ! 1031: opencatalog("integrities", OR_WRITE); ! 1032: clearkeys(&Intdes); ! 1033: if (i = find(&Intdes, NOKEY, &intid, &inhitid)) ! 1034: syserr("CHECKINTEG: find=%d", i); ! 1035: ! 1036: for (;;) ! 1037: { ! 1038: i = get(&Intdes, &intid, &inhitid, &inent, TRUE); ! 1039: if (i > 0) ! 1040: break; /* finished */ ! 1041: if (i < 0) ! 1042: syserr("CHECKINTEG: get=%d", i); ! 1043: ! 1044: /* verify that a tuple exists in 'relation' */ ! 1045: opencatalog("relation", OR_WRITE); ! 1046: clearkeys(&Reldes); ! 1047: setkey(&Reldes, &rkey, inent.intrelid, RELID); ! 1048: setkey(&Reldes, &rkey, inent.intrelowner, RELOWNER); ! 1049: ! 1050: /* fetch the tuple if possible */ ! 1051: if (i = getequal(&Reldes, &rkey, &rel, &rtid)) ! 1052: { ! 1053: /* ! 1054: ** Oops. A tuple doesn't exits in 'relation' ! 1055: ** ! 1056: ** Maybe it's just a fatal error. ! 1057: */ ! 1058: if (i < 0) ! 1059: syserr("CHECKINTEG: getequal=%d", i); ! 1060: ! 1061: /* not a fatal error, what to do? */ ! 1062: printf("\tNo relation for 'integrities' entry:\n\t"); ! 1063: printup(&Intdes, &inent); ! 1064: if (ask("\tRemove 'integrities' entry? ")) ! 1065: { ! 1066: if (i = delete(&Intdes, &intid)) ! 1067: syserr("CHECKINTEG: delete=%d", i); ! 1068: continue; /* go on to next tuple */ ! 1069: } ! 1070: } ! 1071: else ! 1072: { ! 1073: /* 'relation' entry exists, check for the tree entry */ ! 1074: if (inent.inttree >= 0) ! 1075: { ! 1076: if (!havetree(inent.intrelid, inent.intrelowner, mdINTEG)) ! 1077: { ! 1078: /* no tuples in 'tree' */ ! 1079: printf("\tNo tree for:\n\t"); ! 1080: printup(&Intdes, &inent); ! 1081: if (ask("\tDelete entry and fix relation status bits? ")) ! 1082: { ! 1083: if (i = delete(&Intdes, &inent)) ! 1084: syserr("CHECKINTEG: delete=%d", i); ! 1085: rel.relstat &= ~S_INTEG; ! 1086: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 1087: syserr("CHECKINTEG: replace=%d", i); ! 1088: continue; /* go on to next tuple */ ! 1089: } ! 1090: } ! 1091: } ! 1092: if ((rel.relstat & S_INTEG) != S_INTEG) ! 1093: { ! 1094: /* bits not set correctly */ ! 1095: printf("\tIncorrect relation status bits for:\n\t"); ! 1096: printup(&Reldes, &rel); ! 1097: if (ask("\tAdjust? ")) ! 1098: { ! 1099: rel.relstat |= S_INTEG; ! 1100: if (i = replace(&Reldes, &rtid, &rel, FALSE)) ! 1101: syserr("CHECKINTEG: replace=%d", i); ! 1102: continue; /* go on to next tuple */ ! 1103: } ! 1104: } ! 1105: } ! 1106: } ! 1107: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.