Annotation of 43BSD/ingres/source/support/restore.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.