|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.