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

unix.superglobalmegacorp.com

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