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

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

unix.superglobalmegacorp.com

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