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

Defined functions

initdbpath defined in line 671; used 4 times

Defined variables

Flagvect defined in line 198; used 2 times
Ing_uid defined in line 200; used 5 times
Lock defined in line 625; used 1 times
Parmvect defined in line 199; used 5 times
Rubignored defined in line 194; never used
Standalone defined in line 201; used 1 times
Wait_action defined in line 196; used 3 times

Defined macros

MAXFVECT defined in line 189; used 2 times
MAXPVECT defined in line 190; used 2 times
Last modified: 1995-02-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4587
Valid CSS Valid XHTML 1.0 Strict