Annotation of 42BSD/ingres/source/support/ingres.c, revision 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.