1: # include <stdio.h> 2: 3: # include "../ingres.h" 4: # include "../aux.h" 5: # include "../unix.h" 6: # include "../pipes.h" 7: # include "monitor.h" 8: 9: # define ERRDELIM '~' 10: 11: /* 12: ** INTERACTIVE TERMINAL MONITOR 13: ** 14: ** The monitor gathers text from the standard input and performs 15: ** a variety of rudimentary editting functions. This program 16: ** is the main setup. Monitor() is then called, which does the 17: ** real work. 18: ** 19: ** variables: 20: ** Nodayfile -- zero prints all messages; positive one suppresses 21: ** dayfile and logout but not prompts; negative one 22: ** suppresses all printed material except results from \p. 23: ** Newline -- set when the last character in the query buffer 24: ** is a newline. 25: ** Prompt -- set when a prompt character is needed. 26: ** Autoclear -- set when the query buffer should be cleared before 27: ** putting another character in. 28: ** Nautoclear -- if set, suppresses the autoclear function 29: ** entirely. 30: ** 31: ** flags: 32: ** -M -- trace flag 33: ** -d -- suppress dayfile 34: ** -s -- suppress prompt (sets -d) 35: ** -a -- disable autoclear function 36: ** 37: ** The last three options can be set by stating "+x". 38: ** 39: ** Uses trace flag 9 40: ** Proc_error uses trace flag 11 41: ** 42: ** History: 43: ** 8/15/79 (eric) (6.2/7) -- added {database} and 44: ** {usercode} macros. 45: ** 3/2/79 (eric) -- rubproc changed to know about the 46: ** Trapfile stuff. 47: */ 48: 49: extern char *Usercode; 50: extern char *Database; 51: 52: main(argc, argv) 53: int argc; 54: char *argv[]; 55: { 56: register int ndx; 57: extern char *Proc_name; 58: register char *p; 59: extern quit(); 60: extern int (*Exitfn)(); 61: extern int Equel; 62: char buff[100]; 63: extern char **Xparams; 64: char *getufield(); 65: 66: /* insure that permissions are ok */ 67: setuid(getuid()); 68: # ifndef xB_UNIX 69: setgid(getgid()); 70: # endif 71: 72: setexit(); 73: signal(13, &quit); 74: 75: # ifdef xMTR1 76: tTrace(&argc, argv, 'M'); 77: # endif 78: initproc("MONITOR", argv); 79: Exitfn = &quit; 80: 81: /* process arguments */ 82: if (!setflag(argv, 'd', 1)) 83: Nodayfile = 1; 84: if (!setflag(argv, 's', 1)) 85: Nodayfile = -1; 86: Nautoclear = !setflag(argv, 'a', 1); 87: # ifdef xMTR3 88: if (tTf(9, 0)) 89: { 90: close(ndx = dup(0)); 91: printf("0 dups as %d\n", ndx); 92: } 93: # endif 94: # ifdef xMTR2 95: if (tTf(9, 1)) 96: prargs(argc, argv); 97: if (tTf(9, 2)) 98: { 99: printf("R_up %d W_up %d R_down %d W_down %d\n", 100: R_up, W_up, R_down, W_down); 101: printf("R_front %d W_front %d Equel %d\n", 102: R_front, W_front, Equel); 103: } 104: # endif 105: smove(Version, Versn); 106: for (p = Versn; *p != '/'; p++) 107: if (!*p) 108: break; 109: *p = '\0'; 110: 111: /* preinitialize macros */ 112: macinit(0, 0, 0); 113: macdefine("{pathname}", Pathname, 1); 114: macdefine("{database}", Database, 1); 115: macdefine("{usercode}", Usercode, 1); 116: 117: /* print the dayfile */ 118: if (Nodayfile >= 0) 119: { 120: time(buff); 121: printf("INGRES version %s login\n%s", Version, ctime(buff)); 122: } 123: if (Nodayfile == 0 && (Qryiop = fopen(ztack(ztack(Pathname, "/files/dayfile"), Versn), "r")) != NULL) 124: { 125: while ((ndx = getc(Qryiop)) > 0) 126: putchar(ndx); 127: fclose(Qryiop); 128: } 129: 130: /* SET UP LOGICAL QUERY-BUFFER FILE */ 131: concat("/tmp/INGQ", Fileset, Qbname); 132: if ((Qryiop = fopen(Qbname, "w")) == NULL) 133: syserr("main: open(%s)", Qbname); 134: 135: /* GO TO IT ... */ 136: Prompt = Newline = TRUE; 137: Userdflag = Nodayfile; 138: Nodayfile = -1; 139: 140: /* run the system initialization file */ 141: setexit(); 142: Phase++; 143: include(Xparams[0]); 144: 145: /* find out what the user initialization file is */ 146: setexit(); 147: if (getuser(Usercode, buff) == 0) 148: { 149: p = getufield(buff, 7); 150: if (*p != 0) 151: include(p); 152: } 153: getuser(0, 0); 154: 155: Nodayfile = Userdflag; 156: 157: /* get user input from terminal */ 158: Input = stdin; 159: setbuf(stdin, NULL); 160: setexit(); 161: xwait(); 162: monitor(); 163: quit(); 164: } 165: 166: 167: 168: 169: 170: /* 171: ** CATCH SIGNALS 172: ** 173: ** clear out pipes and respond to user 174: ** 175: ** Uses trace flag 10 176: */ 177: 178: rubproc() 179: { 180: register int i; 181: long ltemp; 182: 183: # ifdef xMTR3 184: if (tTf(10, 0)) 185: printf("caught sig\n"); 186: # endif 187: if (Xwaitpid == 0) 188: printf("\nInterrupt\n"); 189: resyncpipes(); 190: for (i = 3; i < MAXFILES; i++) 191: { 192: if (i == Qryiop->_file || i == R_down || i == W_down || 193: (Trapfile != NULL && i == Trapfile->_file)) 194: continue; 195: close(i); 196: } 197: ltemp = 0; 198: lseek(stdin->_file, ltemp, 2); 199: Newline = Prompt = TRUE; 200: Nodayfile = Userdflag; 201: Oneline = FALSE; 202: Idepth = 0; 203: setbuf(stdin, NULL); 204: Input = stdin; 205: } 206: 207: 208: /* 209: ** PROCESS ERROR MESSAGE 210: ** 211: ** This routine takes an error message off of the pipe and 212: ** processes it for output to the terminal. This involves doing 213: ** a lookup in the .../files/error? files, where ? is the thous- 214: ** ands digit of the error number. The associated error message 215: ** then goes through parameter substitution and is printed. 216: ** 217: ** In the current version, the error message is just printed. 218: ** 219: ** Uses trace flag 11 220: */ 221: 222: proc_error(s1, rpipnum) 223: struct pipfrmt *s1; 224: int rpipnum; 225: { 226: register struct pipfrmt *s; 227: register char c; 228: char *pv[10]; 229: char parm[512]; 230: int pc; 231: register char *p; 232: int i; 233: char buf[sizeof parm + 30]; 234: int err; 235: FILE *iop; 236: char *errfilen(); 237: char *mcall(); 238: 239: s = s1; 240: err = s->err_id; 241: Error_id = err; 242: 243: /* read in the parameters */ 244: pc = 0; 245: p = parm; 246: while (i = rdpipe(P_NORM, s, R_down, p, 0)) 247: { 248: pv[pc] = p; 249: # ifdef xMTR3 250: if (tTf(11, 1)) 251: printf("pv[%d] = %s, i=%d\n", pc, p, i); 252: # endif 253: p += i; 254: pc++; 255: if (pc >= 10 || (p - parm) >= 500) 256: { 257: /* buffer overflow; throw him off */ 258: syserr("Your error buffer overfloweth @ pc %d err %d p-p %d", 259: pc, err, p - parm); 260: } 261: } 262: pv[pc] = 0; 263: rdpipe(P_PRIME, s); 264: 265: /* try calling the {catcherror} macro -- maybe not print */ 266: p = buf; 267: p += smove("{catcherror; ", p); 268: p += smove(iocv(err), p); 269: p += smove("}", p); 270: 271: p = mcall(buf); 272: if (sequal(p, "0")) 273: return (1); 274: 275: /* open the appropriate error file */ 276: p = errfilen(err / 1000); 277: 278: # ifdef xMTR3 279: if (tTf(11, -1)) 280: printf("proc_error: "); 281: if (tTf(11, 0)) 282: printf("%d, %s", err, p); 283: # endif 284: 285: if ((iop = fopen(p, "r")) == NULL) 286: syserr("proc_error: open(%s)", p); 287: 288: /* read in the code and check for correct */ 289: for (;;) 290: { 291: p = buf; 292: while ((c = getc(iop)) != '\t') 293: { 294: if (c <= 0) 295: { 296: /* no code exists, print the args */ 297: printf("%d:", err); 298: for (i = 0; i < pc; i++) 299: printf(" `%s'", pv[i]); 300: printf("\n"); 301: fclose(iop); 302: return (1); 303: } 304: *p++ = c; 305: } 306: *p = 0; 307: if (atoi(buf, &i)) 308: syserr("proc_error: bad error file %d\n%s", 309: err, buf); 310: if (i != err) 311: { 312: while ((c = getc(iop)) != ERRDELIM) 313: if (c <= 0) 314: syserr("proc_error: format err %d", err); 315: getc(iop); /* throw out the newline */ 316: continue; 317: } 318: 319: /* got the correct line, print it doing parameter substitution */ 320: printf("%d: ", err); 321: c = '\n'; 322: for (;;) 323: { 324: c = getc(iop); 325: if (c <= 0 || c == ERRDELIM) 326: { 327: printf("\n"); 328: fclose(iop); 329: return (1); 330: } 331: if (c == '%') 332: { 333: c = getc(iop); 334: for (p = pv[c - '0']; c = *p; p++) 335: { 336: if (c < 040 || c >= 0177) 337: printf("\\%o", c); 338: else 339: putchar(c); 340: } 341: continue; 342: } 343: printf("%c", c); 344: } 345: } 346: } 347: 348: 349: 350: /* 351: ** END_JOB -- "cannot happen" 352: */ 353: 354: end_job() 355: { 356: syserr("end_job??"); 357: }