void setlist(register struct argnod *arg, int xp) { if (flags & exportflg) xp |= N_EXPORT; while (arg) { register unsigned char *s = mactrim(arg->argval); setname(s, xp); arg = arg->argnxt; if (flags & execpr) { prs(s); if (arg) blank(); else newline(); } } }
void copy(IOPTR ioparg) { CHAR c, *ends; register CHAR *cline, *clinep; int fd; register IOPTR iop; if (iop = ioparg) { copy(iop->iolst); ends = mactrim(iop->ioname); if (nosubst) iop->iofile &= ~IODOC; fd = tmpfil(); iop->ioname = cpystak(tmpout); iop->iolst = iotemp; iotemp = iop; cline = locstak(); for (;;) { clinep = cline; chkpr(NL); while ((c = (nosubst ? readc() : nextc(*ends)),!eolchar(c))) { *clinep++ = c; } *clinep = 0; if (eof || eq(cline, ends)) break; *clinep++ = NL; write(fd, cline, clinep - cline); } close(fd); } }
/* * service routines for `execute' */ short initio(struct ionod *iop, int save) { unsigned char *ion; int iof, fd; int ioufd; short lastfd; int newmode; lastfd = topfd; while (iop) { iof = iop->iofile; ion = mactrim(iop->ioname); ioufd = iof & IOUFD; if (*ion && (flags&noexec) == 0) { if (save) { fdmap[topfd].org_fd = ioufd; fdmap[topfd++].dup_fd = savefd(ioufd); } if (iof & IODOC) { struct tempblk tb; subst(chkopen(ion, 0), (fd = tmpfil(&tb))); /* * pushed in tmpfil() -- * bug fix for problem with * in-line scripts */ poptemp(); fd = chkopen(tmpout, 0); unlink((const char *)tmpout); } else if (iof & IOMOV) { if (eq(minus, ion)) { fd = -1; close(ioufd); } else if ((fd = stoi(ion)) >= USERIO) { failed(ion, badfile); } else fd = dup(fd); } else if (((iof & IOPUT) == 0) && ((iof & IORDW) == 0)) fd = chkopen(ion, 0); else if (iof & IORDW) /* For <> */ { newmode = O_RDWR|O_CREAT; fd = chkopen(ion, newmode); } else if (flags & rshflg) { failed(ion, restricted); } else if (iof & IOAPP && (fd = open((char *)ion, 1)) >= 0) { lseek(fd, (off_t)0, SEEK_END); } else { fd = create(ion); } if (fd >= 0) renamef(fd, ioufd); } iop = iop->ionxt; } return (lastfd); }
int execute(TREPTR argt, int execflg, int *pf1, int *pf2) { /* `stakbot' is preserved by this routine */ register TREPTR t; STKPTR sav = savstak(); sigchk(); if ((t = argt) && execbrk == 0) { register int treeflgs; int oldexit, type; register char **com; treeflgs = t->tretyp; type = treeflgs & COMMSK; oldexit = exitval; exitval = 0; switch (type) { case TCOM: { STRING a1; int argn, internal; ARGPTR schain = gchain; IOPTR io = t->treio; gchain = 0; argn = getarg((void *)t);/*FIXME*/ com = scan(argn); a1 = com[1]; gchain = schain; if ((internal = syslook(com[0], commands)) || argn == 0) setlist(((COMPTR) t)->comset, 0); if (argn && (flags & noexec) == 0) { /* print command if execpr */ if (flags & execpr) { argn = 0; prs(execpmsg); while (com[argn] != ENDARGS) { prs(com[argn++]); blank(); } newline(); } switch (internal) { case SYSDOT: if (a1) { register int f; if ((f = pathopen(getpath(a1), a1)) < 0) failed(a1, notfound); else execexp(0, f); } break; case SYSTIMES: { struct tms t; times(&t); prt(t.tms_cutime); blank(); prt(t.tms_cstime); newline(); } break; case SYSEXIT: exitsh(a1 ? stoi(a1) : oldexit); case SYSNULL: io = 0; break; case SYSCONT: execbrk = -loopcnt; break; case SYSBREAK: if ((execbrk = loopcnt) && a1) breakcnt = stoi(a1); break; case SYSTRAP: if (a1) { BOOL clear; if ((clear = digit(*a1)) == 0) ++com; while (*++com) { int i; if ((i = stoi(*com)) >= MAXTRAP || i < MINTRAP) failed(*com, badtrap); else if (clear) clrsig(i); else { replace(&trapcom[i], a1); if (*a1) getsig(i); else ignsig(i); } } } else { /* print out current traps */ int i; for (i = 0; i < MAXTRAP; i++) { if (trapcom[i]) { prn(i); prs(colon); prs(trapcom[i]); newline(); } } } break; case SYSEXEC: com++; initio(io); ioset = 0; io = 0; if (a1 == 0) break; case SYSLOGIN: flags |= forked; oldsigs(); execa((const char **)com); done(); case SYSCD: if (flags & rshflg) failed(com[0], restricted); else if ((a1 == 0 && (a1 = (char *)homenod.namval) == 0) || chdir(a1) < 0) /* FIXME */ failed(a1, baddir); break; case SYSSHFT: if (dolc < 1) error(badshift); else { dolv++; dolc--; } assnum(&dolladr, dolc); break; case SYSWAIT: await(-1); break; case SYSREAD: exitval = readvar(&com[1]); break; /* case SYSTST: exitval=testcmd(com); break; */ case SYSSET: if (a1) { int argc; argc = options(argn, (const char **)com); if (argc > 1) setargs((const char **)com + argn - argc); } else if (((COMPTR) t)->comset == 0) /* Scan name chain and print */ namscan(printnam); break; case SYSRDONLY: exitval = N_RDONLY; case SYSXPORT: if (exitval == 0) exitval = N_EXPORT;; if (a1) { while (*++com) attrib(lookup(*com), exitval); } else { namscan(printflg); } exitval = 0; break; case SYSEVAL: if (a1) execexp(a1, (UFD)&com[2]); /* FIXME */ break; case SYSUMASK: if (a1) { int c, i; i = 0; while ((c = *a1++) >= '0' && c <= '7') i = (i << 3) + c - '0'; umask(i); } else { int i, j; umask(i = umask(0)); prc('0'); for (j = 6; j >= 0; j -= 3) prc(((i >> j) & 07) + '0'); newline(); } break; default: internal = builtin(argn, com); } if (internal) { if (io) error(illegal); chktrap(); break; } } else if (t->treio == 0) break; } case TFORK: if (execflg && (treeflgs & (FAMP | FPOU)) == 0) parent = 0; else { while ((parent = fork()) == -1) { sigchk(); alarm(10); pause(); } } if (parent) { /* This is the parent branch of fork; */ /* it may or may not wait for the child. */ if (treeflgs & FPRS && flags & ttyflg) { prn(parent); newline(); } if (treeflgs & FPCL) closepipe(pf1); if ((treeflgs & (FAMP | FPOU)) == 0) await(parent); else if ((treeflgs & FAMP) == 0) post(parent); else assnum(&pcsadr, parent); chktrap(); break; } else { /* this is the forked branch (child) of execute */ flags |= forked; iotemp = 0; postclr(); settmp(); /* Turn off INTR and QUIT if `FINT' */ /* Reset ramaining signals to parent */ /* except for those `lost' by trap */ oldsigs(); if (treeflgs & FINT) { signal(INTR, SIG_IGN); signal(QUIT, SIG_IGN); } /* pipe in or out */ if (treeflgs & FPIN) { sh_rename(pf1[INPIPE], 0); close(pf1[OTPIPE]); } if (treeflgs & FPOU) { sh_rename(pf2[OTPIPE], 1); close(pf2[INPIPE]); } /* default std input for & */ if (treeflgs & FINT && ioset == 0) sh_rename(chkopen(devnull), 0); /* io redirection */ initio(t->treio); if (type != TCOM) execute(((FORKPTR) t)->forktre, 1, NULL, NULL); else if (com[0] != ENDARGS) { setlist(((COMPTR) t)->comset, N_EXPORT); execa((const char **)com); } done(); } case TPAR: sh_rename(dup(2), output); execute(((PARPTR) t)->partre, execflg, NULL, NULL); done(); case TFIL: { int pv[2]; chkpipe(pv); if (execute(((LSTPTR) t)->lstlef, 0, pf1, pv) == 0) execute(((LSTPTR) t)->lstrit, execflg, pv, pf2); else closepipe(pv); break; } case TLST: execute(((LSTPTR) t)->lstlef, 0, NULL, NULL); execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TAND: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) == 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TORF: if (execute(((LSTPTR) t)->lstlef, 0, NULL, NULL) != 0) execute(((LSTPTR) t)->lstrit, execflg, NULL, NULL); break; case TFOR: { NAMPTR n = lookup(((FORPTR) t)->fornam); char **args; DOLPTR argsav = 0; if (((FORPTR) t)->forlst == 0) { args = (char **)dolv + 1; argsav = useargs(); } else { ARGPTR schain = gchain; gchain = 0; trim((args = scan(getarg(((FORPTR) t)->forlst)))[0]); gchain = schain; } loopcnt++; while (*args != ENDARGS && execbrk == 0) { assign(n, *args++); execute(((FORPTR) t)->fortre, 0, NULL, NULL); if (execbrk < 0) { execbrk = 0; } } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; argfor = freeargs(argsav); break; } case TWH: case TUN: { int i = 0; loopcnt++; while (execbrk == 0 && (execute(((WHPTR) t)->whtre, 0, NULL, NULL) == 0) == (type == TWH)) { i = execute(((WHPTR) t)->dotre, 0, NULL, NULL); if (execbrk < 0) execbrk = 0; } if (breakcnt) breakcnt--; execbrk = breakcnt; loopcnt--; exitval = i; break; } case TIF: if (execute(((IFPTR) t)->iftre, 0, NULL, NULL) == 0) execute(((IFPTR) t)->thtre, execflg, NULL, NULL); else execute(((IFPTR) t)->eltre, execflg, NULL, NULL); break; case TSW: { register char *r = mactrim(((SWPTR) t)->swarg); t = (TREPTR) ((SWPTR) t)->swlst; while (t) { ARGPTR rex = ((REGPTR) t)->regptr; while (rex) { register char *s; if (gmatch(r, s = macro(rex->argval)) || (trim(s), eq(r, s))) { execute(((REGPTR)t)->regcom, 0, NULL, NULL); t = 0; break; } else rex = ((ARGPTR)rex)->argnxt; } if (t) t = (TREPTR) ((REGPTR) t)->regnxt; } } break; } exitset(); }
void copy(struct ionod *ioparg) { unsigned char *cline; unsigned char *clinep; struct ionod *iop; unsigned int c; unsigned char *ends; unsigned char *start; int fd; int i; int stripflg; unsigned char *pc; if (iop = ioparg) { struct tempblk tb; copy(iop->iolst); ends = mactrim(iop->ioname); stripflg = iop->iofile & IOSTRIP; if (nosubst) iop->iofile &= ~IODOC; fd = tmpfil(&tb); if (fndef) iop->ioname = (char *) make(tmpout); else iop->ioname = (char *) cpystak(tmpout); iop->iolst = iotemp; iotemp = iop; cline = clinep = start = locstak(); if (stripflg) { iop->iofile &= ~IOSTRIP; while (*ends == '\t') ends++; } for (;;) { chkpr(); if (nosubst) { c = readwc(); if (stripflg) while (c == '\t') c = readwc(); while (!eolchar(c)) { pc = readw(c); while (*pc) { if (clinep >= brkend) growstak(clinep); *clinep++ = *pc++; } c = readwc(); } }else{ c = nextwc(); if (stripflg) while (c == '\t') c = nextwc(); while (!eolchar(c)) { pc = readw(c); while (*pc) { if (clinep >= brkend) growstak(clinep); *clinep++ = *pc++; } if (c == '\\') { pc = readw(readwc()); /* *pc might be NULL */ if (*pc) { while (*pc) { if (clinep >= brkend) growstak(clinep); *clinep++ = *pc++; } } else { if (clinep >= brkend) growstak(clinep); *clinep++ = *pc; } } c = nextwc(); } } if (clinep >= brkend) growstak(clinep); *clinep = 0; if (eof || eq(cline, ends)) { if ((i = cline - start) > 0) write(fd, start, i); break; }else{ if (clinep >= brkend) growstak(clinep); *clinep++ = NL; } if ((i = clinep - start) < CPYSIZ) cline = clinep; else { write(fd, start, i); cline = clinep = start; } } poptemp(); /* * pushed in tmpfil -- bug fix for problem * deleting in-line scripts */ } }