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

Defined functions

checkatts defined in line 315; used 1 times
checkinteg defined in line 997; used 1 times
checkprotect defined in line 910; used 1 times
checkrel defined in line 374; used 1 times
checktree defined in line 811; used 1 times
hasndx defined in line 528; used 1 times
havetree defined in line 682; used 3 times
isinteg defined in line 771; used 1 times
isndx defined in line 598; used 1 times
isprot defined in line 727; used 1 times
lookucode defined in line 298; used 3 times
main defined in line 47; never used
restore defined in line 186; used 1 times
  • in line 92
rubproc defined in line 265; used 2 times
uperr defined in line 251; used 2 times

Defined variables

Berror defined in line 30; used 3 times
Dburetcode defined in line 44; never used
Dburetflag defined in line 43; never used
Direc defined in line 36; used 1 times
Error defined in line 31; used 6 times
Fileset defined in line 29; used 3 times
Utemp defined in line 28; used 4 times

Defined macros

CLOSEFILES defined in line 24; used 1 times
  • in line 36
DESC defined in line 21; used 12 times
PURGE defined in line 20; used 2 times
Last modified: 1995-02-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 7934
Valid CSS Valid XHTML 1.0 Strict