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: }

Defined functions

checkatts defined in line 340; used 1 times
checkinteg defined in line 1021; used 1 times
checkprotect defined in line 930; used 1 times
checkrel defined in line 396; used 1 times
checktree defined in line 830; used 1 times
hasndx defined in line 548; used 1 times
havetree defined in line 701; used 3 times
isinteg defined in line 790; used 1 times
isndx defined in line 617; used 1 times
isprot defined in line 746; used 1 times
lookucode defined in line 323; used 5 times
main defined in line 62; never used
restore defined in line 205; used 1 times
rubproc defined in line 292; used 2 times
uperr defined in line 278; used 2 times

Defined variables

Berror defined in line 40; used 3 times
Btree_fd defined in line 52; never used
Direc defined in line 46; used 1 times
Error defined in line 41; used 6 times
Fileset defined in line 39; used 3 times
Jmpbuffer defined in line 53; used 4 times
Resp defined in line 50; never used
Utemp defined in line 38; used 4 times
tTdbu defined in line 49; used 1 times
  • in line 86
tTvect defined in line 48; used 1 times
  • in line 85

Defined macros

CLOSEFILES defined in line 34; used 1 times
  • in line 46
PURGE defined in line 29; used 4 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2862
Valid CSS Valid XHTML 1.0 Strict