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

Defined functions

filter defined in line 239; used 4 times
recover defined in line 301; used 1 times
revocer defined in line 347; used 1 times
unix0 defined in line 24; used 5 times
unixex defined in line 133; used 4 times
unixwt defined in line 212; used 3 times
waitfor defined in line 330; used 4 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1991-09-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3813
Valid CSS Valid XHTML 1.0 Strict