Annotation of 42BSD/ingres/source/iutil/initucode.c, revision 1.1.1.1

1.1       root        1: # include      <stdio.h>
                      2: # include      <ingres.h>
                      3: # include      <aux.h>
                      4: # include      <version.h>
                      5: # include      <opsys.h>
                      6: # include      <access.h>
                      7: # include      <lock.h>
                      8: # include      <signal.h>
                      9: # include      <sccs.h>
                     10: 
                     11: SCCSID(@(#)initucode.c 7.4     9/26/83)
                     12: 
                     13: /*
                     14: **  INITUCODE -- initialize standalone process
                     15: **
                     16: **     This function initializes a standalone process, initializing
                     17: **     a lot of global variables, scanning the argument vector for
                     18: **     some special flags (-u and +-w), seperating flags and
                     19: **     parameters, and so forth.
                     20: **
                     21: **     Every standalone program should begin with the lines:
                     22: **                     i = initucode(argc, argv, ...);
                     23: **                     switch (i)
                     24: **                             ...
                     25: **
                     26: **     On a return of 2, 3, or 4, essentially none of the processing
                     27: **     is done (particularly true with return 4).  Virtually nothing
                     28: **     can be done in the calling program except print a "usage"
                     29: **     message and exit.  The exception to this is that 'Pathname'
                     30: **     is set, so that it can be used in the error printing.  For
                     31: **     example, ingres.c cats file .../files/usage on this sort of
                     32: **     error.
                     33: **
                     34: **     If it is preferable to not lock the database at this time,
                     35: **     the 'waitmode' parameter should be passed as -1.  This still
                     36: **     causes the 'Wait_action' variable to be initialized, but the
                     37: **     database is not actually locked.  It can be locked by calling:
                     38: **             db_lock(Dbpath, M_EXCL);
                     39: **     at the proper time.
                     40: **
                     41: **     For the main effects of this routine, see the "Side Effects"
                     42: **     section below.
                     43: **
                     44: **     Parameters:
                     45: **             argc -- argc from main.
                     46: **             argv -- argv from main.
                     47: **             dbflag -- TRUE -- take the first parameter as the
                     48: **                             database name.
                     49: **                     FALSE -- don't take the first parameter as
                     50: **                             the database name.
                     51: **             paramlist -- a pointer to an array[4] of pointers
                     52: **                     to character; set to the extra fields of
                     53: **                     the users file entry for the real user
                     54: **                     executing the code (not the user on the
                     55: **                     -u flag).  If NULL, this is ignored.
                     56: **             waitmode -- M_EXCL -- set an exclusive lock on the
                     57: **                             database.
                     58: **                     M_SHARE -- set a shared lock on the database.
                     59: **                     -1 -- don't set a lock on the database.
                     60: **                             However, other stuff (Wait_action) is
                     61: **                             still set up so that the lock can be
                     62: **                             placed later by calling 'db_lock'.
                     63: **
                     64: **     Returns:
                     65: **             0 -- everything is ok.
                     66: **             1 -- the database does not exist.
                     67: **             2 -- you are not authorized to access this database.
                     68: **             3 -- you are not a valid INGRES user.
                     69: **             4 -- no database name was specified (only if dbflag
                     70: **                     == TRUE).
                     71: **             5 -- everything is ok, but there was an indirect
                     72: **                     taken.
                     73: **             6 -- there was an indirect taken, but there was no
                     74: **                     database there.
                     75: **
                     76: **             If dbflag == FALSE, you can only get returns 0 and
                     77: **                     3.
                     78: **
                     79: **     Side Effects:
                     80: **             A lot of variables are set, as follows:
                     81: **
                     82: **             Dbpath -- set to the pathname of the database (only
                     83: **                     if dbflag == TRUE).  It is set even if the
                     84: **                     database does not exist.
                     85: **             Parmvect -- set to the parameters from argv, that is,
                     86: **                     anything not beginning with '+' or '-'.
                     87: **             Flagvect -- set to the flags from argv, that is,
                     88: **                     everything beginning with '+' or '-'.  The
                     89: **                     flags '+w', '-w', and '-u' are stripped out,
                     90: **                     however.
                     91: **             Wait_action -- set to the appropriate action (A_SLP
                     92: **                     or A_RTN) based on the +-w flags and whether
                     93: **                     we are running in background or not.
                     94: **                     This is automatically used by 'db_lock()'.
                     95: **             Usercode -- set to the persons effective user code
                     96: **                     (that is, after the -u processing).  Only
                     97: **                     the INGRES user or the DBA can use the -u
                     98: **                     flag.
                     99: **             Pathname -- set to the pathname of the INGRES subtree.
                    100: **             Status -- an integer set to the user status field
                    101: **                     of the users file for the real user.
                    102: **             Ing_uid -- set to the user id of the INGRES user.
                    103: **
                    104: **             The rubout signal (signal 2) is caught, and refered
                    105: **             to the standard rubout processor (see rub.c); thus,
                    106: **             a routine called 'rubproc' must be defined in the
                    107: **             standalone code (which will just call exit, in the
                    108: **             normal case).
                    109: **
                    110: **             The 'adminhdr' part of the 'Admin' struct is filled
                    111: **             in.  This is not done with readadmin() and is not
                    112: **             equivalent to an 'admininit()', but it does make
                    113: **             the DBA and database status available.
                    114: **
                    115: **             This routine can also exit immediately with an
                    116: **             error message.
                    117: **
                    118: **     Defined Constants:
                    119: **             MAXPARGS -- the maximum number of parameter type
                    120: **                     arguments to any standalone program.
                    121: **             MAXFARGS -- the maximum number of flag type arg-
                    122: **                     uments to any standalong program (not inclu-
                    123: **                     ding flags in the users file, and the +-w
                    124: **                     and -u flags).
                    125: **
                    126: **     Files:
                    127: **             /etc/passwd -- to get the pathname for user "ingres".
                    128: **             .../files/users -- to get all the per-user information,
                    129: **                     and to process the -u flag.
                    130: **
                    131: **     Compilation Flags:
                    132: **             xB_UNIX, xV6_UNIX -- see comments in aux.h
                    133: **
                    134: **     Trace Flags:
                    135: **             none
                    136: */
                    137: 
                    138: 
                    139: # define       MAXFARGS        15      /* maximum flag-type arguments */
                    140: # define       MAXPARGS        20      /* maximum parameter-type args */
                    141: 
                    142: char   *Usercode;      /* the usercode of the effective user */
                    143: char   *Pathname;      /* path of INGRES subtree */
                    144: int    Status;         /* the user status of the real user */
                    145: int    Rubignored;     /* set if rubouts ignored */
                    146:                        /* (also in initproc for system processes) */
                    147: int    Wait_action;    /* the action on the db_lock */
                    148: char   *Dbpath;        /* the pathname of the database */
                    149: char   *Flagvect[MAXFARGS+1];  /* the flags from argv */
                    150: char   *Parmvect[MAXPARGS+1];  /* the parameters from argv */
                    151: int    Ing_uid;        /* the user id of the INGRES user */
                    152: 
                    153: initucode(argc, argv, dbflag, paramlist, waitmode)
                    154: int    argc;
                    155: char   **argv;
                    156: int    dbflag;
                    157: char   *paramlist[4];
                    158: int    waitmode;
                    159: {
                    160:        register char   *p;
                    161:        char            *q;
                    162:        char            c;
                    163:        FILE            *iop;
                    164:        static char     sbuf[MAXLINE * 2];
                    165:        register char   *sbufp;
                    166:        char            buf[MAXLINE+1];
                    167:        register int    i;
                    168:        int             npermit;
                    169:        int             rtval;
                    170:        char            *field[UF_NFIELDS];
                    171:        int             actualuid;
                    172:        auto int        uid;
                    173:        auto int        gid;
                    174:        int             waitflag;
                    175:        char            *userflag;
                    176:        struct sgttyb   gttydummy;
                    177:        int             fvi, pvi;
                    178:        char            **avp;
                    179:        char            usr_ovrd[3];
                    180:        static int      reenter;
                    181:        extern          rubcatch();
                    182:        static short    tvect[100];
                    183:        bool            nobuffer;
                    184: # ifdef xV7_UNIX
                    185:        extern char     *getenv();
                    186: # endif xV7_UNIX
                    187: 
                    188:        /*
                    189:        **  Set up interrupts.
                    190:        */
                    191: 
                    192:        reenter = 0;
                    193:        setexit();
                    194:        if (reenter++)
                    195:                exit(-1);
                    196:        if (signal(SIGINT, SIG_IGN) == SIG_DFL)
                    197:                signal(SIGINT, rubcatch);
                    198: # ifdef xV6_UNIX
                    199:        for (avp = argv; *avp != 0 && *avp != (char *) -1; avp++)
                    200:                continue;
                    201:        *avp = NULL;
                    202: # endif
                    203: 
                    204:        /*
                    205:        **  Do basic initialization, such as setting trace flags.
                    206:        */
                    207: 
                    208:        nobuffer = tTrace(argv, 'T', tvect, 100);
                    209:        if (!nobuffer)
                    210:                set_so_buf();
                    211:        sbufp = sbuf;
                    212: 
                    213:        /*
                    214:        **  Get pathname of INGRES subtree from /etc/passwd file
                    215:        **  entry for USERINGRES (presumably "ingres") and save it
                    216:        **  in 'Pathname'.
                    217:        **
                    218:        **  This algorithm suggested by Jim Popa.
                    219:        */
                    220: 
                    221: # ifdef xV7_UNIX
                    222:        Pathname = getenv("INGPATH");
                    223:        if (Pathname == NULL)
                    224:        {
                    225: # endif xV7_UNIX
                    226:                if ((iop = fopen("/etc/passwd", "r")) == NULL)
                    227:                        syserr("initucode: passwd");
                    228: 
                    229:                do
                    230:                {
                    231:                        if (fgets(buf, MAXLINE, iop) == NULL)
                    232:                                syserr("initucode: no INGRES");
                    233:                        
                    234:                        /* decode passwd entry */
                    235:                        i = 0;
                    236:                        for (p = buf; *p != '\n' && *p != '\0'; p++)
                    237:                        {
                    238:                                if (*p == ':')
                    239:                                {
                    240:                                        *p = 0;
                    241:                                        i++;
                    242:                                        field[i] = p + 1;
                    243:                                }
                    244:                        }
                    245:                        *p = '\0';
                    246: 
                    247:                        /* check for enough fields for valid entry */
                    248:                        if (i < 3)
                    249:                                syserr("initucode: passwd fmt %s", buf);
                    250:                } while (!sequal(buf, USERINGRES));
                    251: 
                    252:                /* we now have the INGRES passwd file entry in 'buf' */
                    253:                fclose(iop);
                    254: 
                    255:                /* copy pathname entry into 'Pathname' variable */
                    256:                Pathname = sbufp;
                    257:                sbufp += smove(field[i - 1], sbufp) + 1;
                    258: # ifdef PATHEXT
                    259:                sbufp += smove(PATHEXT, sbufp - 1);
                    260: # endif PATHEXT
                    261: # ifdef xV7_UNIX
                    262:        }
                    263: # endif xV7_UNIX
                    264: 
                    265:        /* create the INGRES user id */
                    266:        Ing_uid = atoi(field[2]);
                    267: # ifdef xV6_UNIX
                    268:        Ing_uid &= 0377;
                    269: # endif
                    270: # ifdef xB_UNIX
                    271:        gid = atoi(field[3]);
                    272:        Ing_uid = (Ing_uid & 0377) | ((gid & 0377) << 8);
                    273: # endif
                    274: 
                    275:        /*
                    276:        **  Scan the argument vector.  The following flags are pulled
                    277:        **  out of the vector (and argc and argv are adjusted so it
                    278:        **  looks like they never existed):
                    279:        **      +w, -w -- (don't) wait for the database to be free.
                    280:        **      -uxxx -- run as user xxx.  If first character is a
                    281:        **      colon, the format must be '-u:xx' where 'xx' is the
                    282:        **      internal user code.
                    283:        */
                    284: 
                    285:        avp = argv;
                    286:        fvi = 0;
                    287:        pvi = 0;
                    288:        waitflag = 0;
                    289:        userflag = NULL;
                    290:        usr_ovrd[0] = 0;
                    291: 
                    292:        for (i = argc; --i > 0; )
                    293:        {
                    294:                p = *++avp;
                    295:                if (p[0] == '+')
                    296:                {
                    297:                        if (p[1] == 'w')
                    298:                                waitflag = 1;
                    299:                        else
                    300:                                goto boring;
                    301:                }
                    302:                else if (p[0] == '-')
                    303:                {
                    304:                        switch (p[1])
                    305:                        {
                    306:                          case 'w':
                    307:                                waitflag = -1;
                    308:                                break;
                    309:                        
                    310:                          case 'u':
                    311:                                if (p[2] == ':')
                    312:                                {
                    313:                                        if (p[3] == 0 || p[4] == 0 || p[5] != 0)
                    314:                                        {
                    315:                                                printf("Bad flag %s\n", p);
                    316:                                                exit(-1);
                    317:                                        }
                    318:                                        smove(&p[3], usr_ovrd);
                    319:                                }
                    320:                                else
                    321:                                        userflag = &p[2];
                    322:                                break;
                    323: 
                    324:                          default:
                    325:                                /* not an interesting flag */
                    326:                        boring:
                    327:                                if (fvi >= MAXFARGS)
                    328:                                {
                    329:                                        printf("Too many flags\n");
                    330:                                        exit(-1);
                    331:                                }
                    332:                                Flagvect[fvi++] = p;
                    333:                                break;
                    334:                        }
                    335:                }
                    336:                else
                    337:                {
                    338:                        /* not a flag: save in Parmvect */
                    339:                        if (pvi >= MAXPARGS)
                    340:                        {
                    341:                                printf("Too many parmameters\n");
                    342:                                exit(-1);
                    343:                        }
                    344:                        Parmvect[pvi++] = p;
                    345:                }
                    346:        }
                    347: 
                    348:        if (pvi <= 0 && dbflag)
                    349:        {
                    350:                return (4);     /* no database name specified */
                    351:        }
                    352: 
                    353:        /*
                    354:        **  Scan the "users" file.
                    355:        */
                    356: 
                    357:        if ((iop = fopen(ztack(Pathname, "/files/users"), "r")) == NULL)
                    358:                syserr("initucode: open error");
                    359:        
                    360:        /* get uid (out of loop) for test */
                    361: #      ifdef xV6_UNIX
                    362:        actualuid = getuid() & 0377;
                    363: #      endif
                    364: #      ifndef xV6_UNIX
                    365:        actualuid = getuid();
                    366: #      endif
                    367:        
                    368:        /* scan users file, one line at a time */
                    369:        rtval = 3;
                    370:        while ((Usercode == NULL || userflag != NULL) && fgets(buf, MAXLINE, iop) != NULL)
                    371:        {
                    372:        
                    373:                /* decode users file entry */
                    374:                i = 0;
                    375:                field[0] = buf;
                    376:                for (p = buf; *p != '\n' && *p != '\0'; p++)
                    377:                {
                    378:                        if (*p == ':')
                    379:                        {
                    380:                                *p = 0;
                    381:                                i++;
                    382:                                field[i] = p + 1;
                    383:                        }
                    384:                }
                    385:                *p = '\0';
                    386: 
                    387:                /* check for correct number of fields */
                    388:                if (i != UF_NFIELDS - 1)
                    389:                        syserr("initucode: users fmt %s", buf);
                    390: 
                    391:                /*
                    392:                **  Check to see if this entry is the override user.
                    393:                **  If so, save his user code in usr_ovrd.
                    394:                */
                    395: 
                    396:                if (userflag != NULL && sequal(userflag, field[UF_NAME]))
                    397:                {
                    398:                        smove(field[UF_UCODE], usr_ovrd);
                    399:                        userflag = NULL;
                    400:                }
                    401: 
                    402:                /* don't bother with this shit if not needed */
                    403:                if (Usercode != NULL)
                    404:                        continue;
                    405:                
                    406:                /*
                    407:                **  Build the user id of this entry into 'uid'
                    408:                **  and see if it is this user.
                    409:                */
                    410: 
                    411:                uid = atoi(field[UF_UID]);
                    412: 
                    413: #              ifdef xB_UNIX
                    414:                gid = atoi(field[UF_GID]);
                    415:                uid = (uid & 0377) | ((gid & 0377) << 8);
                    416: #              endif
                    417: 
                    418: #              ifdef xV6_UNIX
                    419:                if ((uid & 0377) != actualuid)
                    420:                        continue;
                    421: #              endif
                    422: #              ifndef xV6_UNIX
                    423:                if (uid != actualuid)
                    424:                        continue;
                    425: #              endif
                    426: 
                    427:                /*
                    428:                **  We now have the real user entry.
                    429:                **      Fetch the usercode, the status bits, and other
                    430:                **      fields from the users file, and save them in
                    431:                **      a safe place (sbuf).
                    432:                */
                    433: 
                    434:                Usercode = sbufp;
                    435:                sbufp += smove(field[UF_UCODE], sbufp) + 1;
                    436:                Status = oatoi(field[UF_STAT]);
                    437:                if (paramlist != NULL)
                    438:                {
                    439:                        for (i = 0; i < 4; i++)
                    440:                        {
                    441:                                paramlist[i] = sbufp;
                    442:                                sbufp += smove(field[UF_FLAGS + i], sbufp) + 1;
                    443:                        }
                    444:                }
                    445: 
                    446:                /* validate access permission */
                    447:                rtval = 0;
                    448:                if (!dbflag || (Status & U_SUPER) != 0)
                    449:                        continue;
                    450:                p = field[UF_DBLIST];
                    451:                if (*p == 0)
                    452:                        continue;
                    453: 
                    454:                /* select permission/no-permission */
                    455:                npermit = 0;
                    456:                if (*p == '-')
                    457:                {
                    458:                        p++;
                    459:                        npermit++;
                    460:                }
                    461: 
                    462:                /* scan for database listed */
                    463:                if (!npermit)
                    464:                        rtval = 2;
                    465:                for (c = *p; c != 0; p = q + 1)
                    466:                {
                    467:                        for (q = p; *q != ',' && *q != 0; q++)
                    468:                                continue;
                    469:                        c = *q;
                    470:                        *q = 0;
                    471:                        if (sequal(Parmvect[0], p))
                    472:                        {
                    473:                                rtval = npermit ? 2 : 0;
                    474:                                break;
                    475:                        }
                    476:                }
                    477:        }
                    478:        fclose(iop);
                    479: 
                    480:        if (rtval != 0)
                    481:                return (rtval);
                    482: 
                    483:        /*
                    484:        **  Check for existance of the database.  This is done by
                    485:        **      first building the pathname of the database into
                    486:        **      'Dbpath', and then reading the admin file (just
                    487:        **      the adhdr part).
                    488:        */
                    489: 
                    490:        if (dbflag)
                    491:        {
                    492:                Dbpath = sbufp;
                    493:                switch (i = initdbpath(Parmvect[0], Dbpath, TRUE))
                    494:                {
                    495:                  case 0:
                    496:                        rtval = 0;
                    497:                        break;
                    498: 
                    499:                  case 1:
                    500:                        rtval = 5;
                    501:                        break;
                    502: 
                    503:                  case 2:
                    504:                        rtval = 1;
                    505:                        break;
                    506: 
                    507:                  case 3:
                    508:                        rtval = 6;
                    509:                        break;
                    510: 
                    511:                  default:
                    512:                        syserr("initucode: initdbpath %d", i);
                    513:                }
                    514:                sbufp += length(Dbpath) + 1;
                    515: 
                    516:                if (rtval == 0 || rtval == 5)
                    517:                {
                    518:                        i = open(ztack(Dbpath, "/admin"), 0);
                    519:                        if (i < 0)
                    520:                                rtval += 1;
                    521:                        else
                    522:                        {
                    523:                                /* open and check admin file */
                    524:                                checkadmin(i);
                    525:                                close(i);
                    526:                        }
                    527:                }
                    528:        }
                    529: 
                    530:        /*
                    531:        **  Check to see if the name on the -u flag is valid, and
                    532:        **      that this user is allowed to use it.
                    533:        */
                    534: 
                    535:        if (userflag != NULL)
                    536:        {
                    537:                printf("Invalid user name %s\n", userflag);
                    538:                exit(-1);
                    539:        }
                    540:        if (usr_ovrd[0] != '\0')
                    541:        {
                    542:                if ((Status & U_SUPER) == 0)
                    543:                {
                    544:                        if (!dbflag || !bequal(Admin.adhdr.adowner, Usercode, 2))
                    545:                        {
                    546:                                printf("You may not use the -u flag\n");
                    547:                                exit(-1);
                    548:                        }
                    549:                }
                    550:                bmove(usr_ovrd, Usercode, 2);
                    551:        }
                    552: 
                    553:        /*
                    554:        **  Process the +-w flag.
                    555:        **      First, determine the locking mode.  If +w, always
                    556:        **      wait; if -w, never wait; if unspecified, wait if in
                    557:        **      background, but print error and exit if running
                    558:        **      interactive.
                    559:        */
                    560: 
                    561:        if (waitflag > 0 || (waitflag == 0 && gtty(0, &gttydummy) < 0))
                    562:                Wait_action = A_SLP;
                    563:        else
                    564:                Wait_action = A_RTN;
                    565:        if (dbflag && waitmode >= 0)
                    566:                db_lock(waitmode);
                    567:        
                    568:        /*
                    569:        **  Return authorization value.
                    570:        */
                    571: 
                    572:        return (rtval);
                    573: }
                    574: /*
                    575: **  DB_LOCK -- lock database
                    576: **
                    577: **     Locks the database.  Everyone should do this before using any
                    578: **     database.
                    579: **
                    580: **     Parameters:
                    581: **             database -- the pathname of the database.
                    582: **             mode -- M_EXCL -- get an exclusive lock.
                    583: **                     M_SHARE -- get a shared lock.
                    584: **
                    585: **     Returns:
                    586: **             none
                    587: **
                    588: **     Side Effects:
                    589: **             Alockdes is opened.
                    590: */
                    591: 
                    592: struct lockreq Lock;   /* the database lock structure */
                    593: 
                    594: db_lock(mode)
                    595: int    mode;
                    596: {
                    597:        if ((Admin.adhdr.adflags & A_DBCONCUR) == 0)
                    598:                return;
                    599:        if (Alockdes < 0)
                    600:                Alockdes = start_up_lock_driver();
                    601:        if (setdbl(Wait_action, mode) < 0)
                    602:        {
                    603:                printf("Database temporarily unavailable\n");
                    604:                exit(1);
                    605:        }
                    606: }
                    607: /*
                    608: **  INITDBPATH -- initialize the pathname of the database
                    609: **
                    610: **     The pathname of a specified database is created.  Indirection
                    611: **     via a file is supported, so that if the pathname is a file,
                    612: **     the first line of the file is read and used as the pathname
                    613: **     of the real database.
                    614: **
                    615: **     Parameters:
                    616: **             database -- the name of the database.  If NULL,
                    617: **                     the pathname of datadir is returned.
                    618: **             dbbuf -- a buffer into which the pathname should
                    619: **                     be dumped.
                    620: **             follow -- if set, follow the indirect chain of
                    621: **                     database pathnames.
                    622: **
                    623: **     Returns:
                    624: **             0 -- database exists in datadir
                    625: **             1 -- database exists, but I followed a pointer.
                    626: **             2 -- database doesn't exist in datadir.
                    627: **             3 -- databae doesn't exist, but I followed a pointer.
                    628: **
                    629: **     Side Effects:
                    630: **             none.
                    631: */
                    632: 
                    633: initdbpath(database, dbpath, follow)
                    634: char   *database;
                    635: char   *dbpath;
                    636: int    follow;
                    637: {
                    638:        struct stat     ibuf;
                    639:        register char   *d;
                    640:        register FILE   *f;
                    641:        register int    phase;
                    642:        int             retval;
                    643:        int             uid;
                    644:        extern char     *index();
                    645: 
                    646:        d = dbpath;
                    647: 
                    648:        if (database == NULL)
                    649:        {
                    650: # ifndef xDBPATH
                    651:                concat(Pathname, "/data/base/", d);
                    652: # else
                    653:                smove(xDBPATH, d);
                    654: # endif
                    655:                return (0);
                    656:        }
                    657: 
                    658:        /* get the basic pathname */
                    659:        concat(ztack(Pathname, "/datadir/"), database, d);
                    660: 
                    661:        /*
                    662:        ** Iterate looking for database.
                    663:        **      "Phase" is what we are trying:
                    664:        **         -1 -- looking in datadir
                    665:        **          0 -- looking in data/base
                    666:        **          1 -- following indirect.
                    667:        */
                    668: 
                    669:        retval = 2;
                    670:        for (phase = -1;;)
                    671:        {
                    672:                /* find out what sort of filesystem node this is */
                    673:                if (stat(d, &ibuf) < 0)
                    674:                {
                    675:                        if (phase < 0)
                    676:                        {
                    677: # ifdef xDBPATH
                    678:                                concat(xDBPATH, database, d);
                    679: # else
                    680:                                concat(ztack(Pathname, "/data/base/"), database, d);
                    681: # endif
                    682:                                phase = 0;
                    683:                                continue;
                    684:                        }
                    685:                        else
                    686:                                return (retval);
                    687:                }
                    688:                
                    689:                /* set up the lock structure for future use */
                    690:                bmove(&ibuf, Lock.dbnode, 4);
                    691: 
                    692:                retval -= 2;
                    693:                if ((ibuf.st_mode & S_IFMT) == S_IFDIR)
                    694:                        return (retval);
                    695:                
                    696:                /* if second time through, the database must be a directory */
                    697:                if (phase > 0)
                    698:                        syserr("initdbpath: not direc");
                    699:                
                    700:                /* if we shouldn't follow the chain, say it exists */
                    701:                if (!follow)
                    702:                        return (3);
                    703:                
                    704:                /* it's a file -- see if we can use it */
                    705:                uid = ibuf.st_uid;
                    706: #              ifdef xB_UNIX
                    707:                uid = (uid & 0377) | ((ibuf.st_gid & 0377) << 8);
                    708: #              endif
                    709: #              ifdef xV6_UNIX
                    710:                uid &= 0377;
                    711: #              endif
                    712:                if (uid != Ing_uid || (ibuf.st_mode & 0777) != 0600)
                    713:                        return (3);
                    714:                
                    715:                f = fopen(d, "r");
                    716:                if (f == NULL)
                    717:                        syserr("initdbpath: fopen");
                    718:        
                    719:                /* read the pathname of the database */
                    720:                if (fgets(d, MAXLINE, f) == NULL || d[0] != '/')
                    721:                        syserr("initdbpath: bad indirect");
                    722:                *index(d, '\n') = '\0';
                    723:                fclose(f);
                    724: 
                    725:                /* prepare for next iteration */
                    726:                retval = 3;
                    727:                phase = 1;
                    728:        }
                    729: }

unix.superglobalmegacorp.com

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