00001 #define Extern extern
00002 #include <sys/types.h>
00003 #include <signal.h>
00004 #include <errno.h>
00005 #include <setjmp.h>
00006 #include "sh.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015 static struct iobuf sharedbuf = {AFID_NOBUF};
00016 static struct iobuf mainbuf = {AFID_NOBUF};
00017 static unsigned bufid = AFID_ID;
00018
00019 struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
00020
00021 _PROTOTYPE(static void readhere, (char **name, char *s, int ec ));
00022 _PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));
00023 _PROTOTYPE(static int xxchar, (struct ioarg *ap ));
00024 _PROTOTYPE(void tempname, (char *tname ));
00025
00026 int
00027 getc(ec)
00028 register int ec;
00029 {
00030 register int c;
00031
00032 if(e.linep > elinep) {
00033 while((c=readc()) != '\n' && c)
00034 ;
00035 err("input line too long");
00036 gflg++;
00037 return(c);
00038 }
00039 c = readc();
00040 if (ec != '\'' && e.iop->task != XGRAVE) {
00041 if(c == '\\') {
00042 c = readc();
00043 if (c == '\n' && ec != '\"')
00044 return(getc(ec));
00045 c |= QUOTE;
00046 }
00047 }
00048 return(c);
00049 }
00050
00051 void
00052 unget(c)
00053 int c;
00054 {
00055 if (e.iop >= e.iobase)
00056 e.iop->peekc = c;
00057 }
00058
00059 int
00060 eofc()
00061
00062 {
00063 return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
00064 }
00065
00066 int
00067 readc()
00068 {
00069 register c;
00070
00071 for (; e.iop >= e.iobase; e.iop--)
00072 if ((c = e.iop->peekc) != '\0') {
00073 e.iop->peekc = 0;
00074 return(c);
00075 }
00076 else {
00077 if (e.iop->prev != 0) {
00078 if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
00079 if (c == -1) {
00080 e.iop++;
00081 continue;
00082 }
00083 if (e.iop == iostack)
00084 ioecho(c);
00085 return(e.iop->prev = c);
00086 }
00087 else if (e.iop->task == XIO && e.iop->prev != '\n') {
00088 e.iop->prev = 0;
00089 if (e.iop == iostack)
00090 ioecho('\n');
00091 return '\n';
00092 }
00093 }
00094 if (e.iop->task == XIO) {
00095 if (multiline)
00096 return e.iop->prev = 0;
00097 if (talking && e.iop == iostack+1)
00098 prs(prompt->value);
00099 }
00100 }
00101 if (e.iop >= iostack)
00102 return(0);
00103 leave();
00104
00105 }
00106
00107 void
00108 ioecho(c)
00109 char c;
00110 {
00111 if (flag['v'])
00112 write(2, &c, sizeof c);
00113 }
00114
00115 void
00116 pushio(argp, fn)
00117 struct ioarg *argp;
00118 int (*fn)();
00119 {
00120 if (++e.iop >= &iostack[NPUSH]) {
00121 e.iop--;
00122 err("Shell input nested too deeply");
00123 gflg++;
00124 return;
00125 }
00126 e.iop->iofn = fn;
00127
00128 if (argp->afid != AFID_NOBUF)
00129 e.iop->argp = argp;
00130 else {
00131 e.iop->argp = ioargstack + (e.iop - iostack);
00132 *e.iop->argp = *argp;
00133 e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
00134 if (isatty(e.iop->argp->afile) == 0 &&
00135 (e.iop == &iostack[0] ||
00136 lseek(e.iop->argp->afile, 0L, 1) != -1)) {
00137 if (++bufid == AFID_NOBUF)
00138 bufid = AFID_ID;
00139 e.iop->argp->afid = bufid;
00140 }
00141 }
00142
00143 e.iop->prev = ~'\n';
00144 e.iop->peekc = 0;
00145 e.iop->xchar = 0;
00146 e.iop->nlcount = 0;
00147 if (fn == filechar || fn == linechar)
00148 e.iop->task = XIO;
00149 else if (fn == gravechar || fn == qgravechar)
00150 e.iop->task = XGRAVE;
00151 else
00152 e.iop->task = XOTHER;
00153 }
00154
00155 struct io *
00156 setbase(ip)
00157 struct io *ip;
00158 {
00159 register struct io *xp;
00160
00161 xp = e.iobase;
00162 e.iobase = ip;
00163 return(xp);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 int
00174 nlchar(ap)
00175 register struct ioarg *ap;
00176 {
00177 register int c;
00178
00179 if (ap->aword == NULL)
00180 return(0);
00181 if ((c = *ap->aword++) == 0) {
00182 ap->aword = NULL;
00183 return('\n');
00184 }
00185 return(c);
00186 }
00187
00188
00189
00190
00191
00192 int
00193 wdchar(ap)
00194 register struct ioarg *ap;
00195 {
00196 register char c;
00197 register char **wl;
00198
00199 if ((wl = ap->awordlist) == NULL)
00200 return(0);
00201 if (*wl != NULL) {
00202 if ((c = *(*wl)++) != 0)
00203 return(c & 0177);
00204 ap->awordlist++;
00205 return(' ');
00206 }
00207 ap->awordlist = NULL;
00208 return('\n');
00209 }
00210
00211
00212
00213
00214
00215 int
00216 dolchar(ap)
00217 register struct ioarg *ap;
00218 {
00219 register char *wp;
00220
00221 if ((wp = *ap->awordlist++) != NULL) {
00222 PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
00223 return(-1);
00224 }
00225 return(0);
00226 }
00227
00228 static int
00229 xxchar(ap)
00230 register struct ioarg *ap;
00231 {
00232 register int c;
00233
00234 if (ap->aword == NULL)
00235 return(0);
00236 if ((c = *ap->aword++) == '\0') {
00237 ap->aword = NULL;
00238 return(' ');
00239 }
00240 return(c);
00241 }
00242
00243
00244
00245
00246 int
00247 strchar(ap)
00248 register struct ioarg *ap;
00249 {
00250 register int c;
00251
00252 if (ap->aword == NULL || (c = *ap->aword++) == 0)
00253 return(0);
00254 return(c);
00255 }
00256
00257
00258
00259
00260 int
00261 qstrchar(ap)
00262 register struct ioarg *ap;
00263 {
00264 register int c;
00265
00266 if (ap->aword == NULL || (c = *ap->aword++) == 0)
00267 return(0);
00268 return(c|QUOTE);
00269 }
00270
00271
00272
00273
00274 int
00275 filechar(ap)
00276 register struct ioarg *ap;
00277 {
00278 register int i;
00279 char c;
00280 struct iobuf *bp = ap->afbuf;
00281
00282 if (ap->afid != AFID_NOBUF) {
00283 if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
00284 if (i)
00285 lseek(ap->afile, ap->afpos, 0);
00286 do {
00287 i = read(ap->afile, bp->buf, sizeof(bp->buf));
00288 } while (i < 0 && errno == EINTR);
00289 if (i <= 0) {
00290 closef(ap->afile);
00291 return 0;
00292 }
00293 bp->id = ap->afid;
00294 bp->ebufp = (bp->bufp = bp->buf) + i;
00295 }
00296 ap->afpos++;
00297 return *bp->bufp++ & 0177;
00298 }
00299
00300 do {
00301 i = read(ap->afile, &c, sizeof(c));
00302 } while (i < 0 && errno == EINTR);
00303 return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
00304 }
00305
00306
00307
00308
00309 int
00310 herechar(ap)
00311 register struct ioarg *ap;
00312 {
00313 char c;
00314
00315
00316 if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
00317 close(ap->afile);
00318 c = 0;
00319 }
00320 return (c);
00321
00322 }
00323
00324
00325
00326
00327
00328 int
00329 gravechar(ap, iop)
00330 struct ioarg *ap;
00331 struct io *iop;
00332 {
00333 register int c;
00334
00335 if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
00336 c = ' ';
00337 return(c);
00338 }
00339
00340 int
00341 qgravechar(ap, iop)
00342 register struct ioarg *ap;
00343 struct io *iop;
00344 {
00345 register int c;
00346
00347 if (iop->xchar) {
00348 if (iop->nlcount) {
00349 iop->nlcount--;
00350 return('\n'|QUOTE);
00351 }
00352 c = iop->xchar;
00353 iop->xchar = 0;
00354 } else if ((c = filechar(ap)) == '\n') {
00355 iop->nlcount = 1;
00356 while ((c = filechar(ap)) == '\n')
00357 iop->nlcount++;
00358 iop->xchar = c;
00359 if (c == 0)
00360 return(c);
00361 iop->nlcount--;
00362 c = '\n';
00363 }
00364 return(c!=0? c|QUOTE: 0);
00365 }
00366
00367
00368
00369
00370 int
00371 linechar(ap)
00372 register struct ioarg *ap;
00373 {
00374 register int c;
00375
00376 if ((c = filechar(ap)) == '\n') {
00377 if (!multiline) {
00378 closef(ap->afile);
00379 ap->afile = -1;
00380 }
00381 }
00382 return(c);
00383 }
00384
00385 void
00386 prs(s)
00387 register char *s;
00388 {
00389 if (*s)
00390 write(2, s, strlen(s));
00391 }
00392
00393 void
00394 putc(c)
00395 char c;
00396 {
00397 write(2, &c, sizeof c);
00398 }
00399
00400 void
00401 prn(u)
00402 unsigned u;
00403 {
00404 prs(itoa(u, 0));
00405 }
00406
00407 void
00408 closef(i)
00409 register int i;
00410 {
00411 if (i > 2)
00412 close(i);
00413 }
00414
00415 void
00416 closeall()
00417 {
00418 register u;
00419
00420 for (u=NUFILE; u<NOFILE;)
00421 close(u++);
00422 }
00423
00424
00425
00426
00427 int
00428 remap(fd)
00429 register int fd;
00430 {
00431 register int i;
00432 int map[NOFILE];
00433
00434 if (fd < e.iofd) {
00435 for (i=0; i<NOFILE; i++)
00436 map[i] = 0;
00437 do {
00438 map[fd] = 1;
00439 fd = dup(fd);
00440 } while (fd >= 0 && fd < e.iofd);
00441 for (i=0; i<NOFILE; i++)
00442 if (map[i])
00443 close(i);
00444 if (fd < 0)
00445 err("too many files open in shell");
00446 }
00447 return(fd);
00448 }
00449
00450 int
00451 openpipe(pv)
00452 register int *pv;
00453 {
00454 register int i;
00455
00456 if ((i = pipe(pv)) < 0)
00457 err("can't create pipe - try again");
00458 return(i);
00459 }
00460
00461 void
00462 closepipe(pv)
00463 register int *pv;
00464 {
00465 if (pv != NULL) {
00466 close(*pv++);
00467 close(*pv);
00468 }
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478 struct here {
00479 char *h_tag;
00480 int h_dosub;
00481 struct ioword *h_iop;
00482 struct here *h_next;
00483 };
00484
00485 static struct here *inhere;
00486 static struct here *acthere;
00487
00488 void
00489 inithere()
00490 {
00491 inhere=acthere=(struct here*)0;
00492 }
00493
00494 void
00495 markhere(s, iop)
00496 register char *s;
00497 struct ioword *iop;
00498 {
00499 register struct here *h, *lh;
00500
00501 h = (struct here *) space(sizeof(struct here));
00502 if (h == 0)
00503 return;
00504 h->h_tag = evalstr(s, DOSUB);
00505 if (h->h_tag == 0)
00506 return;
00507 h->h_iop = iop;
00508 iop->io_name = 0;
00509 h->h_next = NULL;
00510 if (inhere == 0)
00511 inhere = h;
00512 else
00513 for (lh = inhere; lh!=NULL; lh = lh->h_next)
00514 if (lh->h_next == 0) {
00515 lh->h_next = h;
00516 break;
00517 }
00518 iop->io_flag |= IOHERE|IOXHERE;
00519 for (s = h->h_tag; *s; s++)
00520 if (*s & QUOTE) {
00521 iop->io_flag &= ~ IOXHERE;
00522 *s &= ~ QUOTE;
00523 }
00524 h->h_dosub = iop->io_flag & IOXHERE;
00525 }
00526
00527 void
00528 gethere()
00529 {
00530 register struct here *h, *hp;
00531
00532
00533 for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
00534 readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
00535
00536
00537 if (hp != NULL) {
00538 hp->h_next = acthere;
00539 acthere = inhere;
00540 inhere = NULL;
00541 }
00542 }
00543
00544 static void
00545 readhere(name, s, ec)
00546 char **name;
00547 register char *s;
00548 int ec;
00549 {
00550 int tf;
00551 char tname[30];
00552 register c;
00553 jmp_buf ev;
00554 char line [LINELIM+1];
00555 char *next;
00556
00557 tempname(tname);
00558 *name = strsave(tname, areanum);
00559 tf = creat(tname, 0600);
00560 if (tf < 0)
00561 return;
00562 if (newenv(setjmp(errpt = ev)) != 0)
00563 unlink(tname);
00564 else {
00565 pushio(e.iop->argp, e.iop->iofn);
00566 e.iobase = e.iop;
00567 for (;;) {
00568 if (talking && e.iop <= iostack)
00569 prs(cprompt->value);
00570 next = line;
00571 while ((c = readc()) != '\n' && c) {
00572 if (next >= &line[LINELIM]) {
00573 c = 0;
00574 break;
00575 }
00576 *next++ = c;
00577 }
00578 *next = 0;
00579 if (strcmp(s, line) == 0 || c == 0)
00580 break;
00581 *next++ = '\n';
00582 write (tf, line, (int)(next-line));
00583 }
00584 if (c == 0) {
00585 prs("here document `"); prs(s); err("' unclosed");
00586 }
00587 quitenv();
00588 }
00589 close(tf);
00590 }
00591
00592
00593
00594
00595
00596 int
00597 herein(hname, xdoll)
00598 char *hname;
00599 int xdoll;
00600 {
00601 register hf, tf;
00602
00603 if (hname == 0)
00604 return(-1);
00605 hf = open(hname, 0);
00606 if (hf < 0)
00607 return (-1);
00608 if (xdoll) {
00609 char c;
00610 char tname[30];
00611 jmp_buf ev;
00612
00613 tempname(tname);
00614 if ((tf = creat(tname, 0600)) < 0)
00615 return (-1);
00616 if (newenv(setjmp(errpt = ev)) == 0) {
00617 PUSHIO(afile, hf, herechar);
00618 setbase(e.iop);
00619 while ((c = subgetc(0, 0)) != 0) {
00620 char c1 = c&~QUOTE;
00621
00622 if (c"E && !any(c1,"`$\\"))
00623 write(tf,"\\",1);
00624 write(tf, &c1, 1);
00625 }
00626 quitenv();
00627 } else
00628 unlink(tname);
00629 close(tf);
00630 tf = open(tname, 0);
00631 unlink(tname);
00632 return (tf);
00633 } else
00634 return (hf);
00635 }
00636
00637 void
00638 scraphere()
00639 {
00640 register struct here *h;
00641
00642 for (h = inhere; h != NULL; h = h->h_next) {
00643 if (h->h_iop && h->h_iop->io_name)
00644 unlink(h->h_iop->io_name);
00645 }
00646 inhere = NULL;
00647 }
00648
00649
00650 void
00651 freehere(area)
00652 int area;
00653 {
00654 register struct here *h, *hl;
00655
00656 hl = NULL;
00657 for (h = acthere; h != NULL; h = h->h_next)
00658 if (getarea((char *) h) >= area) {
00659 if (h->h_iop->io_name != NULL)
00660 unlink(h->h_iop->io_name);
00661 if (hl == NULL)
00662 acthere = h->h_next;
00663 else
00664 hl->h_next = h->h_next;
00665 } else
00666 hl = h;
00667 }
00668
00669 void
00670 tempname(tname)
00671 char *tname;
00672 {
00673 static int inc;
00674 register char *cp, *lp;
00675
00676 for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
00677 ;
00678 lp = putn(getpid()*1000 + inc++);
00679 for (; (*cp = *lp++) != '\0'; cp++)
00680 ;
00681 }