|
|
1.1 ! root 1: # include "monitor.h" ! 2: # include <ingres.h> ! 3: # include <version.h> ! 4: # include <opsys.h> ! 5: # include <pv.h> ! 6: # include <func.h> ! 7: # include <signal.h> ! 8: # include <pipes.h> ! 9: # include <setjmp.h> ! 10: # include <sccs.h> ! 11: ! 12: SCCSID(@(#)ttymon.c 7.2 6/4/83) ! 13: ! 14: ! 15: ! 16: # define ERRDELIM '~' ! 17: ! 18: /* ! 19: ** INTERACTIVE TERMINAL MONITOR ! 20: ** ! 21: ** The monitor gathers text from the standard input and performs ! 22: ** a variety of rudimentary editting functions. This program ! 23: ** is the main setup. Monitor() is then called, which does the ! 24: ** real work. ! 25: ** ! 26: ** variables: ! 27: ** Nodayfile -- zero prints all messages; positive one suppresses ! 28: ** dayfile and logout but not prompts; negative one ! 29: ** suppresses all printed material except results from \p. ! 30: ** Newline -- set when the last character in the query buffer ! 31: ** is a newline. ! 32: ** Prompt -- set when a prompt character is needed. ! 33: ** Autoclear -- set when the query buffer should be cleared before ! 34: ** putting another character in. ! 35: ** Nautoclear -- if set, suppresses the autoclear function ! 36: ** entirely. ! 37: ** ! 38: ** flags: ! 39: ** -M -- trace flag ! 40: ** -d -- suppress dayfile ! 41: ** -s -- suppress prompt (sets -d) ! 42: ** -a -- disable autoclear function ! 43: ** ! 44: ** The last three options can be set by stating "+x". ! 45: ** ! 46: ** Trace Flags: ! 47: ** 9 ! 48: ** 11 (proc_err) ! 49: */ ! 50: ! 51: extern char *Usercode; ! 52: extern tm_mon(); ! 53: extern tm_init(); ! 54: extern tm_intr(); ! 55: short tTttymon[100]; ! 56: ! 57: struct fn_def TtyMonFn = ! 58: { ! 59: "MONITOR", ! 60: tm_mon, ! 61: tm_init, ! 62: tm_intr, ! 63: NULL, ! 64: 0, ! 65: tTttymon, ! 66: 100, ! 67: 'M', ! 68: 0 ! 69: }; ! 70: ! 71: tm_init(argc, argv) ! 72: int argc; ! 73: char *argv[]; ! 74: { ! 75: register int ndx; ! 76: register char *p; ! 77: extern quit(); ! 78: extern int (*ExitFn)(); ! 79: extern int Equel; ! 80: char buff[100]; ! 81: extern char *getufield(); ! 82: extern jmp_buf CmReset; ! 83: extern char SysIdent[]; ! 84: ! 85: ! 86: /* insure that permissions are ok */ ! 87: setuid(getuid()); ! 88: # ifndef xB_UNIX ! 89: setgid(getgid()); ! 90: # endif ! 91: ! 92: setjmp(CmReset); ! 93: signal(SIGPIPE, quit); ! 94: ! 95: ExitFn = quit; ! 96: set_si_buf(); ! 97: ! 98: /* process arguments */ ! 99: if (!setflag(argv, 'd', 1)) ! 100: Nodayfile = 1; ! 101: if (!setflag(argv, 's', 1)) ! 102: Nodayfile = -1; ! 103: Nautoclear = !setflag(argv, 'a', 1); ! 104: ! 105: /* preinitialize macros */ ! 106: macinit(0, 0, 0); ! 107: macdefine("{pathname}", Pathname, 1); ! 108: ! 109: /* print the dayfile */ ! 110: if (Nodayfile >= 0) ! 111: { ! 112: time(buff); ! 113: printf("%s login\n%s", SysIdent, ctime(buff)); ! 114: } ! 115: if (Nodayfile == 0 && (Qryiop = fopen(ztack(ztack(Pathname, "/files/dayfile"), VERSION), "r")) != NULL) ! 116: { ! 117: while ((ndx = getc(Qryiop)) > 0) ! 118: putchar(ndx); ! 119: fclose(Qryiop); ! 120: } ! 121: ! 122: /* SET UP LOGICAL QUERY-BUFFER FILE */ ! 123: concat("/tmp/INGQ", Fileset, Qbname); ! 124: if ((Qryiop = fopen(Qbname, "w")) == NULL) ! 125: syserr("main: open(%s)", Qbname); ! 126: ! 127: /* GO TO IT ... */ ! 128: Prompt = Newline = TRUE; ! 129: Userdflag = Nodayfile; ! 130: Nodayfile = -1; ! 131: ! 132: /* run the system initialization file */ ! 133: setjmp(CmReset); ! 134: Phase++; ! 135: include(ztack(Pathname, "/files/startup")); ! 136: ! 137: /* find out what the user initialization file is */ ! 138: setjmp(CmReset); ! 139: if (getuser(Usercode, buff) == 0) ! 140: { ! 141: p = getufield(buff, 7); ! 142: if (*p != 0) ! 143: include(p); ! 144: } ! 145: getuser(0, 0); ! 146: ! 147: Nodayfile = Userdflag; ! 148: ! 149: /* ! 150: ** Get user input from terminal ! 151: ** ! 152: ** THIS CODE IS A CLUDGE!!! ! 153: ** ! 154: ** This code should return right after the setbuf call, ! 155: ** but it doesn't because we want the monitor to be in ! 156: ** control initially. The way the control module is ! 157: ** written, this will work. But we are definitely ! 158: ** cheating.... ! 159: */ ! 160: ! 161: Input = stdin; ! 162: setbuf(stdin, NULL); ! 163: monitor(); ! 164: quit(); ! 165: } ! 166: /* ! 167: ** CATCH SIGNALS ! 168: ** ! 169: ** clear out pipes and respond to user ! 170: ** ! 171: ** Uses trace flag 10 ! 172: */ ! 173: ! 174: tm_intr(typ) ! 175: int typ; ! 176: { ! 177: register int i; ! 178: ! 179: if (typ != 2) ! 180: syserr("tm_intr: typ %d", typ); ! 181: ! 182: if (Xwaitpid == 0) ! 183: printf("\nInterrupt\n"); ! 184: ! 185: lseek(stdin->_file, 0L, 2); ! 186: Newline = Prompt = TRUE; ! 187: Nodayfile = Userdflag; ! 188: Oneline = FALSE; ! 189: Idepth = 0; ! 190: setbuf(stdin, NULL); ! 191: Input = stdin; ! 192: xwait(); ! 193: } ! 194: /* ! 195: ** PROCESS ERROR MESSAGE ! 196: ** ! 197: ** This routine takes an error message off of the pipe and ! 198: ** processes it for output to the terminal. This involves doing ! 199: ** a lookup in the .../files/error? files, where ? is the thous- ! 200: ** ands digit of the error number. The associated error message ! 201: ** then goes through parameter substitution and is printed. ! 202: ** ! 203: ** In the current version, the error message is just printed. ! 204: ** ! 205: ** We unquestionably cheat, by doing a longjmp rather than a ! 206: ** return here -- this is so that the synchronization works right. ! 207: ** ! 208: ** Trace Flags: ! 209: ** 30 ! 210: */ ! 211: ! 212: proc_err(ppb, pc, pv) ! 213: pb_t *ppb; ! 214: int pc; ! 215: PARM pv[]; ! 216: { ! 217: register char c; ! 218: register char *p; ! 219: int i; ! 220: char buf[512]; ! 221: int err; ! 222: FILE *iop; ! 223: char *errfilen(); ! 224: extern char *mcall(); ! 225: bool fatal; ! 226: extern jmp_buf GoJmpBuf; ! 227: ! 228: if (pc <= 0 || pv[0].pv_type != PV_INT) ! 229: syserr("proc_err: pc %d pv0type %d", pc, pv[0].pv_type); ! 230: err = pv[0].pv_val.pv_int; ! 231: Error_id = err; ! 232: fatal = !bitset(PB_INFO, ppb->pb_stat); ! 233: ! 234: /* try calling the {catcherror} macro -- maybe not print */ ! 235: p = buf; ! 236: p += smove("{catcherror; ", p); ! 237: p += smove(iocv(err), p); ! 238: p += smove("}", p); ! 239: ! 240: p = mcall(buf); ! 241: if (sequal(p, "0")) ! 242: return (1); ! 243: ! 244: /* open the appropriate error file */ ! 245: p = errfilen(err / 1000); ! 246: ! 247: # ifdef xMTR3 ! 248: if (tTf(30, -1)) ! 249: printf("proc_error: "); ! 250: if (tTf(30, 0)) ! 251: printf("%d, %s", err, p); ! 252: # endif ! 253: ! 254: if ((iop = fopen(p, "r")) == NULL) ! 255: syserr("proc_error: open(%s)", p); ! 256: ! 257: /* read in the code and check for correct */ ! 258: for (;;) ! 259: { ! 260: p = buf; ! 261: while ((c = getc(iop)) != '\t') ! 262: { ! 263: if (c <= 0) ! 264: { ! 265: /* no code exists, print the args */ ! 266: printf("%d:", err); ! 267: for (i = 0; i < pc; i++) ! 268: printf(" `%s'", pv[i].pv_val.pv_str); ! 269: printf("\n"); ! 270: fclose(iop); ! 271: if (fatal) ! 272: longjmp(CmReset, 1); ! 273: else ! 274: longjmp(GoJmpBuf, 1); ! 275: } ! 276: *p++ = c; ! 277: } ! 278: *p = 0; ! 279: i = atoi(buf); ! 280: ! 281: if (i != err) ! 282: { ! 283: while ((c = getc(iop)) != ERRDELIM) ! 284: if (c <= 0) ! 285: syserr("proc_error: format err %d", err); ! 286: getc(iop); /* throw out the newline */ ! 287: continue; ! 288: } ! 289: ! 290: /* got the correct line, print it doing parameter substitution */ ! 291: printf("%d: ", err); ! 292: c = '\n'; ! 293: for (;;) ! 294: { ! 295: c = getc(iop); ! 296: if (c <= 0 || c == ERRDELIM) ! 297: { ! 298: printf("\n"); ! 299: fclose(iop); ! 300: if (fatal) ! 301: longjmp(CmReset, 1); ! 302: else ! 303: longjmp(GoJmpBuf, 1); ! 304: } ! 305: if (c == '%') ! 306: { ! 307: c = getc(iop) - '0' + 1; ! 308: if (c >= pc) ! 309: syserr("proc_err: parm %d", c - 1); ! 310: switch (pv[c].pv_type) ! 311: { ! 312: case PV_STR: ! 313: for (p = pv[c].pv_val.pv_str; c = *p; p++) ! 314: xputchar(c); ! 315: continue; ! 316: ! 317: case PV_INT: ! 318: printf("%d", pv[c].pv_val.pv_int); ! 319: continue; ! 320: ! 321: default: ! 322: syserr("proc_err: arg %d type %d", c, pv[c].pv_type); ! 323: } ! 324: } ! 325: printf("%c", c); ! 326: } ! 327: } ! 328: } ! 329: /* ! 330: ** TM_MON -- "function to implement this module" ! 331: ** ! 332: ** Since we have cludged up this module to work, and hence ! 333: ** the init routine should never return, this routine just ! 334: ** syserr's. ! 335: */ ! 336: ! 337: tm_mon() ! 338: { ! 339: syserr("tm_mon"); ! 340: } ! 341: /* ! 342: ** ACC_INIT, PAGEFLUSH -- dummy access method routines ! 343: ** ! 344: ** Since the CM wants to do some basic access method functions, ! 345: ** we will let it. ! 346: */ ! 347: ! 348: acc_init() ! 349: { ! 350: } ! 351: ! 352: pageflush(x) ! 353: char *x; ! 354: { ! 355: return (0); ! 356: } ! 357: /* ! 358: ** CLOSECATALOG -- dummy catalog close routine. ! 359: ** ! 360: ** To keep from loading access methods. ! 361: */ ! 362: ! 363: closecatalog() ! 364: { ! 365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.