1: /* Copyright (c) 1979 Regents of the University of California */
   2: #include "ex.h"
   3: #include "ex_temp.h"
   4: #include "ex_tty.h"
   5: #include "ex_vis.h"
   6: 
   7: /*
   8:  * Unix escapes, filtering
   9:  */
  10: 
  11: /*
  12:  * First part of a shell escape,
  13:  * parse the line, expanding # and % and ! and printing if implied.
  14:  */
  15: unix0(warn)
  16:     bool warn;
  17: {
  18:     register char *up, *fp;
  19:     register short c;
  20:     char printub, puxb[UXBSIZE + sizeof (int)];
  21: 
  22:     printub = 0;
  23:     CP(puxb, uxb);
  24:     c = getchar();
  25:     if (c == '\n' || c == EOF)
  26:         error("Incomplete shell escape command@- use 'shell' to get a shell");
  27:     up = uxb;
  28:     do {
  29:         switch (c) {
  30: 
  31:         case '\\':
  32:             if (any(peekchar(), "%#!"))
  33:                 c = getchar();
  34:         default:
  35:             if (up >= &uxb[UXBSIZE]) {
  36: tunix:
  37:                 uxb[0] = 0;
  38:                 error("Command too long");
  39:             }
  40:             *up++ = c;
  41:             break;
  42: 
  43:         case '!':
  44:             fp = puxb;
  45:             if (*fp == 0) {
  46:                 uxb[0] = 0;
  47:                 error("No previous command@to substitute for !");
  48:             }
  49:             printub++;
  50:             while (*fp) {
  51:                 if (up >= &uxb[UXBSIZE])
  52:                     goto tunix;
  53:                 *up++ = *fp++;
  54:             }
  55:             break;
  56: 
  57:         case '#':
  58:             fp = altfile;
  59:             if (*fp == 0) {
  60:                 uxb[0] = 0;
  61:                 error("No alternate filename@to substitute for #");
  62:             }
  63:             goto uexp;
  64: 
  65:         case '%':
  66:             fp = savedfile;
  67:             if (*fp == 0) {
  68:                 uxb[0] = 0;
  69:                 error("No filename@to substitute for %%");
  70:             }
  71: uexp:
  72:             printub++;
  73:             while (*fp) {
  74:                 if (up >= &uxb[UXBSIZE])
  75:                     goto tunix;
  76:                 *up++ = *fp++ | QUOTE;
  77:             }
  78:             break;
  79:         }
  80:         c = getchar();
  81:     } while (c == '"' || c == '|' || !endcmd(c));
  82:     if (c == EOF)
  83:         ungetchar(c);
  84:     *up = 0;
  85:     if (!inopen)
  86:         resetflav();
  87:     if (warn)
  88:         ckaw();
  89:     if (warn && hush == 0 && chng && xchng != chng && value(WARN) && dol > zero) {
  90:         xchng = chng;
  91:         vnfl();
  92:         printf(mesg("[No write]|[No write since last change]"));
  93:         noonl();
  94:         flush();
  95:     } else
  96:         warn = 0;
  97:     if (printub) {
  98:         if (uxb[0] == 0)
  99:             error("No previous command@to repeat");
 100:         if (inopen) {
 101:             splitw++;
 102:             vclean();
 103:             vgoto(WECHO, 0);
 104:         }
 105:         if (warn)
 106:             vnfl();
 107:         if (hush == 0)
 108:             lprintf("!%s", uxb);
 109:         if (inopen && Outchar != termchar) {
 110:             vclreol();
 111:             vgoto(WECHO, 0);
 112:         } else
 113:             putnl();
 114:         flush();
 115:     }
 116: }
 117: 
 118: /*
 119:  * Do the real work for execution of a shell escape.
 120:  * Mode is like the number passed to open system calls
 121:  * and indicates filtering.  If input is implied, newstdin
 122:  * must have been setup already.
 123:  */
 124: ttymode
 125: unixex(opt, up, newstdin, mode)
 126:     char *opt, *up;
 127:     int newstdin, mode;
 128: {
 129:     int pvec[2];
 130:     ttymode f;
 131: 
 132:     signal(SIGINT, SIG_IGN);
 133:     if (inopen)
 134:         f = setty(normf);
 135:     if ((mode & 1) && pipe(pvec) < 0) {
 136:         /* Newstdin should be io so it will be closed */
 137:         if (inopen)
 138:             setty(f);
 139:         error("Can't make pipe for filter");
 140:     }
 141: #ifndef VFORK
 142:     pid = fork();
 143: #else
 144:     pid = vfork();
 145: #endif
 146:     if (pid < 0) {
 147:         if (mode & 1) {
 148:             close(pvec[0]);
 149:             close(pvec[1]);
 150:         }
 151:         setrupt();
 152:         error("No more processes");
 153:     }
 154:     if (pid == 0) {
 155:         if (mode & 2) {
 156:             close(0);
 157:             dup(newstdin);
 158:             close(newstdin);
 159:         }
 160:         if (mode & 1) {
 161:             close(pvec[0]);
 162:             close(1);
 163:             dup(pvec[1]);
 164:             if (inopen) {
 165:                 close(2);
 166:                 dup(1);
 167:             }
 168:             close(pvec[1]);
 169:         }
 170:         if (io)
 171:             close(io);
 172:         if (tfile)
 173:             close(tfile);
 174:         close(erfile);
 175:         signal(SIGHUP, oldhup);
 176:         signal(SIGQUIT, oldquit);
 177:         if (ruptible)
 178:             signal(SIGINT, SIG_DFL);
 179:         execl(svalue(SHELL), "sh", opt, up, (char *) 0);
 180:         printf("No %s!\n", svalue(SHELL));
 181:         error(NOSTR);
 182:     }
 183:     if (mode & 1) {
 184:         io = pvec[0];
 185:         close(pvec[1]);
 186:     }
 187:     if (newstdin)
 188:         close(newstdin);
 189:     return (f);
 190: }
 191: 
 192: /*
 193:  * Wait for the command to complete.
 194:  * F is for restoration of tty mode if from open/visual.
 195:  * C flags suppression of printing.
 196:  */
 197: unixwt(c, f)
 198:     bool c;
 199:     ttymode f;
 200: {
 201: 
 202:     waitfor();
 203:     if (inopen)
 204:         setty(f);
 205:     setrupt();
 206:     if (!inopen && c && hush == 0) {
 207:         printf("!\n");
 208:         flush();
 209:         termreset();
 210:         gettmode();
 211:     }
 212: }
 213: 
 214: /*
 215:  * Setup a pipeline for the filtration implied by mode
 216:  * which is like a open number.  If input is required to
 217:  * the filter, then a child editor is created to write it.
 218:  * If output is catch it from io which is created by unixex.
 219:  */
 220: filter(mode)
 221:     register int mode;
 222: {
 223:     static int pvec[2];
 224:     register ttymode f;
 225:     register int lines = lineDOL();
 226: 
 227:     mode++;
 228:     if (mode & 2) {
 229:         signal(SIGINT, SIG_IGN);
 230:         if (pipe(pvec) < 0)
 231:             error("Can't make pipe");
 232:         pid = fork();
 233:         io = pvec[0];
 234:         if (pid < 0) {
 235:             setrupt();
 236:             close(pvec[1]);
 237:             error("No more processes");
 238:         }
 239:         if (pid == 0) {
 240:             setrupt();
 241:             io = pvec[1];
 242:             close(pvec[0]);
 243:             putfile();
 244:             exit(0);
 245:         }
 246:         close(pvec[1]);
 247:         io = pvec[0];
 248:         setrupt();
 249:     }
 250:     f = unixex("-c", uxb, (mode & 2) ? pvec[0] : 0, mode);
 251:     if (mode == 3) {
 252:         delete(0);
 253:         addr2 = addr1 - 1;
 254:     }
 255:     if (mode & 1) {
 256:         undap1 = undap2 = addr2+1;
 257:         ignore(append(getfile, addr2));
 258:     }
 259:     close(io);
 260:     io = -1;
 261:     unixwt(!inopen, f);
 262:     netchHAD(lines);
 263: }
 264: 
 265: /*
 266:  * Set up to do a recover, getting io to be a pipe from
 267:  * the recover process.
 268:  */
 269: recover()
 270: {
 271:     static int pvec[2];
 272: 
 273:     if (pipe(pvec) < 0)
 274:         error(" Can't make pipe for recovery");
 275:     pid = fork();
 276:     io = pvec[0];
 277:     if (pid < 0) {
 278:         close(pvec[1]);
 279:         error(" Can't fork to execute recovery");
 280:     }
 281:     if (pid == 0) {
 282:         close(2);
 283:         dup(1);
 284:         close(1);
 285:         dup(pvec[1]);
 286:             close(pvec[1]);
 287:         execl(EXRECOVER, "exrecover", svalue(DIRECTORY), file, (char *) 0);
 288:         close(1);
 289:         dup(2);
 290:         error(" No recovery routine");
 291:     }
 292:     close(pvec[1]);
 293: }
 294: 
 295: /*
 296:  * Wait for the process (pid an external) to complete.
 297:  */
 298: waitfor()
 299: {
 300: 
 301:     do
 302:         rpid = wait(&status);
 303:     while (rpid != pid && rpid != -1);
 304:     status = (status >> 8) & 0377;
 305: }
 306: 
 307: /*
 308:  * The end of a recover operation.  If the process
 309:  * exits non-zero, force not edited; otherwise force
 310:  * a write.
 311:  */
 312: revocer()
 313: {
 314: 
 315:     waitfor();
 316:     if (pid == rpid && status != 0)
 317:         edited = 0;
 318:     else
 319:         change();
 320: }

Defined functions

filter defined in line 220; used 4 times
recover defined in line 269; used 1 times
revocer defined in line 312; used 1 times
unix0 defined in line 15; used 5 times
unixex defined in line 124; used 4 times
unixwt defined in line 197; used 3 times
waitfor defined in line 298; used 4 times
Last modified: 1980-09-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1129
Valid CSS Valid XHTML 1.0 Strict