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