# 2.11BSD#431 - /usr/ingres/source/support/restore.c

##### Functions

    checkatts         X
    checkinteg        X
    checkprotect      X
    checkrel          X
    checktree         X
    hasndx            X
    havetree          X
    isinteg           X
    isndx             X
    isprot            X
    lookucode         X
    main              X
    restore           X
    rubproc           X
    uperr             X

##### Variables

    Berror            X
    Dburetcode        X
    Dburetflag        X
    Direc             X
    Error             X
    Fileset           X
    Utemp             X

##### Macros

    CLOSEFILES        X
    DESC              X
    PURGE             X

       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

- in line 123

checkinteg defined in line 997; used 1 times

- in line 132

checkprotect defined in line 910; used 1 times

- in line 129

checkrel defined in line 374; used 1 times

- in line 112

checktree defined in line 811; used 1 times

- in line 140

hasndx defined in line 528; used 1 times

- in line 424

havetree defined in line 682; used 3 times

- in line 473, 965, 1052

isinteg defined in line 771; used 1 times

- in line 503

isndx defined in line 598; used 1 times

- in line 443

isprot defined in line 727; used 1 times

- in line 488

lookucode defined in line 298; used 3 times

- in line 87, 217, 233

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

- in line 57, 74

uperr defined in line 251; used 2 times

- in line 193, 203

#### Defined variables

Berror defined in line 30; used 3 times

- in line 78, 149, 256

Dburetcode defined in line 44; never used
Dburetflag defined in line 43; never used
Direc defined in line 36; used 1 times

- in line 290

Error defined in line 31; used 6 times

- in line 78-82(2), 101, 149, 272, 414

Fileset defined in line 29; used 3 times

- in line 192, 211, 226

Utemp defined in line 28; used 4 times

- in line 200, 241, 276(2)

#### Defined macros

CLOSEFILES defined in line 24; used 1 times

- in line 36

DESC defined in line 21; used 12 times

- in line 190, 317, 376, 534, 604-607(2), 687, 732, 776, 813, 913, 1000

PURGE defined in line 20; used 2 times

- in line 171-172(2)

Last modified: 1995-02-12 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3748 |