Annotation of 43BSD/ingres/source/support/ingres.y, revision 1.1.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.