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

1.1     ! root        1: %{
        !             2: 
        !             3: # include      <stdio.h>
        !             4: # include      <ctype.h>
        !             5: # include      <ingres.h>
        !             6: # include      <aux.h>
        !             7: # include      <version.h>
        !             8: # include      <access.h>
        !             9: # include      <lock.h>
        !            10: # include      <opsys.h>
        !            11: # include      <ctlmod.h>
        !            12: # include      <sccs.h>
        !            13: 
        !            14: 
        !            15: /*
        !            16: **  INGRES -- INGRES startup
        !            17: **
        !            18: **     This program starts up the entire system.
        !            19: **
        !            20: **     Parameters:
        !            21: **             1 -- database name
        !            22: **             2 -- optional process table name
        !            23: **             x -- flags of the form +x or -x may be freely inter-
        !            24: **                     sperced in the argument list.
        !            25: **
        !            26: **     Return:
        !            27: **             none if successful
        !            28: **             1 -- user error (no database, etc)
        !            29: **             -1 -- system error
        !            30: **
        !            31: **     Flags:
        !            32: **             -&xxxx -- EQUEL flag: xxxx are file descriptors for the
        !            33: **                     status return pipe, the command write pipe, the
        !            34: **                     data return pipe, and the data transfer pipe
        !            35: **                     respectively.
        !            36: **             -@xxxx -- xxxx is same as EQUEL flag, but no flags
        !            37: **                     are set.
        !            38: **             -*?? -- Masterid flag. Gives the siteid of the master
        !            39: **                     site in a distributed ingres. (Used in dist.
        !            40: **                     ingres' initproc() function.)
        !            41: **             -|xxxx -- Network flag.  This flag is just passed to
        !            42: **                     the other processes, to be processed by the
        !            43: **                     DBU's.
        !            44: **             -uusername -- set effective user to be username.  You
        !            45: **                     must be INGRES or the DBA for the database to
        !            46: **                     use this option.
        !            47: **             -cN -- set minimum character field output width to be
        !            48: **                     N, default 6.  This is the fewest number of
        !            49: **                     characters which may be output in any "c" type
        !            50: **                     field.
        !            51: **             -inN -- integer output width.  this is the width of
        !            52: **                     an integer field.  The small "n" is the size
        !            53: **                     of the internal field ("1", "2", or "4") and
        !            54: **                     N is the width of the field for that flag.
        !            55: **                     The defaults are -i16, -i26, and -i413.
        !            56: **             -fnxN.M -- floating point output width and precision.
        !            57: **                     Small "n" is the internal width in bytes ("4"
        !            58: **                     or "8"), x is the format (f, F, g, G, e, E,
        !            59: **                     n, or N), N is the field width, and M is the
        !            60: **                     precision (number of digits after the decimal
        !            61: **                     point).  The formats are:
        !            62: **                     "f" or "F": FORTRAN-style F format: digits,
        !            63: **                             decimal point, digits, no exponent.
        !            64: **                     "e" or "E": FORTRAN-style E format: digits,
        !            65: **                             decimal point, digits, letter "e" (or
        !            66: **                             "E", depending on "x" in the param-
        !            67: **                             eter), and an exponent.  The scaling
        !            68: **                             factor is always one, that is, there
        !            69: **                             is always one digit before the decimal
        !            70: **                             point.
        !            71: **                     "g" or "G": F format if it will fit in the
        !            72: **                             field, otherwise E format.  Space is
        !            73: **                             always left at the right of the field
        !            74: **                             for the exponent, so that decimal
        !            75: **                             points will align.
        !            76: **                     "n" or "N": like G, except that space is not
        !            77: **                             left for the decimal point in F style
        !            78: **                             format (useful if you expect everything
        !            79: **                             to fit, but you're not sure).
        !            80: **                     The default is -fn10.3.
        !            81: **             -vx -- set vertical seperator for print operations
        !            82: **                     and retrieves to the terminal to be "x".  The
        !            83: **                     default is vertical bar ("|").
        !            84: **             +w -- database wait state.  If set ("+w"), you will
        !            85: **                     wait until the database is not busy.  If clear,
        !            86: **                     you will be informed if the database is busy.
        !            87: **                     If not specified, the same operations take
        !            88: **                     place depending on whether or not you are
        !            89: **                     running in background (determined by whether
        !            90: **                     or not your input is a teletype).  If in fore-
        !            91: **                     ground, you are informed; if in background,
        !            92: **                     you wait.
        !            93: **             -M -- monitor trace flag
        !            94: **             -P -- parser trace flag
        !            95: **             -O -- ovqp trace flag
        !            96: **             -Q -- qrymod trace flag
        !            97: **             -D -- decomp trace flag
        !            98: **             -Z -- dbu trace flag.  These flags require the 020 bit
        !            99: **                     in the status field of the users file to be
        !           100: **                     set.  The syntax is loose and is described
        !           101: **                     elsewhere.  Briefly, "-Z" sets all flags except
        !           102: **                     the last 20, "-Z4" sets flag 4, and "-Z5/7"
        !           103: **                     sets all flags from 5 through 7.
        !           104: **             +L -- enable/disable upper to lower case mapping in the
        !           105: **                     parser.  Used for debugging.
        !           106: **             -rmode -- retrieve into mode
        !           107: **             -nmode -- index mode.  These flags give the default
        !           108: **                     modify mode for retrieve into and index.  They
        !           109: **                     default to cheapsort and isam.  "Mode" can be
        !           110: **                     any mode to modify except "truncated".
        !           111: **             +a -- enable/disable autoclear function in monitor.
        !           112: **                     Default on.
        !           113: **             +b -- enable/disable batch update.  Default on.
        !           114: **                     The 02 bit is needed to clear this flag.
        !           115: **             +d -- enable/disable printing of the dayfile.  Default
        !           116: **                     on.
        !           117: **             +s -- enable/disable printing of almost everything from
        !           118: **                     the monitor.
        !           119: **             +U -- enable/disable direct update of system catalogs.
        !           120: **                     Default off.  The 04 bit is needed to set this
        !           121: **                     option.
        !           122: **
        !           123: **     Files:
        !           124: **             .../files/usage -- to print a "usage: ..." message.
        !           125: **             .../data/base/<database>/admin -- to determine
        !           126: **                     existance and some info about <database>.
        !           127: **             .../files/dayfile<VERSION> -- dayfile (printed by
        !           128: **                     monitor).
        !           129: **             .../files/users -- file with UNIX uid -> INGRES code
        !           130: **                     mapping, plus a pile of other information about
        !           131: **                     the user.
        !           132: **             .../files/proctab<VERSION> -- default process table
        !           133: **
        !           134: **
        !           135: **     Note:
        !           136: **             this is also the startup program for sysmod.
        !           137: **             different flags are expected and the default process table
        !           138: **             is different from that of ingres.
        !           139: **
        !           140: */
        !           141: 
        !           142: SCCSID(@(#)ingres.y    8.4     12/18/85)
        !           143: 
        !           144: # define       MAXOPTNS        10              /* maximum number of options you can specify */
        !           145: # define       SYSMAXOPTNS     6               /* maximum number of options to sysmod */
        !           146: # define       MAXPROCS        10              /* maximum number of processes in the system */
        !           147: # define       EQUELFLAG       '&'
        !           148: # define       NETFLAG         '|'             /* network slave flag */
        !           149: # define       CLOSED          '?'
        !           150: 
        !           151: char           Fileset[10];
        !           152: char           *Database;
        !           153: extern char    *Dbpath;                /* defined in initucode */
        !           154: struct admin   Admin;                  /* set in initucode */
        !           155: struct lockreq Lock;
        !           156: FILE           *ProcFile;              /* fildes for the process table */
        !           157: char           *DefProcTab = NULL;     /* default process table name */
        !           158: char           *Opt[MAXOPTNS + 1];
        !           159: int            Nopts;
        !           160: int            No_exec;                /* if set, don't execute */
        !           161: int            NumProcs;               /* number of processes this system */
        !           162: 
        !           163: 
        !           164: /*
        !           165: **  Internal form of process descriptions.
        !           166: */
        !           167: 
        !           168: struct proc
        !           169: {
        !           170:        short           prstat;         /* status bits, see below */
        !           171:        char            prmpipe;        /* initial pipe to this process */
        !           172:        char            prtflag;        /* trace flag for CM this proc */
        !           173:        char            prpath[50];     /* pathname of this process */
        !           174:        struct _cm_t    prcm;           /* cm info passed to this proc */
        !           175: };
        !           176: 
        !           177: /* bits for prstat */
        !           178: # define PR_REALUID    0001            /* run as the user, not INGRES */
        !           179: # define PR_NOCHDIR    0002            /* don't chdir into database */
        !           180: # define PR_CLSSIN     0004            /* close standard input */
        !           181: # define PR_CLSDOUT    0010            /* close diagnostic output */
        !           182: 
        !           183: struct proc    ProcTab[CM_MAXPROC];
        !           184: 
        !           185: 
        !           186: /*
        !           187: **  Open pipe info.
        !           188: */
        !           189: 
        !           190: struct pipeinfo
        !           191: {
        !           192:        char    pip_rfd;        /* read file descriptor */
        !           193:        char    pip_wfd;        /* write file descriptor */
        !           194:        short   pip_rcnt;       /* read reference count */
        !           195:        short   pip_wcnt;       /* write reference count */
        !           196: };
        !           197: 
        !           198: struct pipeinfo Pipe[128];
        !           199: 
        !           200: 
        !           201: /*
        !           202: **  Macro definitions
        !           203: */
        !           204: 
        !           205: char   Macro[26][80];
        !           206: 
        !           207: 
        !           208: /* system error messages, etc. */
        !           209: extern int     sys_nerr;
        !           210: extern char    *sys_errlist[];
        !           211: extern int     errno;
        !           212: 
        !           213: /* globals used by the grammar. */
        !           214: struct proc    *Proc;
        !           215: state_t                *StateP;
        !           216: proc_t         *ProcP;
        !           217: int            ProcNo;
        !           218: int            RemStat;
        !           219: 
        !           220: 
        !           221: %}
        !           222: 
        !           223: %union
        !           224: {
        !           225:        int     yyint;          /* integer */
        !           226:        char    *yystr;         /* string */
        !           227:        char    yypip;          /* pipe id */
        !           228:        char    yychar;         /* single character */
        !           229: }
        !           230: 
        !           231: %token <yyint> INT
        !           232: %token <yystr> STR
        !           233: 
        !           234: %type  <yyint> procno stateno funcno
        !           235: %type  <yyint> flags
        !           236: %type  <yystr> pathname printname
        !           237: %type  <yypip> pipe_id
        !           238: %type  <yychar>macro_id tflag
        !           239: 
        !           240: %%
        !           241: 
        !           242: proctab:       spec_list
        !           243:        ;
        !           244: 
        !           245: spec_list:     spec
        !           246:        |       spec_list spec
        !           247:        ;
        !           248: 
        !           249: spec:          proc_line states
        !           250:        |       macro_defn
        !           251:        ;
        !           252: 
        !           253: /*
        !           254: **  Lines beginning with "P" introduce new processes.
        !           255: **
        !           256: **     procno is the number of the process being defined.
        !           257: **     pathname is the pathname of the executable object
        !           258: **             of this module.
        !           259: **     printname is the name to be used as "Procname" in
        !           260: **             this module for activities unconnected with
        !           261: **             particular modules.
        !           262: **     pipe_id is the pipe to use as the normal input for
        !           263: **             this process.  It must be listed as a pipe
        !           264: **             in at least one of the constituent state
        !           265: **             definitions.
        !           266: **     flags are flags associated with this process.  They
        !           267: **             are not actually passed to the process, but
        !           268: **             are used internally.  See the #defines after
        !           269: **             /^struct proc/.
        !           270: */
        !           271: 
        !           272: proc_line:     'P' procno pathname printname pipe_id flags tflag
        !           273:                {
        !           274:                        NumProcs++;
        !           275:                        Proc = &ProcTab[$2];
        !           276:                        smove($3, Proc->prpath);
        !           277:                        Proc->prmpipe = Proc->prcm.cm_input = Proc->prcm.cm_rinput
        !           278:                            = Proc->prcm.cm_proc[$2].pr_ninput = $5;
        !           279:                        smove($4, Proc->prcm.cm_myname);
        !           280:                        Proc->prcm.cm_myproc = $2;
        !           281:                        Proc->prstat = $6;
        !           282:                        Proc->prtflag = $7;
        !           283:                        Pipe[$5].pip_rcnt += 3;
        !           284:                        Pipe[$5].pip_wcnt++;
        !           285:                }
        !           286:        ;
        !           287: 
        !           288: states:                state_line
        !           289:        |       states state_line
        !           290:        ;
        !           291: 
        !           292: state_line:    local_line
        !           293:        |       remote_line
        !           294:        ;
        !           295: 
        !           296: local_line:    'L' stateno flags funcno stateno
        !           297:                {
        !           298:                        StateP = &Proc->prcm.cm_state[$2];
        !           299:                        StateP->st_type = ST_LOCAL;
        !           300:                        StateP->st_stat = $3;
        !           301:                        StateP->st_v.st_loc.st_funcno = $4;
        !           302:                        StateP->st_v.st_loc.st_next = $5;
        !           303:                }
        !           304:        ;
        !           305: 
        !           306: remote_line:   remote_header stateno_list
        !           307:        ;
        !           308: 
        !           309: remote_header: 'R' procno flags pipe_id pipe_id flags
        !           310:                {
        !           311:                        ProcNo = $2;
        !           312:                        ProcP = &Proc->prcm.cm_proc[ProcNo];
        !           313:                        RemStat = $3;
        !           314:                        ProcP->pr_file = $4;
        !           315:                        ProcP->pr_ninput = $5;
        !           316:                        ProcP->pr_stat = $6;
        !           317:                        Pipe[$4].pip_wcnt++;
        !           318:                        Pipe[$5].pip_rcnt++;
        !           319:                }
        !           320:        ;
        !           321: 
        !           322: stateno_list:          /* empty */
        !           323:        |       stateno_list remote_stateno
        !           324:        ;
        !           325: 
        !           326: remote_stateno:        stateno
        !           327:                {
        !           328:                        StateP = &Proc->prcm.cm_state[$1];
        !           329:                        StateP->st_type = ST_REMOT;
        !           330:                        StateP->st_stat = RemStat;
        !           331:                        StateP->st_v.st_rem.st_proc = ProcNo;
        !           332:                }
        !           333:        ;
        !           334: 
        !           335: /*
        !           336: **  Macro definitions.
        !           337: */
        !           338: 
        !           339: macro_defn:    'D' macro_id STR
        !           340:                {
        !           341:                        smove($3, Macro[$2 - 'A']);
        !           342:                }
        !           343: 
        !           344: /*
        !           345: **  Productions for things that perhaps ought to be in the scanner.
        !           346: */
        !           347: 
        !           348: procno:                INT
        !           349:                {
        !           350:                        if ($1 < 0 || $1 >= CM_MAXPROC)
        !           351:                        {
        !           352:                                usrerr("Illegal proc number %d", $1);
        !           353:                                YYERROR;
        !           354:                        }
        !           355:                }
        !           356:        ;
        !           357: 
        !           358: stateno:       INT
        !           359:                {
        !           360:                        if ($1 < 0 || $1 >= CM_MAXST)
        !           361:                        {
        !           362:                                usrerr("Illegal state number %d", $1);
        !           363:                                YYERROR;
        !           364:                        }
        !           365:                }
        !           366:        ;
        !           367: 
        !           368: funcno:                INT
        !           369:                {
        !           370:                        if ($1 < 0)
        !           371:                        {
        !           372:                                usrerr("Illegal funcno %d", $1);
        !           373:                                YYERROR;
        !           374:                        }
        !           375:                }
        !           376:        ;
        !           377: 
        !           378: pathname:      STR
        !           379:        ;
        !           380: 
        !           381: printname:     STR
        !           382:        ;
        !           383: 
        !           384: pipe_id:       STR
        !           385:                {
        !           386:                        if ((islower($1[0]) || $1[0] == CLOSED) && $1[1] == '\0')
        !           387:                                $$ = $1[0];
        !           388:                        else if ($1[0] == '|' && isdigit($1[1]) && $1[2] == '\0')
        !           389:                                $$ = $1[1];
        !           390:                        else
        !           391:                        {
        !           392:                                usrerr("Invalid pipe id \"%s\"", $1);
        !           393:                                YYERROR;
        !           394:                        }
        !           395:                }
        !           396:        ;
        !           397: 
        !           398: tflag:         STR
        !           399:                {
        !           400:                        if ($1[1] != '\0')
        !           401:                        {
        !           402:                                usrerr("Invalid trace flag \"%s\"", $1);
        !           403:                                YYERROR;
        !           404:                        }
        !           405:                        else
        !           406:                                $$ = $1[0];
        !           407:                }
        !           408:        ;
        !           409: 
        !           410: flags:         INT
        !           411:        ;
        !           412: 
        !           413: macro_id:      STR
        !           414:                {
        !           415:                        if ($1[0] < 'A' || $1[0] > 'Z' || $1[1] != '\0')
        !           416:                        {
        !           417:                                usrerr("Invalid macro name \"%s\"", $1);
        !           418:                                YYERROR;
        !           419:                        }
        !           420:                        else
        !           421:                                $$ = $1[0];
        !           422:                }
        !           423: 
        !           424: %%
        !           425: 
        !           426: main(argc, argv)
        !           427: int    argc;
        !           428: char   **argv;
        !           429: {
        !           430:        register int    i;
        !           431:        register int    j;
        !           432:        extern char     *Proc_name;
        !           433:        int             fd;
        !           434:        extern int      Status;
        !           435:        char            *proctab;
        !           436:        register char   *p;
        !           437:        char            *ptr;
        !           438:        extern char     *Flagvect[];    /* defined in initucode.c */
        !           439:        extern char     *Parmvect[];    /* ditto */
        !           440:        char            *uservect[4];
        !           441:        char            buf[MAXLINE+1];
        !           442:        char            str[MAXLINE+1]; /* a string to put the Alockdes value into */
        !           443:        char            str2[MAXLINE+1];
        !           444:        extern  int     Wait_action;    /* action on lock driver */
        !           445:        int             CallSysmod = FALSE;
        !           446:        struct proc     *pr;
        !           447:        int             len;
        !           448:        char            *sysptr;
        !           449: 
        !           450:        /*
        !           451:        ** sysmod is linked to ingres.
        !           452:        ** check whether ingres or sysmod was called.
        !           453:        */
        !           454:        len =  strlen(argv[0]);
        !           455:        sysptr = &argv[0][len - 6];
        !           456:        if (sequal( sysptr, "sysmod"))
        !           457:        {
        !           458:                CallSysmod = TRUE;
        !           459:                Proc_name = "SYSMOD";
        !           460:        }
        !           461:        else
        !           462:                Proc_name = "INGRES";
        !           463: 
        !           464: 
        !           465:        itoa(getpid(), Fileset);
        !           466:        proctab = NULL;
        !           467:        Database = NULL;
        !           468: 
        !           469:        /*
        !           470:        **  Initialize everything, like Flagvect, Parmvect, Usercode,
        !           471:        **      etc.
        !           472:        */
        !           473: 
        !           474:        for (i = 0; i < 128; i++)
        !           475:                Pipe[i].pip_rfd = Pipe[i].pip_wfd = -1;
        !           476: 
        !           477:        i = initucode(argc, argv, TRUE, uservect, CallSysmod?M_EXCL:-1);
        !           478:        switch (i)
        !           479:        {
        !           480:          case 0:       /* ok */
        !           481:          case INDIRECT:
        !           482:                break;
        !           483: 
        !           484:          case NODB:    /* database does not exist */
        !           485:          case INDNODB:
        !           486:                printf("Database %s does not exist\n", Parmvect[0]);
        !           487:                if (CallSysmod)
        !           488:                        goto sysusage;
        !           489:                else
        !           490:                        goto usage;
        !           491: 
        !           492:          case NOACCESS:        /* you are not authorized */
        !           493:                printf("You may not access database %s\n", Database);
        !           494:                if (CallSysmod)
        !           495:                        goto sysusage;
        !           496:                else
        !           497:                        goto usage;
        !           498: 
        !           499:          case INVALIDUSR:      /* not a valid user */
        !           500:                printf("You are not a valid INGRES user\n");
        !           501:                if (CallSysmod)
        !           502:                        goto sysusage;
        !           503:                else
        !           504:                        goto usage;
        !           505: 
        !           506:          case NODBNAME:        /* no database name specified */
        !           507:                printf("No database name specified\n");
        !           508:                if (CallSysmod)
        !           509:                        goto sysusage;
        !           510:                else
        !           511:                        goto usage;
        !           512: 
        !           513:          default:
        !           514:                syserr("initucode %d", i);
        !           515:        }
        !           516: 
        !           517:        /*
        !           518:        **  Extract database name and process table name from
        !           519:        **      parameter vector.
        !           520:        **  Initialize the $P macro.
        !           521:        */
        !           522: 
        !           523:        Database = Parmvect[0];
        !           524:        proctab = Parmvect[1];
        !           525:        smove(Pathname, Macro['P' - 'A']);
        !           526: 
        !           527:        if (!CallSysmod)
        !           528:        {
        !           529:                /* scan flags in users file */
        !           530:                for (p = uservect[0]; *p != '\0'; p++)
        !           531:                {
        !           532:                        /* skip initial blanks and tabs */
        !           533:                        if (*p == ' ' || *p == '\t')
        !           534:                                continue;
        !           535:                        ptr = p;
        !           536: 
        !           537:                        /* find end of flag and null-terminate it */
        !           538:                        while (*p != '\0' && *p != ' ' && *p != '\t')
        !           539:                        p++;
        !           540:                        i = *p;
        !           541:                        *p = '\0';
        !           542: 
        !           543:                        /* process the flag */
        !           544:                        doflag(ptr, 1);
        !           545:                        if (i == '\0')
        !           546:                                break;
        !           547:                }
        !           548: 
        !           549:                /* scan flags on command line */
        !           550:                for (i = 0; (p = Flagvect[i]) != NULL; i++)
        !           551:                        doflag(p, 0);
        !           552: 
        !           553:                /* check for query modification specified for this database */
        !           554:                if ((Admin.adhdr.adflags & A_QRYMOD) == 0)
        !           555:                        doflag("-q", -1);
        !           556:        }
        !           557:        /* special routine for handling sysmod flags */
        !           558:        else            
        !           559:        {
        !           560:                DefProcTab = "=sysmod";
        !           561:                if ( Flagvect[0] == NULL)
        !           562:                {
        !           563:                        if (!bequal(Usercode, Admin.adhdr.adowner, UCODE_SZ))
        !           564:                        {
        !           565:                                printf("You are not the dba for %s\n", Database);
        !           566:                                No_exec++;
        !           567:                        }
        !           568:                }
        !           569:                for (i = 0; (p = Flagvect[i]) != NULL; i++)
        !           570:                        sysflag(p);
        !           571:        }
        !           572: 
        !           573: 
        !           574:        /* close any extraneous files, being careful not to close anything we need */
        !           575:        for (i = 3; i < NOFILE; i++)
        !           576:        {
        !           577:                for (j = '0'; j <= '9'; j++)
        !           578:                {
        !           579:                        if (Pipe[j].pip_wfd == i || Pipe[j].pip_rfd == i)
        !           580:                                break;
        !           581:                }
        !           582:                if (j > '9')
        !           583:                        close(i);
        !           584:        }
        !           585: 
        !           586:        /* determine process table */
        !           587:        if (proctab == NULL)
        !           588:        {
        !           589:                /* use default proctab */
        !           590:                if (DefProcTab == NULL)
        !           591:                {
        !           592:                        if (argv[0][length(argv[0]) - 1] == 'x')
        !           593:                                DefProcTab = "=procx";
        !           594:                        else
        !           595:                                DefProcTab = "=proctab";
        !           596:                        proctab = uservect[1];
        !           597:                }
        !           598:                if (proctab == NULL || proctab[0] == 0)
        !           599:                {
        !           600:                        /* no proctab in users file */
        !           601:                        concat(DefProcTab, VERSION, buf);
        !           602:                        proctab = buf;
        !           603:                }
        !           604:        }
        !           605:        else
        !           606:        {
        !           607:                /* proctab specified; check permissions */
        !           608:                if ((Status & (proctab[0] == '=' ? U_EPROCTAB : U_APROCTAB)) == 0)
        !           609:                {
        !           610:                        printf("You may not specify this process table\n");
        !           611:                        if (CallSysmod)
        !           612:                                goto sysusage;
        !           613:                        else
        !           614:                                goto usage;
        !           615:                }
        !           616:        }
        !           617: 
        !           618:        /* expand process table name */
        !           619:        if (proctab[0] == '=')
        !           620:        {
        !           621:                smove(ztack(ztack(Pathname, "/files/"), &proctab[1]), buf);
        !           622:                proctab = buf;
        !           623:        }
        !           624: 
        !           625:        /* open and read the process table */
        !           626:        if ((ProcFile = fopen(proctab, "r")) == NULL)
        !           627:        {
        !           628:                printf("Proctab %s: %s\n", proctab, sys_errlist[errno]);
        !           629:                if (CallSysmod)
        !           630:                        goto sysusage;
        !           631:                else
        !           632:                        goto usage;
        !           633:        }
        !           634: 
        !           635:        /* build internal form of the process table */
        !           636:        if (yyparse())
        !           637:                No_exec++;
        !           638: 
        !           639:        /* don't bother executing if we have found errors */
        !           640:        if (No_exec)
        !           641:        {
        !           642:                if (!CallSysmod)
        !           643:                {
        !           644:                usage:
        !           645:                        /* cat .../files/usage */
        !           646:                        cat(ztack(Pathname, "/files/usage"));
        !           647:                        exit(1);
        !           648:                }
        !           649:                else
        !           650:                {
        !           651:                sysusage:
        !           652:                        cat(ztack(Pathname, "/files/sysusage"));
        !           653:                        exit(1);
        !           654:                }
        !           655:        }
        !           656: 
        !           657:        fclose(ProcFile);
        !           658: 
        !           659:        /* set locks on the database */
        !           660:        if (!CallSysmod) {
        !           661:                dolocks();
        !           662:                if ( Alockdes >= 0 )
        !           663:                {
        !           664:                        sprintf(str,"-l%d",(flagval('E') >0 ?M_EXCL : M_SHARE));
        !           665:                        doflag(str,-1);
        !           666:                        sprintf(str2,"-W%d",Wait_action);
        !           667:                        doflag(str2,-1);
        !           668:                        close(Alockdes);
        !           669:                }
        !           670:        }
        !           671: 
        !           672:        /* satisfy process table (never returns) */
        !           673:                satisfypt(CallSysmod);
        !           674: }
        !           675: 
        !           676: 
        !           677: 
        !           678: /*
        !           679: **  Process rubouts (just exit)
        !           680: */
        !           681: 
        !           682: rubproc()
        !           683: {
        !           684:        exit(2);
        !           685: }
        !           686: /*
        !           687: **  DOFLAG -- process flag
        !           688: **
        !           689: **     Parameters:
        !           690: **             flag -- the flag (as a string)
        !           691: **             where -- where it is called from
        !           692: **                     -1 -- internally inserted
        !           693: **                     0 -- on user command line
        !           694: **                     1 -- from users file
        !           695: **
        !           696: **     Return:
        !           697: **             none
        !           698: **
        !           699: **     Side effects:
        !           700: **             All flags are inserted on the end of the
        !           701: **             "Flaglist" vector for passing to the processes.
        !           702: **             The "No_exec" flag is set if the flag is bad or you
        !           703: **             are not authorized to use it.
        !           704: **
        !           705: **     Requires:
        !           706: **             Status -- to get the status bits set for this user.
        !           707: **             syserr -- for the obvious
        !           708: **             printf -- to print errors
        !           709: **             atoi -- to check syntax on numerically-valued flags
        !           710: **
        !           711: **     Defines:
        !           712: **             doflag()
        !           713: **             Flagok -- a list of legal flags and attributes (for
        !           714: **                     local use only).
        !           715: **             Relmode -- a list of legal relation modes.
        !           716: **
        !           717: **     Called by:
        !           718: **             main
        !           719: **
        !           720: **     History:
        !           721: **             11/6/79 (6.2/8) (eric) -- -u flag processing dropped,
        !           722: **                     since initucode does it anyhow.  -E flag
        !           723: **                     removed (what is it?).  F_USER code dropped.
        !           724: **                     F_DROP is still around; we may need it some-
        !           725: **                     day.  Also, test of U_SUPER flag and/or DBA
        !           726: **                     status was wrong.
        !           727: **             7/5/78 (eric) -- NETFLAG added to list.
        !           728: **             3/27/78 (eric) -- EQUELFLAG added to the list.
        !           729: **             1/29/78 -- do_u_flag broken off by eric
        !           730: **             1/4/78 -- written by eric
        !           731: */
        !           732: 
        !           733: struct flag
        !           734: {
        !           735:        char    flagname;       /* name of the flag */
        !           736:        char    flagstat;       /* status of flag (see below) */
        !           737:        int     flagsyntx;      /* syntax code for this flag */
        !           738:        int     flagperm;       /* status bits needed to use this flag */
        !           739:        char    *flagpt;        /* default proctab to use with this flag */
        !           740: };
        !           741: 
        !           742: /* status bits for flag */
        !           743: # define       F_PLOK          01      /* allow +x form */
        !           744: # define       F_PLD           02      /* defaults to +x */
        !           745: # define       F_DBA           04      /* must be the DBA to use */
        !           746: # define       F_DROP          010     /* don't save in Flaglist */
        !           747: 
        !           748: /* syntax codes */
        !           749: # define       F_ACCPT         1       /* always accept */
        !           750: # define       F_C_SPEC        3       /* -cN spec */
        !           751: # define       F_I_SPEC        4       /* -inN spec */
        !           752: # define       F_F_SPEC        5       /* -fnxN.M spec */
        !           753: # define       F_CHAR          6       /* single character */
        !           754: # define       F_MODE          7       /* a modify mode */
        !           755: # define       F_INTERNAL      8       /* internal flag, e.g., -q */
        !           756: # define       F_EQUEL         9       /* EQUEL flag */
        !           757: 
        !           758: struct flag    Flagok[] =
        !           759: {
        !           760:        'a',    F_PLD|F_PLOK,   F_ACCPT,        0,              NULL,
        !           761:        'b',    F_PLD|F_PLOK,   F_ACCPT,        U_DRCTUPDT,     NULL,
        !           762:        'c',    0,              F_C_SPEC,       0,              NULL,
        !           763:        'd',    F_PLD|F_PLOK,   F_ACCPT,        0,              NULL,
        !           764:        'f',    0,              F_F_SPEC,       0,              NULL,
        !           765:        'i',    0,              F_I_SPEC,       0,              NULL,
        !           766:        'l',    F_PLOK,         F_INTERNAL,     0,              NULL,
        !           767:        'n',    0,              F_MODE,         0,              NULL,
        !           768:        'q',    F_PLD|F_PLOK,   F_INTERNAL,     0,              NULL,
        !           769:        'r',    0,              F_MODE,         0,              NULL,
        !           770:        's',    F_PLD|F_PLOK,   F_ACCPT,        0,              NULL,
        !           771:        'v',    0,              F_CHAR,         0,              NULL,
        !           772:        'w',    F_PLOK|F_DROP,  F_ACCPT,        0,              NULL,
        !           773:        'D',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           774:        'L',    F_PLOK,         F_ACCPT,        0,              NULL,
        !           775:        'M',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           776:        'O',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           777:        'P',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           778:        'Q',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           779:        'T',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           780:        'U',    F_PLOK,         F_ACCPT,        U_UPSYSCAT,     NULL,
        !           781:        'W',    0,              F_INTERNAL,     0,              NULL,
        !           782:        'Z',    0,              F_ACCPT,        U_TRACE,        NULL,
        !           783:        EQUELFLAG, 0,           F_EQUEL,        0,              "=equel",
        !           784:        NETFLAG, 0,             F_EQUEL,        0,              "=slave",
        !           785:        '@',    0,              F_EQUEL,        0,              NULL,
        !           786:        '*',    0,              F_ACCPT,        0,              NULL,
        !           787:        0,      0,              0,              0,              NULL,
        !           788: };
        !           789: 
        !           790: /* list of valid retrieve into or index modes */
        !           791: char   *Relmode[] =
        !           792: {
        !           793:        "isam",
        !           794:        "cisam",
        !           795:        "hash",
        !           796:        "chash",
        !           797:        "heap",
        !           798:        "cheap",
        !           799:        "heapsort",
        !           800:        "cheapsort",
        !           801:        NULL
        !           802: };
        !           803: 
        !           804: 
        !           805: doflag(flag, where)
        !           806: char   *flag;
        !           807: int    where;
        !           808: {
        !           809:        register char           *p;
        !           810:        register struct flag    *f;
        !           811:        auto int                intxx;
        !           812:        register char           *ptr;
        !           813:        int                     i;
        !           814:        int                     j;
        !           815:        extern int              Status;
        !           816: 
        !           817:        p = flag;
        !           818: 
        !           819:        /* check for valid flag format (begin with + or -) */
        !           820:        if (p[0] != '+' && p[0] != '-')
        !           821:                goto badflag;
        !           822: 
        !           823:        /* check for flag in table */
        !           824:        for (f = Flagok; f->flagname != p[1]; f++)
        !           825:        {
        !           826:                if (f->flagname == 0)
        !           827:                        goto badflag;
        !           828:        }
        !           829: 
        !           830:        /* check for +x form allowed */
        !           831:        if (p[0] == '+' && (f->flagstat & F_PLOK) == 0)
        !           832:                goto badflag;
        !           833: 
        !           834:        /* check for permission to use the flag */
        !           835:        if ((f->flagperm != 0 && (Status & f->flagperm) == 0 &&
        !           836:             (((f->flagstat & F_PLD) == 0) ? (p[0] == '+') : (p[0] == '-'))) ||
        !           837:            ((f->flagstat & F_DBA) != 0 && (Status & U_SUPER) == 0 &&
        !           838:             !bequal(Usercode, Admin.adhdr.adowner, UCODE_SZ)))
        !           839:        {
        !           840:                printf("You are not authorized to use the %s flag\n", p);
        !           841:                No_exec++;
        !           842:        }
        !           843: 
        !           844:        /* check syntax */
        !           845:        switch (f->flagsyntx)
        !           846:        {
        !           847:          case F_ACCPT:
        !           848:                break;
        !           849: 
        !           850:          case F_C_SPEC:
        !           851:                if ((intxx = atoi(&p[2])) > MAXFIELD)
        !           852:                        goto badflag;
        !           853:                break;
        !           854: 
        !           855:          case F_I_SPEC:
        !           856:                if (p[2] != '1' && p[2] != '2' && p[2] != '4')
        !           857:                        goto badflag;
        !           858:                if ((intxx = atoi(&p[3])) > MAXFIELD)
        !           859:                        goto badflag;
        !           860:                break;
        !           861: 
        !           862:          case F_F_SPEC:
        !           863:                if (p[2] != '4' && p[2] != '8')
        !           864:                        goto badflag;
        !           865:                switch (p[3])
        !           866:                {
        !           867:                  case 'e':
        !           868:                  case 'E':
        !           869:                  case 'f':
        !           870:                  case 'F':
        !           871:                  case 'g':
        !           872:                  case 'G':
        !           873:                  case 'n':
        !           874:                  case 'N':
        !           875:                        break;
        !           876: 
        !           877:                  default:
        !           878:                        goto badflag;
        !           879: 
        !           880:                }
        !           881:                ptr = &p[4];
        !           882:                while (*ptr != '.')
        !           883:                        if (*ptr == 0)
        !           884:                                goto badflag;
        !           885:                        else
        !           886:                                ptr++;
        !           887:                *ptr = 0;
        !           888:                if ((intxx = atoi(&p[4])) > MAXFIELD)
        !           889:                        goto badflag;
        !           890:                *ptr++ = '.';
        !           891:                if ((intxx = atoi(ptr)) > MAXFIELD)
        !           892:                        goto badflag;
        !           893:                break;
        !           894: 
        !           895:          case F_CHAR:
        !           896:                if (p[2] == 0 || p[3] != 0)
        !           897:                        goto badflag;
        !           898:                break;
        !           899: 
        !           900:          case F_MODE:
        !           901:                for (i = 0; (ptr = Relmode[i]) != NULL; i++)
        !           902:                {
        !           903:                        if (sequal(&p[2], ptr))
        !           904:                                break;
        !           905:                }
        !           906:                if (ptr == NULL)
        !           907:                        goto badflag;
        !           908:                break;
        !           909: 
        !           910:          case F_INTERNAL:
        !           911:                if (where >= 0)
        !           912:                        goto badflag;
        !           913:                break;
        !           914: 
        !           915:          case F_EQUEL:
        !           916:                ptr = &p[2];
        !           917:                for (i = 0; i < 20; i++, ptr++)
        !           918:                {
        !           919:                        if (*ptr == CLOSED)
        !           920:                                continue;
        !           921:                        if (*ptr < 0100 || *ptr >= 0100 + NOFILE)
        !           922:                                break;
        !           923:                        j = (i / 2) + '0';
        !           924:                        if ((i & 01) == 0)
        !           925:                        {
        !           926:                                Pipe[j].pip_rfd = *ptr & 077;
        !           927:                        }
        !           928:                        else
        !           929:                        {
        !           930:                                Pipe[j].pip_wfd = *ptr & 077;
        !           931:                        }
        !           932:                }
        !           933:                break;
        !           934: 
        !           935:          default:
        !           936:                syserr("doflag: syntx %d", f->flagsyntx);
        !           937: 
        !           938:        }
        !           939: 
        !           940:        /* save flag */
        !           941:        if (Nopts >= MAXOPTNS)
        !           942:        {
        !           943:                printf("Too many options to INGRES\n");
        !           944:                exit(1);
        !           945:        }
        !           946:        if ((f->flagstat & F_DROP) == 0)
        !           947:                Opt[Nopts++] = p;
        !           948: 
        !           949:        /* change to new process table as appropriate */
        !           950:        if (f->flagpt != NULL)
        !           951:                DefProcTab = f->flagpt;
        !           952: 
        !           953:        return;
        !           954: 
        !           955:   badflag:
        !           956:        printf("Bad flag format: %s\n", p);
        !           957:        No_exec++;
        !           958:        return;
        !           959: }
        !           960: /*
        !           961: **  DOLOCKS -- set database lock
        !           962: **
        !           963: **     A lock is set on the database.
        !           964: */
        !           965: 
        !           966: dolocks()
        !           967: {
        !           968:        db_lock(flagval('E') > 0 ? M_EXCL : M_SHARE);
        !           969: }
        !           970: /*
        !           971: **  FLAGVAL -- return value of flag
        !           972: **
        !           973: **     Parameter:
        !           974: **             flag -- the name of the flag
        !           975: **
        !           976: **     Return:
        !           977: **             -1 -- flag is de-asserted (-x)
        !           978: **             0 -- flag is not specified
        !           979: **             1 -- flag is asserted (+x)
        !           980: **
        !           981: **     Requires:
        !           982: **             Opt -- to scan the flags
        !           983: **
        !           984: **     Defines:
        !           985: **             flagval
        !           986: **
        !           987: **     Called by:
        !           988: **             buildint
        !           989: **             dolocks
        !           990: **
        !           991: **     History:
        !           992: **             3/27/78 (eric) -- changed to handle EQUEL flag
        !           993: **                     normally.
        !           994: **             1/4/78 -- written by eric
        !           995: */
        !           996: 
        !           997: flagval(flag)
        !           998: char   flag;
        !           999: {
        !          1000:        register char   f;
        !          1001:        register char   **p;
        !          1002:        register char   *o;
        !          1003: 
        !          1004:        f = flag;
        !          1005: 
        !          1006:        /* start scanning option list */
        !          1007:        for (p = Opt; (o = *p) != 0; p++)
        !          1008:        {
        !          1009:                if (o[1] == f)
        !          1010:                        if (o[0] == '+')
        !          1011:                                return (1);
        !          1012:                        else
        !          1013:                                return (-1);
        !          1014:        }
        !          1015:        return (0);
        !          1016: }
        !          1017: /*
        !          1018: **  SATISFYPT -- satisfy the process table
        !          1019: **
        !          1020: **     Well folks, now that you've read this far, this is it!!!  I
        !          1021: **     mean, this one really does it!!!  It takes the internal form
        !          1022: **     built by the parser and creates pipes as necessary, forks, and
        !          1023: **     execs the INGRES processes.  Isn't that neat?
        !          1024: **
        !          1025: **     Parameters:
        !          1026: **             none
        !          1027: **
        !          1028: **     Returns:
        !          1029: **             never
        !          1030: **
        !          1031: **     Requires:
        !          1032: **             Proctab -- the internal form
        !          1033: **             ingexec -- to actually exec the process
        !          1034: **             pipe -- to create the pipe
        !          1035: **             syserr -- for the obvious
        !          1036: **             fillpipe -- to extend a newly opened pipe through all
        !          1037: **                     further references to it.
        !          1038: **             checkpipes -- to see if a given pipe will ever be
        !          1039: **                     referenced again.
        !          1040: **             fork -- to create a new process
        !          1041: **
        !          1042: **     Defines:
        !          1043: **             satisfypt
        !          1044: **
        !          1045: **     Called by:
        !          1046: **             main
        !          1047: **
        !          1048: **     History:
        !          1049: **             3/14/80 (eric) -- changed for version 7.0.
        !          1050: **             7/24/78 (eric) -- Actual file descriptors stored in
        !          1051: **                     'prpipes' are changed to have the 0100 bit
        !          1052: **                     set internally (as well as externally), so
        !          1053: **                     fd 0 will work correctly.
        !          1054: **             1/4/78 -- written by eric
        !          1055: */
        !          1056: 
        !          1057: 
        !          1058: 
        !          1059: satisfypt(callsysmod)
        !          1060: int    callsysmod;
        !          1061: {
        !          1062:        register struct proc    *pr;
        !          1063:        register proc_t         *pp;
        !          1064:        register int            i;
        !          1065:        int                     procno;
        !          1066:        register int            pip;
        !          1067: 
        !          1068:        /* scan the process table */
        !          1069:        for (procno = CM_MAXPROC - 1; procno >= 0; procno--)
        !          1070:        {
        !          1071: 
        !          1072:                pr = &ProcTab[procno];
        !          1073:                if (pr->prpath[0] == '\0')
        !          1074:                        continue;
        !          1075: 
        !          1076:                /* scan pipe vector, creating new pipes as needed */
        !          1077:                pipeopen(pr->prmpipe, TRUE);
        !          1078:                pipeopen(pr->prcm.cm_input, FALSE);
        !          1079:                pipeopen(pr->prcm.cm_rinput, FALSE);
        !          1080:                for (i = 0; i < CM_MAXPROC; i++)
        !          1081:                {
        !          1082:                        pp = &pr->prcm.cm_proc[i];
        !          1083:                        pipeopen(pp->pr_file, TRUE);
        !          1084:                        pipeopen(pp->pr_ninput, FALSE);
        !          1085:                }
        !          1086: 
        !          1087:                /* substitute real file descriptors throughout */
        !          1088:                pipexlat(&pr->prmpipe, TRUE);
        !          1089:                pipexlat(&pr->prcm.cm_input, FALSE);
        !          1090:                pipexlat(&pr->prcm.cm_rinput, FALSE);
        !          1091:                for (i = 0; i < CM_MAXPROC; i++)
        !          1092:                {
        !          1093:                        pp = &pr->prcm.cm_proc[i];
        !          1094:                        pipexlat(&pp->pr_file, TRUE);
        !          1095:                        pipexlat(&pp->pr_ninput, FALSE);
        !          1096:                }
        !          1097: 
        !          1098:                /* fork if necessary */
        !          1099:                if (--NumProcs <= 0  || (i = fork()) == 0 )
        !          1100:                {
        !          1101:                        /* child!! */
        !          1102:                        ingexec(procno);
        !          1103:                }
        !          1104: 
        !          1105:                /* parent */
        !          1106:                if (i < 0)
        !          1107:                        syserr("satisfypt: fork");
        !          1108: 
        !          1109:                /* scan pipes.  close all not used in the future */
        !          1110:                for (i = 0; i < 128; i++)
        !          1111:                {
        !          1112:                        if (i == CLOSED)
        !          1113:                                continue;
        !          1114:                        if (Pipe[i].pip_rcnt <= 0 && Pipe[i].pip_rfd >= 0)
        !          1115:                        {
        !          1116:                                if (close(Pipe[i].pip_rfd) < 0)
        !          1117:                                        syserr("satisfypt: close-r(%d)", Pipe[i].pip_rfd);
        !          1118:                                Pipe[i].pip_rfd = -1;
        !          1119:                        }
        !          1120:                        if (Pipe[i].pip_wcnt <= 0 && Pipe[i].pip_wfd >= 0)
        !          1121:                        {
        !          1122:                                if (close(Pipe[i].pip_wfd) < 0)
        !          1123:                                        syserr("satisfypt: close-w(%d)", Pipe[i].pip_wfd);
        !          1124:                                Pipe[i].pip_wfd = -1;
        !          1125:                        }
        !          1126:                }
        !          1127:        }
        !          1128:        syserr("satisfypt: fell out");
        !          1129: }
        !          1130: 
        !          1131: 
        !          1132: /*
        !          1133: **  SYSFLAG -- process flags for sysmod
        !          1134: **
        !          1135: **     Parameters:
        !          1136: **             flag -- the flag (as a string)
        !          1137: **             may be one of: -s, -S, -T? 
        !          1138: **
        !          1139: **     Return:
        !          1140: **             none
        !          1141: **
        !          1142: **     Side effects:
        !          1143: **             All flags are inserted on the end of the
        !          1144: **             "Flaglist" vector for passing to the processes.
        !          1145: **             The "No_exec" flag is set if the flag is bad or you
        !          1146: **             are not authorized to use it.
        !          1147: **
        !          1148: **     Called by:
        !          1149: **             main
        !          1150: **
        !          1151: */
        !          1152: 
        !          1153: sysflag(flag)
        !          1154: char   *flag;
        !          1155: {
        !          1156:        register char   *p;
        !          1157: 
        !          1158:        p = flag;
        !          1159: 
        !          1160:        if (p[0] != '-')
        !          1161:                goto sysbadflag;
        !          1162: 
        !          1163:        switch (p[1])
        !          1164:        {
        !          1165:          case 's':
        !          1166:                if ((Status & U_SUPER) == 0)
        !          1167:                {
        !          1168:                        printf("Only INGRES can use the -s flag\n");
        !          1169:                        No_exec++;
        !          1170:                        return;
        !          1171:                }
        !          1172:                bmove(Admin.adhdr.adowner, Usercode, UCODE_SZ);
        !          1173:                return(0);
        !          1174:                break;
        !          1175: 
        !          1176:          case 'R':
        !          1177:          case 'S':
        !          1178:                break;
        !          1179:        
        !          1180:          default:
        !          1181:                goto sysbadflag;
        !          1182:        }
        !          1183: 
        !          1184:        if (!bequal(Usercode, Admin.adhdr.adowner, UCODE_SZ))
        !          1185:        {
        !          1186:                printf("You are not the dba for %s\n", Database);
        !          1187:                No_exec++;
        !          1188:                return;
        !          1189:        }
        !          1190: 
        !          1191: 
        !          1192:        /* save flag */
        !          1193:        if (Nopts >= SYSMAXOPTNS)
        !          1194:        {
        !          1195:                printf("Too many options to SYSMOD\n");
        !          1196:                exit(1);
        !          1197:        }
        !          1198: 
        !          1199:        Opt[Nopts++] = p;
        !          1200: 
        !          1201: 
        !          1202:        return(0);
        !          1203: 
        !          1204: 
        !          1205:     sysbadflag:
        !          1206:        printf("Sysmod: bad flag format: %s \n", p);
        !          1207:        No_exec++;
        !          1208:        return;
        !          1209: 
        !          1210: }
        !          1211: 
        !          1212: /*
        !          1213: **  PIPEOPEN -- open pipe if necessary.
        !          1214: */
        !          1215: 
        !          1216: pipeopen(pipid, rw)
        !          1217:        char pipid;
        !          1218:        int rw;
        !          1219: {
        !          1220:        register struct pipeinfo *pi;
        !          1221:        int pipex[2];
        !          1222: 
        !          1223:        if (pipid == '\0')
        !          1224:                return;
        !          1225: 
        !          1226:        pi = &Pipe[pipid];
        !          1227: 
        !          1228:        if ((rw ? pi->pip_wfd : pi->pip_rfd) >= 0)
        !          1229:                return;
        !          1230:        if (pi->pip_rfd >= 0 || pi->pip_wfd >= 0)
        !          1231:                syserr("pipeopen %o %d: rfd=%d, wfd=%d", pipid, rw, pi->pip_rfd, pi->pip_wfd);
        !          1232:        if (pipid == CLOSED)
        !          1233:                pi->pip_rfd = pi->pip_wfd = CLOSED;
        !          1234:        else
        !          1235:        {
        !          1236:                if (pipe(pipex) < 0)
        !          1237:                        syserr("pipeopen: pipe");
        !          1238:                pi->pip_rfd = pipex[0];
        !          1239:                pi->pip_wfd = pipex[1];
        !          1240:        }
        !          1241: }
        !          1242: /*
        !          1243: **  CHECKPIPES -- check for pipe referenced in the future
        !          1244: **
        !          1245: **     Parameters:
        !          1246: **             proc -- point in the process table to start looking
        !          1247: **                     from.
        !          1248: **             fd -- the file descriptor to look for.
        !          1249: **
        !          1250: **     Return:
        !          1251: **             zero -- it will be referenced in the future.
        !          1252: **             one -- it is never again referenced.
        !          1253: **
        !          1254: **     Requires:
        !          1255: **             nothing
        !          1256: **
        !          1257: **     Defines:
        !          1258: **             checkpipes
        !          1259: **
        !          1260: **     Called by:
        !          1261: **             satisfypt
        !          1262: **
        !          1263: **     History:
        !          1264: **             7/24/78 (eric) -- 0100 bit on file descriptors handled.
        !          1265: **             1/4/78 -- written by eric
        !          1266: */
        !          1267: 
        !          1268: checkpipes(proc, fd)
        !          1269: struct proc    *proc;
        !          1270: register int   fd;
        !          1271: {
        !          1272:        register struct proc    *pr;
        !          1273:        register proc_t         *pp;
        !          1274:        register int            i;
        !          1275: 
        !          1276:        for (pr = proc; pr < &ProcTab[CM_MAXPROC]; pr++)
        !          1277:        {
        !          1278:                if (pr->prpath[0] == '\0')
        !          1279:                        continue;
        !          1280:                for (i = 0; i < CM_MAXPROC; i++)
        !          1281:                {
        !          1282:                        pp = &pr->prcm.cm_proc[i];
        !          1283:                        if (pp->pr_file == fd || pp->pr_ninput == fd)
        !          1284:                                return (0);
        !          1285:                }
        !          1286:        }
        !          1287:        return (1);
        !          1288: }
        !          1289: /*
        !          1290: **  INGEXEC -- execute INGRES process
        !          1291: **
        !          1292: **     This routine handles all the setup of the argument vector
        !          1293: **     and then executes a process.
        !          1294: **
        !          1295: **     Parameters:
        !          1296: **             process -- a pointer to the process table entry which
        !          1297: **                     describes this process.
        !          1298: **
        !          1299: **     Returns:
        !          1300: **             never
        !          1301: **
        !          1302: **     Side Effects:
        !          1303: **             never returns, but starts up a new overlay.  Notice
        !          1304: **                     that it does NOT fork.
        !          1305: **
        !          1306: **     Requires:
        !          1307: **             none
        !          1308: **
        !          1309: **     Called By:
        !          1310: **             satisfypt
        !          1311: **
        !          1312: **     Trace Flags:
        !          1313: **             none
        !          1314: **
        !          1315: **     Diagnostics:
        !          1316: **             none
        !          1317: **
        !          1318: **     Syserrs:
        !          1319: **             chdir %s -- could not change directory into the data-
        !          1320: **                     base.
        !          1321: **             creat %s -- could not create the redirected standard
        !          1322: **                     output file.
        !          1323: **             %s not executable -- could not execute the process.
        !          1324: **
        !          1325: **     History:
        !          1326: **             8/9/78 (eric) -- changed "prparam" to be a colon-
        !          1327: **                     separated list of parameters (so the number
        !          1328: **                     is variable); also, moved parameter expansion
        !          1329: **                     into this routine from buildint() so that
        !          1330: **                     the colons in the dbu part of the proctab
        !          1331: **                     would not confuse things.
        !          1332: **             7/24/78 (eric) -- changed the technique of closing
        !          1333: **                     files 0 & 2 so that they will never be closed
        !          1334: **                     (even if requested in the status field)
        !          1335: **                     if they are mentioned in the pipe vector.
        !          1336: **                     Also, some fiddling is done to handle the
        !          1337: **                     0100 bit on file descriptors correctly.
        !          1338: */
        !          1339: 
        !          1340: ingexec(procno)
        !          1341:        int procno;
        !          1342: {
        !          1343:        char                    *vect[30];
        !          1344:        register char           **v;
        !          1345:        char                    **opt;
        !          1346:        int                     i;
        !          1347:        register struct proc    *pr;
        !          1348:        register proc_t         *pp;
        !          1349:        register char           *p;
        !          1350:        int                     outfd;
        !          1351:        char                    closeit[NOFILE];
        !          1352:        char                    fdbuf[3];
        !          1353: 
        !          1354:        v = vect;
        !          1355:        pr = &ProcTab[procno];
        !          1356: 
        !          1357:        *v++ = pr->prpath;
        !          1358:        fdbuf[0] = pr->prcm.cm_rinput | 0100;
        !          1359:        fdbuf[1] = pr->prtflag;
        !          1360:        fdbuf[2] = '\0';
        !          1361:        *v++ = fdbuf;
        !          1362:        *v++ = Fileset;
        !          1363:        *v++ = Usercode;
        !          1364:        *v++ = Database;
        !          1365:        *v++ = Pathname;
        !          1366: 
        !          1367:        /* insert flag parameters */
        !          1368:        for (opt = Opt; *opt; opt++)
        !          1369:                *v++ = *opt;
        !          1370:        *v = 0;
        !          1371: 
        !          1372:        /* set up 'closeit' to tell which pipes to close */
        !          1373:        for (i = 0; i < NOFILE; i++)
        !          1374:                closeit[i] = TRUE;
        !          1375:        closeit[pr->prmpipe & 077] = FALSE;
        !          1376:        closeit[pr->prcm.cm_input & 077] = FALSE;
        !          1377:        closeit[pr->prcm.cm_rinput & 077] = FALSE;
        !          1378:        for (i = 0; i < CM_MAXPROC; i++)
        !          1379:        {
        !          1380:                pp = &pr->prcm.cm_proc[i];
        !          1381:                if (pp->pr_ninput != CLOSED)
        !          1382:                        closeit[pp->pr_ninput & 077] = FALSE;
        !          1383:                if (pp->pr_file != CLOSED)
        !          1384:                        closeit[pp->pr_file & 077] = FALSE;
        !          1385:        }
        !          1386:        closeit[1] = FALSE;
        !          1387:        if ((pr->prstat & PR_CLSSIN) == 0)
        !          1388:                closeit[0] = FALSE;
        !          1389:        if ((pr->prstat & PR_CLSDOUT) == 0)
        !          1390:                closeit[2] = FALSE;
        !          1391: 
        !          1392:        /* close extra pipes (those not used by this process) */
        !          1393:        for (i = 0; i < NOFILE; i++)
        !          1394:        {
        !          1395:                if (closeit[i])
        !          1396:                        close(i);
        !          1397:        }
        !          1398: 
        !          1399:        /* change to the correct directory */
        !          1400:        if ((pr->prstat & PR_NOCHDIR) == 0)
        !          1401:        {
        !          1402:                if (chdir(Dbpath))
        !          1403:                        syserr("ingexec: chdir %s", Dbpath);
        !          1404:        }
        !          1405: 
        !          1406:        /* change to normal userid/groupid if a non-dangerous process */
        !          1407:        if ((pr->prstat & PR_REALUID) != 0)
        !          1408:        {
        !          1409:                setuid(getuid());
        !          1410: #              ifndef xB_UNIX
        !          1411:                setgid(getgid());
        !          1412: #              endif
        !          1413:        }
        !          1414: 
        !          1415: # ifdef LEAVEOUT
        !          1416:        /* change standard output if specified in proctab */
        !          1417:        p = pr->prstdout;
        !          1418:        if (*p != 0)
        !          1419:        {
        !          1420:                /* chew up fd 0 (just in case) */
        !          1421:                outfd = dup(1);
        !          1422:                close(1);
        !          1423:                if (creat(p, 0666) != 1)
        !          1424:                {
        !          1425:                        /* restore standard output and print error */
        !          1426:                        close(1);
        !          1427:                        dup(outfd);     /* better go into slot 1 */
        !          1428:                        syserr("ingexec: creat %s", p);
        !          1429:                }
        !          1430:                close(outfd);
        !          1431:        }
        !          1432: # endif LEAVEOUT
        !          1433: 
        !          1434:        /*
        !          1435:        **  PLEASE NOTE THE TRICKERY USED HERE.
        !          1436:        **      In this code I depend on UNIX buffering pipes at least
        !          1437:        **      enough to handle one "CM" struct.  If not, the following
        !          1438:        **      write will hang before the exec will call the process
        !          1439:        **      that will read it.
        !          1440:        **
        !          1441:        **      The "correct" way to do this is to fork & have the
        !          1442:        **      parent write the CM struct.  But how do I handle the
        !          1443:        **      last one (that does not fork)?  I could also do an
        !          1444:        **      extra fork of a process to do the write.  But some
        !          1445:        **      systems have a limit on processes, and besides, it
        !          1446:        **      seems like a lot of overhead for such a little thing.
        !          1447:        **
        !          1448:        **      Perhaps I should encode the CM struct into argv
        !          1449:        **      instead & do it "right".
        !          1450:        */
        !          1451: 
        !          1452:        /* output the control structure to the awaiting process... */
        !          1453:        write(pr->prmpipe & 077, &pr->prcm, sizeof pr->prcm);
        !          1454:        close(pr->prmpipe & 077);
        !          1455: 
        !          1456:        /* give it the old college (or in this case, University) try */
        !          1457:        execv(vect[0], vect);
        !          1458:        syserr("\"%s\" not executable", vect[0]);
        !          1459: }
        !          1460: 
        !          1461: 
        !          1462: 
        !          1463: pipexlat(ppip, rw)
        !          1464:        char *ppip;
        !          1465:        int rw;
        !          1466: {
        !          1467:        register struct pipeinfo *pi;
        !          1468:        int cnt;
        !          1469:        int fd;
        !          1470: 
        !          1471:        if (*ppip == '\0' || *ppip == CLOSED)
        !          1472:                return;
        !          1473:        pi = &Pipe[*ppip];
        !          1474: 
        !          1475:        if (rw)
        !          1476:        {
        !          1477:                cnt = --(pi->pip_wcnt);
        !          1478:                fd = pi->pip_wfd;
        !          1479:        }
        !          1480:        else
        !          1481:        {
        !          1482:                cnt = --(pi->pip_rcnt);
        !          1483:                fd = pi->pip_rfd;
        !          1484:        }
        !          1485: 
        !          1486:        if (cnt < 0)
        !          1487:                syserr("pipexlat: cnt=%d: %o %d", cnt, *ppip, rw);
        !          1488:        if (fd < 0 || fd > NOFILE)
        !          1489:                syserr("pipexlat: fd=%d: %o %d", fd, *ppip, rw);
        !          1490: 
        !          1491:        *ppip = fd;
        !          1492: }
        !          1493: /*
        !          1494: **  YYLEX -- Return next token from proctab
        !          1495: **
        !          1496: **     Parameters:
        !          1497: **             none
        !          1498: **
        !          1499: **     Returns:
        !          1500: **             Next token
        !          1501: **
        !          1502: **     Side Effects:
        !          1503: **             Input from proctab
        !          1504: */
        !          1505: 
        !          1506: # define BOLSTATE      0       /* beginning of line */
        !          1507: # define NORMSTATE     1       /* normal token */
        !          1508: # define EOFSTATE      2       /* end of file */
        !          1509: int    LineNo;                 /* current line number */
        !          1510: 
        !          1511: yylex()
        !          1512: {
        !          1513:        static int state;
        !          1514:        static char *ptp;
        !          1515:        auto int ix;
        !          1516:        static char line[MAXLINE];
        !          1517:        register int c;
        !          1518:        register char *p;
        !          1519: 
        !          1520:        switch (state)
        !          1521:        {
        !          1522:          case EOFSTATE:
        !          1523:                return (0);
        !          1524: 
        !          1525:          case BOLSTATE:
        !          1526:                ptp = line;
        !          1527:                for (;;)
        !          1528:                {
        !          1529:                        LineNo++;
        !          1530:                        c = getc(ProcFile);
        !          1531:                        if (c < 0)
        !          1532:                        {
        !          1533:                                state = EOFSTATE;
        !          1534:                                return (0);
        !          1535:                        }
        !          1536:                        switch (c)
        !          1537:                        {
        !          1538:                          case '*':
        !          1539:                          case '#':
        !          1540:                          case '\n':
        !          1541:                                while (c != '\n' && (c = getc(ProcFile)) > 0)
        !          1542:                                        continue;
        !          1543:                                break;
        !          1544: 
        !          1545:                          case ':':
        !          1546:                                while (c != '\n' && (c = getc(ProcFile)) > 0)
        !          1547:                                        putchar(c);
        !          1548:                                break;
        !          1549: 
        !          1550:                          default:
        !          1551:                                /* regular line, return header */
        !          1552:                                state = NORMSTATE;
        !          1553:                                return (c);
        !          1554:                        }
        !          1555:                }
        !          1556:        
        !          1557:          case NORMSTATE:
        !          1558:                yylval.yystr = ptp;
        !          1559:                while ((c = getc(ProcFile)) != ':' && c != '\n' && c > 0)
        !          1560:                {
        !          1561:                        *ptp++ = c;
        !          1562:                        if (c == '$')
        !          1563:                        {
        !          1564:                                c = getc(ProcFile);
        !          1565:                                if (c < 'A' || c > 'Z')
        !          1566:                                        *ptp++ = c;
        !          1567:                                else
        !          1568:                                {
        !          1569:                                        ptp--;
        !          1570:                                        for (p = Macro[c - 'A']; (*ptp++ = *p++) != '\0'; )
        !          1571:                                                continue;
        !          1572:                                        ptp--;
        !          1573:                                }
        !          1574:                        }
        !          1575:                }
        !          1576:                
        !          1577:                /* compute next state */
        !          1578:                if (c != ':')
        !          1579:                        state = BOLSTATE;
        !          1580: 
        !          1581:                *ptp++ = '\0';
        !          1582:                ix = atoi(yylval.yystr);
        !          1583:                if ( *yylval.yystr <= '9' && *yylval.yystr >= '0')
        !          1584:                {
        !          1585:                        if (yylval.yystr[0] == '0')
        !          1586:                                ix = oatoi(yylval.yystr);
        !          1587:                        yylval.yyint = ix;
        !          1588:                        return (INT);
        !          1589:                }
        !          1590:                else
        !          1591:                        return (STR);
        !          1592:        
        !          1593:          default:
        !          1594:                syserr("yylex: state %d", state);
        !          1595:        }
        !          1596: }
        !          1597: 
        !          1598: 
        !          1599: 
        !          1600: 
        !          1601: yyerror(s)
        !          1602:        char *s;
        !          1603: {
        !          1604:        syserr("Line %d: Yacc error: %s", LineNo, s);
        !          1605: }
        !          1606: 
        !          1607: 
        !          1608: /*VARARGS1*/
        !          1609: usrerr(f, p1, p2, p3)
        !          1610:        char *f;
        !          1611: {
        !          1612:        printf("Line %d: ", LineNo);
        !          1613:        printf(f, p1, p2, p3);
        !          1614:        printf("\n");
        !          1615: }

unix.superglobalmegacorp.com

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