1: # include "monitor.h" 2: # include <ingres.h> 3: # include <aux.h> 4: # include <signal.h> 5: # include <ctlmod.h> 6: # include <sccs.h> 7: 8: SCCSID(@(#)monitor.c 8.1 12/31/84) 9: 10: 11: 12: /* 13: ** MONITOR 14: ** 15: ** This routine maintains the logical query buffer in 16: ** /tmp/INGQxxxx. It in general just does a copy from input 17: ** to query buffer, unless it gets a backslash escape character 18: ** or dollarsign escape character. 19: ** It recognizes the following escapes: 20: ** 21: ** \a -- force append mode (no autoclear) 22: ** \b -- branch (within an include file only) 23: ** \c -- reserved for screen clear in geoquel 24: ** \d -- change working directory 25: ** \e -- enter editor 26: ** \g -- "GO": submit query to INGRES 27: ** \i -- include (switch input to external file) 28: ** \k -- mark (for \b) 29: ** \l -- list: print query buffer after macro evaluation 30: ** \p -- print query buffer (before macro evaluation) 31: ** \q -- quit ingres 32: ** \r -- force reset (clear) of query buffer 33: ** \s -- call shell 34: ** \t -- print current time 35: ** \v -- evaluate macros, but throw away result (for side effects) 36: ** \w -- write query buffer to external file 37: ** \$t -- change setting of trace flags 38: ** \$r -- reset system 39: ** \\ -- produce a single backslash in query buffer 40: ** 41: ** Uses trace flag 2 42: */ 43: 44: /* 45: ** COMMAND TABLE 46: ** To add synonyms for commands, add entries to this table 47: */ 48: 49: struct cntrlwd 50: { 51: char *name; 52: int code; 53: }; 54: 55: struct cntrlwd Controlwords[] = 56: { 57: "a", C_APPEND, 58: "append", C_APPEND, 59: "b", C_BRANCH, 60: "branch", C_BRANCH, 61: "cd", C_CHDIR, 62: "chdir", C_CHDIR, 63: "e", C_EDIT, 64: "ed", C_EDIT, 65: "edit", C_EDIT, 66: "editor", C_EDIT, 67: "g", C_GO, 68: "go", C_GO, 69: "i", C_INCLUDE, 70: "include", C_INCLUDE, 71: "read", C_INCLUDE, 72: "k", C_MARK, 73: "mark", C_MARK, 74: "l", C_LIST, 75: "list", C_LIST, 76: "p", C_PRINT, 77: "print", C_PRINT, 78: "q", C_QUIT, 79: "quit", C_QUIT, 80: "r", C_RESET, 81: "reset", C_RESET, 82: "s", C_SHELL, 83: "sh", C_SHELL, 84: "shell", C_SHELL, 85: "t", C_TIME, 86: "time", C_TIME, 87: "date", C_TIME, 88: "v", C_EVAL, 89: "eval", C_EVAL, 90: "w", C_WRITE, 91: "write", C_WRITE, 92: "$t", C_SYSTRACE, 93: "$trace", C_SYSTRACE, 94: "$r", C_SYSRESET, 95: "$reset", C_SYSRESET, 96: 0 97: }; 98: 99: 100: monitor(recurs) 101: int recurs; /* Is this a recursive call? */ 102: { 103: register char chr; 104: int timevec[2]; 105: register int controlno; 106: extern jmp_buf CmReset; 107: extern error(); 108: extern char *Proc_name; 109: extern int RubLevel; 110: extern rubcatch(); 111: 112: if ( recurs == FALSE ) 113: setjmp(CmReset); 114: initbuf(Qbuf, QbufSize, ERR_QBUF, error); 115: clrmem(&Ctx, sizeof Ctx); 116: Ctx.ctx_cmark = Ctx.ctx_pmark = markbuf(Qbuf); 117: Ctx.ctx_name = Proc_name = Cm.cm_myname; 118: Ctx.ctx_tvect = tT = FuncVect[0]->fn_tvect; 119: xwait(); 120: if (RubLevel >= 0) 121: signal(SIGINT, rubcatch); 122: 123: while (chr = getch()) 124: { 125: if (chr == '\\') 126: { 127: 128: /* 129: ** do not process "\\" as an escape char 130: */ 131: if ((chr = getch()) == '\\') 132: { 133: putch(chr); 134: putch(chr); 135: continue; 136: } 137: else 138: ungetc(chr, Input); 139: 140: /* process control sequence */ 141: if ((controlno = getescape(1)) == 0) 142: continue; 143: 144: switch (controlno) 145: { 146: 147: case C_EDIT: 148: edit(); 149: continue; 150: 151: case C_PRINT: 152: print(); 153: continue; 154: 155: case C_LIST: 156: eval(1); 157: continue; 158: 159: case C_EVAL: 160: eval(0); 161: Autoclear = TRUE; 162: continue; 163: 164: case C_INCLUDE: 165: include(0); 166: cgprompt(); 167: continue; 168: 169: case C_WRITE: 170: writeout(); 171: cgprompt(); 172: continue; 173: 174: case C_CHDIR: 175: newdirec(); 176: cgprompt(); 177: continue; 178: 179: case C_RESET: 180: clear(1); 181: continue; 182: 183: case C_GO: 184: go(); 185: continue; 186: 187: case C_QUIT: 188: clrline(1); 189: quit(); 190: 191: case C_SHELL: 192: shell(); 193: continue; 194: 195: case C_TIME: 196: time(timevec); 197: printf("%s", ctime(timevec)); 198: clrline(0); 199: continue; 200: 201: case C_APPEND: 202: Autoclear = 0; 203: clrline(0); 204: continue; 205: 206: case C_MARK: 207: getfilenm(); 208: prompt(0); 209: continue; 210: 211: case C_BRANCH: 212: branch(); 213: prompt(0); 214: continue; 215: 216: case C_SYSTRACE: 217: trace(); 218: prompt(0); 219: continue; 220: 221: case C_SYSRESET: 222: reset(); 223: clrline(0); 224: continue; 225: 226: default: 227: syserr("monitor: bad code %d", controlno); 228: } 229: } 230: putch(chr); 231: } 232: 233: if (Input == stdin) 234: { 235: if (Nodayfile >= 0) 236: printf("\n"); 237: } 238: else 239: fclose(Input); 240: } 241: 242: getescape(copy) 243: int copy; 244: { 245: register struct cntrlwd *cw; 246: register char *word; 247: char *getname(); 248: 249: word = getname(); 250: for (cw = Controlwords; cw->name; cw++) 251: { 252: if (sequal(cw->name, word)) 253: return (cw->code); 254: } 255: 256: /* not found -- pass symbol through and return failure */ 257: if (copy == 0) 258: return (0); 259: putch('\\'); 260: while (*word != 0) 261: { 262: putch(*word++); 263: } 264: return (0); 265: } 266: 267: char * 268: getname() 269: { 270: register char *p; 271: static char buf[41]; 272: register int len; 273: register char c; 274: 275: p = buf; 276: for (len = 0; len < 40; len++) 277: { 278: c = getch(); 279: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 280: { 281: *p++ = c; 282: } 283: else if ((len == 0) && (c == '$')) /* system control command */ 284: { 285: *p++ = c; 286: } 287: else 288: { 289: ungetc(c, Input); 290: break; 291: } 292: } 293: 294: *p = 0; 295: return (buf); 296: } 297: 298: 299: 300: putch(ch) 301: char ch; 302: { 303: register char c; 304: 305: c = ch; 306: 307: Prompt = Newline = (c == '\n'); 308: if (c < 040 && c != '\n' && c != '\t') 309: { 310: printf("Funny character 0%o converted to blank\n", c); 311: c = ' '; 312: } 313: prompt(0); 314: if (Autoclear) 315: clear(0); 316: putc(c, Qryiop); 317: Notnull++; 318: }