13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * Maybe `simple' is a misnomer. 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include "rc.h" 53e12c5d1SDavid du Colombier #include "getflags.h" 63e12c5d1SDavid du Colombier #include "exec.h" 73e12c5d1SDavid du Colombier #include "io.h" 83e12c5d1SDavid du Colombier #include "fns.h" 93e12c5d1SDavid du Colombier /* 103e12c5d1SDavid du Colombier * Search through the following code to see if we're just going to exit. 113e12c5d1SDavid du Colombier */ 12d3907fe5SDavid du Colombier int 1399eb86a7SDavid du Colombier exitnext(void){ 143e12c5d1SDavid du Colombier union code *c=&runq->code[runq->pc]; 1599eb86a7SDavid du Colombier while(c->f==Xpopredir) c++; 163e12c5d1SDavid du Colombier return c->f==Xexit; 173e12c5d1SDavid du Colombier } 18dc5a79c1SDavid du Colombier 19dc5a79c1SDavid du Colombier void 20dc5a79c1SDavid du Colombier Xsimple(void) 21dc5a79c1SDavid du Colombier { 223e12c5d1SDavid du Colombier word *a; 233e12c5d1SDavid du Colombier thread *p = runq; 243e12c5d1SDavid du Colombier var *v; 253e12c5d1SDavid du Colombier struct builtin *bp; 26dc5a79c1SDavid du Colombier int pid; 273e12c5d1SDavid du Colombier globlist(); 283e12c5d1SDavid du Colombier a = runq->argv->words; 293e12c5d1SDavid du Colombier if(a==0){ 309a747e4fSDavid du Colombier Xerror1("empty argument list"); 313e12c5d1SDavid du Colombier return; 323e12c5d1SDavid du Colombier } 333e12c5d1SDavid du Colombier if(flag['x']) 343e12c5d1SDavid du Colombier pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ 353e12c5d1SDavid du Colombier v = gvlook(a->word); 363e12c5d1SDavid du Colombier if(v->fn) 373e12c5d1SDavid du Colombier execfunc(v); 383e12c5d1SDavid du Colombier else{ 393e12c5d1SDavid du Colombier if(strcmp(a->word, "builtin")==0){ 403e12c5d1SDavid du Colombier if(count(a)==1){ 413e12c5d1SDavid du Colombier pfmt(err, "builtin: empty argument list\n"); 423e12c5d1SDavid du Colombier setstatus("empty arg list"); 433e12c5d1SDavid du Colombier poplist(); 443e12c5d1SDavid du Colombier return; 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier a = a->next; 473e12c5d1SDavid du Colombier popword(); 483e12c5d1SDavid du Colombier } 493e12c5d1SDavid du Colombier for(bp = Builtin;bp->name;bp++) 503e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){ 513e12c5d1SDavid du Colombier (*bp->fnc)(); 523e12c5d1SDavid du Colombier return; 533e12c5d1SDavid du Colombier } 543e12c5d1SDavid du Colombier if(exitnext()){ 553e12c5d1SDavid du Colombier /* fork and wait is redundant */ 563e12c5d1SDavid du Colombier pushword("exec"); 573e12c5d1SDavid du Colombier execexec(); 583e12c5d1SDavid du Colombier Xexit(); 593e12c5d1SDavid du Colombier } 603e12c5d1SDavid du Colombier else{ 613e12c5d1SDavid du Colombier flush(err); 629a747e4fSDavid du Colombier Updenv(); /* necessary so changes don't go out again */ 63dc5a79c1SDavid du Colombier if((pid = execforkexec()) < 0){ 647dd7cddfSDavid du Colombier Xerror("try again"); 653e12c5d1SDavid du Colombier return; 66dc5a79c1SDavid du Colombier } 67dc5a79c1SDavid du Colombier 683e12c5d1SDavid du Colombier /* interrupts don't get us out */ 69dc5a79c1SDavid du Colombier poplist(); 703e12c5d1SDavid du Colombier while(Waitfor(pid, 1) < 0) 713e12c5d1SDavid du Colombier ; 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier struct word nullpath = { "", 0}; 76dc5a79c1SDavid du Colombier 77dc5a79c1SDavid du Colombier void 78dc5a79c1SDavid du Colombier doredir(redir *rp) 793e12c5d1SDavid du Colombier { 803e12c5d1SDavid du Colombier if(rp){ 813e12c5d1SDavid du Colombier doredir(rp->next); 823e12c5d1SDavid du Colombier switch(rp->type){ 833e12c5d1SDavid du Colombier case ROPEN: 843e12c5d1SDavid du Colombier if(rp->from!=rp->to){ 853e12c5d1SDavid du Colombier Dup(rp->from, rp->to); 863e12c5d1SDavid du Colombier close(rp->from); 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier break; 89dc5a79c1SDavid du Colombier case RDUP: 90dc5a79c1SDavid du Colombier Dup(rp->from, rp->to); 91dc5a79c1SDavid du Colombier break; 92dc5a79c1SDavid du Colombier case RCLOSE: 93dc5a79c1SDavid du Colombier close(rp->from); 94dc5a79c1SDavid du Colombier break; 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier } 98dc5a79c1SDavid du Colombier 99dc5a79c1SDavid du Colombier word* 100dc5a79c1SDavid du Colombier searchpath(char *w) 101dc5a79c1SDavid du Colombier { 1023e12c5d1SDavid du Colombier word *path; 1033e12c5d1SDavid du Colombier if(strncmp(w, "/", 1)==0 1043e12c5d1SDavid du Colombier || strncmp(w, "#", 1)==0 1053e12c5d1SDavid du Colombier || strncmp(w, "./", 2)==0 1063e12c5d1SDavid du Colombier || strncmp(w, "../", 3)==0 1073e12c5d1SDavid du Colombier || (path = vlook("path")->val)==0) 1083e12c5d1SDavid du Colombier path=&nullpath; 1093e12c5d1SDavid du Colombier return path; 1103e12c5d1SDavid du Colombier } 111dc5a79c1SDavid du Colombier 112dc5a79c1SDavid du Colombier void 113dc5a79c1SDavid du Colombier execexec(void) 114dc5a79c1SDavid du Colombier { 1153e12c5d1SDavid du Colombier popword(); /* "exec" */ 1163e12c5d1SDavid du Colombier if(runq->argv->words==0){ 1179a747e4fSDavid du Colombier Xerror1("empty argument list"); 1183e12c5d1SDavid du Colombier return; 1193e12c5d1SDavid du Colombier } 1203e12c5d1SDavid du Colombier doredir(runq->redir); 1213e12c5d1SDavid du Colombier Execute(runq->argv->words, searchpath(runq->argv->words->word)); 1223e12c5d1SDavid du Colombier poplist(); 1233e12c5d1SDavid du Colombier } 124dc5a79c1SDavid du Colombier 125dc5a79c1SDavid du Colombier void 126dc5a79c1SDavid du Colombier execfunc(var *func) 1273e12c5d1SDavid du Colombier { 1283e12c5d1SDavid du Colombier word *starval; 1293e12c5d1SDavid du Colombier popword(); 1303e12c5d1SDavid du Colombier starval = runq->argv->words; 1313e12c5d1SDavid du Colombier runq->argv->words = 0; 1323e12c5d1SDavid du Colombier poplist(); 133*7c6618bfSDavid du Colombier start(func->fn, func->pc, runq->local); 1343e12c5d1SDavid du Colombier runq->local = newvar(strdup("*"), runq->local); 1353e12c5d1SDavid du Colombier runq->local->val = starval; 1363e12c5d1SDavid du Colombier runq->local->changed = 1; 1373e12c5d1SDavid du Colombier } 138dc5a79c1SDavid du Colombier 139dc5a79c1SDavid du Colombier int 140dc5a79c1SDavid du Colombier dochdir(char *word) 141dc5a79c1SDavid du Colombier { 1427dd7cddfSDavid du Colombier /* report to /dev/wdir if it exists and we're interactive */ 1437dd7cddfSDavid du Colombier static int wdirfd = -2; 1447dd7cddfSDavid du Colombier if(chdir(word)<0) return -1; 1457dd7cddfSDavid du Colombier if(flag['i']!=0){ 1467dd7cddfSDavid du Colombier if(wdirfd==-2) /* try only once */ 1477dd7cddfSDavid du Colombier wdirfd = open("/dev/wdir", OWRITE|OCEXEC); 1487dd7cddfSDavid du Colombier if(wdirfd>=0) 1497dd7cddfSDavid du Colombier write(wdirfd, word, strlen(word)); 1507dd7cddfSDavid du Colombier } 1517dd7cddfSDavid du Colombier return 1; 1527dd7cddfSDavid du Colombier } 153dc5a79c1SDavid du Colombier 154dc5a79c1SDavid du Colombier void 155dc5a79c1SDavid du Colombier execcd(void) 156dc5a79c1SDavid du Colombier { 1573e12c5d1SDavid du Colombier word *a = runq->argv->words; 1583e12c5d1SDavid du Colombier word *cdpath; 159276e7d6dSDavid du Colombier char *dir; 160276e7d6dSDavid du Colombier 1613e12c5d1SDavid du Colombier setstatus("can't cd"); 1623e12c5d1SDavid du Colombier cdpath = vlook("cdpath")->val; 1633e12c5d1SDavid du Colombier switch(count(a)){ 1643e12c5d1SDavid du Colombier default: 1653e12c5d1SDavid du Colombier pfmt(err, "Usage: cd [directory]\n"); 1663e12c5d1SDavid du Colombier break; 1673e12c5d1SDavid du Colombier case 2: 168dc5a79c1SDavid du Colombier if(a->next->word[0]=='/' || cdpath==0) 169dc5a79c1SDavid du Colombier cdpath = &nullpath; 1703e12c5d1SDavid du Colombier for(; cdpath; cdpath = cdpath->next){ 171276e7d6dSDavid du Colombier if(cdpath->word[0] != '\0') 172276e7d6dSDavid du Colombier dir = smprint("%s/%s", cdpath->word, 173276e7d6dSDavid du Colombier a->next->word); 174276e7d6dSDavid du Colombier else 175276e7d6dSDavid du Colombier dir = strdup(a->next->word); 176276e7d6dSDavid du Colombier 1777dd7cddfSDavid du Colombier if(dochdir(dir) >= 0){ 178276e7d6dSDavid du Colombier if(cdpath->word[0] != '\0' && 179276e7d6dSDavid du Colombier strcmp(cdpath->word, ".") != 0) 1803e12c5d1SDavid du Colombier pfmt(err, "%s\n", dir); 181276e7d6dSDavid du Colombier free(dir); 1823e12c5d1SDavid du Colombier setstatus(""); 1833e12c5d1SDavid du Colombier break; 1843e12c5d1SDavid du Colombier } 185276e7d6dSDavid du Colombier free(dir); 1863e12c5d1SDavid du Colombier } 187dc5a79c1SDavid du Colombier if(cdpath==0) 188dc5a79c1SDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->next->word); 1893e12c5d1SDavid du Colombier break; 1903e12c5d1SDavid du Colombier case 1: 1913e12c5d1SDavid du Colombier a = vlook("home")->val; 1923e12c5d1SDavid du Colombier if(count(a)>=1){ 1937dd7cddfSDavid du Colombier if(dochdir(a->word)>=0) 1943e12c5d1SDavid du Colombier setstatus(""); 1953e12c5d1SDavid du Colombier else 1969a747e4fSDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->word); 1973e12c5d1SDavid du Colombier } 1983e12c5d1SDavid du Colombier else 1993e12c5d1SDavid du Colombier pfmt(err, "Can't cd -- $home empty\n"); 2003e12c5d1SDavid du Colombier break; 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier poplist(); 2033e12c5d1SDavid du Colombier } 204dc5a79c1SDavid du Colombier 205dc5a79c1SDavid du Colombier void 206dc5a79c1SDavid du Colombier execexit(void) 207dc5a79c1SDavid du Colombier { 2083e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 209dc5a79c1SDavid du Colombier default: 210dc5a79c1SDavid du Colombier pfmt(err, "Usage: exit [status]\nExiting anyway\n"); 211dc5a79c1SDavid du Colombier case 2: 212dc5a79c1SDavid du Colombier setstatus(runq->argv->words->next->word); 2133e12c5d1SDavid du Colombier case 1: Xexit(); 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier } 216dc5a79c1SDavid du Colombier 217dc5a79c1SDavid du Colombier void 218dc5a79c1SDavid du Colombier execshift(void) 219dc5a79c1SDavid du Colombier { 2203e12c5d1SDavid du Colombier int n; 2213e12c5d1SDavid du Colombier word *a; 2223e12c5d1SDavid du Colombier var *star; 2233e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 2243e12c5d1SDavid du Colombier default: 2253e12c5d1SDavid du Colombier pfmt(err, "Usage: shift [n]\n"); 2263e12c5d1SDavid du Colombier setstatus("shift usage"); 2273e12c5d1SDavid du Colombier poplist(); 2283e12c5d1SDavid du Colombier return; 229dc5a79c1SDavid du Colombier case 2: 230dc5a79c1SDavid du Colombier n = atoi(runq->argv->words->next->word); 231dc5a79c1SDavid du Colombier break; 232dc5a79c1SDavid du Colombier case 1: 233dc5a79c1SDavid du Colombier n = 1; 234dc5a79c1SDavid du Colombier break; 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier star = vlook("*"); 2373e12c5d1SDavid du Colombier for(;n && star->val;--n){ 2383e12c5d1SDavid du Colombier a = star->val->next; 2393e12c5d1SDavid du Colombier efree(star->val->word); 2403e12c5d1SDavid du Colombier efree((char *)star->val); 2413e12c5d1SDavid du Colombier star->val = a; 2423e12c5d1SDavid du Colombier star->changed = 1; 2433e12c5d1SDavid du Colombier } 2443e12c5d1SDavid du Colombier setstatus(""); 2453e12c5d1SDavid du Colombier poplist(); 2463e12c5d1SDavid du Colombier } 247dc5a79c1SDavid du Colombier 248dc5a79c1SDavid du Colombier int 249dc5a79c1SDavid du Colombier octal(char *s) 2503e12c5d1SDavid du Colombier { 2513e12c5d1SDavid du Colombier int n = 0; 2523e12c5d1SDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n') s++; 2533e12c5d1SDavid du Colombier while('0'<=*s && *s<='7') n = n*8+*s++-'0'; 2543e12c5d1SDavid du Colombier return n; 2553e12c5d1SDavid du Colombier } 256dc5a79c1SDavid du Colombier 257dc5a79c1SDavid du Colombier int 258dc5a79c1SDavid du Colombier mapfd(int fd) 2593e12c5d1SDavid du Colombier { 2603e12c5d1SDavid du Colombier redir *rp; 2613e12c5d1SDavid du Colombier for(rp = runq->redir;rp;rp = rp->next){ 2623e12c5d1SDavid du Colombier switch(rp->type){ 2633e12c5d1SDavid du Colombier case RCLOSE: 264dc5a79c1SDavid du Colombier if(rp->from==fd) 265dc5a79c1SDavid du Colombier fd=-1; 2663e12c5d1SDavid du Colombier break; 2673e12c5d1SDavid du Colombier case RDUP: 2683e12c5d1SDavid du Colombier case ROPEN: 269dc5a79c1SDavid du Colombier if(rp->to==fd) 270dc5a79c1SDavid du Colombier fd = rp->from; 2713e12c5d1SDavid du Colombier break; 2723e12c5d1SDavid du Colombier } 2733e12c5d1SDavid du Colombier } 2743e12c5d1SDavid du Colombier return fd; 2753e12c5d1SDavid du Colombier } 2763e12c5d1SDavid du Colombier union code rdcmds[4]; 277dc5a79c1SDavid du Colombier 278dc5a79c1SDavid du Colombier void 279dc5a79c1SDavid du Colombier execcmds(io *f) 2803e12c5d1SDavid du Colombier { 2813e12c5d1SDavid du Colombier static int first = 1; 2823e12c5d1SDavid du Colombier if(first){ 2833e12c5d1SDavid du Colombier rdcmds[0].i = 1; 2843e12c5d1SDavid du Colombier rdcmds[1].f = Xrdcmds; 2853e12c5d1SDavid du Colombier rdcmds[2].f = Xreturn; 2863e12c5d1SDavid du Colombier first = 0; 2873e12c5d1SDavid du Colombier } 2883e12c5d1SDavid du Colombier start(rdcmds, 1, runq->local); 2893e12c5d1SDavid du Colombier runq->cmdfd = f; 2903e12c5d1SDavid du Colombier runq->iflast = 0; 2913e12c5d1SDavid du Colombier } 292dc5a79c1SDavid du Colombier 293dc5a79c1SDavid du Colombier void 294dc5a79c1SDavid du Colombier execeval(void) 295dc5a79c1SDavid du Colombier { 2963e12c5d1SDavid du Colombier char *cmdline, *s, *t; 2973e12c5d1SDavid du Colombier int len = 0; 2983e12c5d1SDavid du Colombier word *ap; 2993e12c5d1SDavid du Colombier if(count(runq->argv->words)<=1){ 3009a747e4fSDavid du Colombier Xerror1("Usage: eval cmd ..."); 3013e12c5d1SDavid du Colombier return; 3023e12c5d1SDavid du Colombier } 303219b2ee8SDavid du Colombier eflagok = 1; 3043e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next) 3053e12c5d1SDavid du Colombier len+=1+strlen(ap->word); 3063e12c5d1SDavid du Colombier cmdline = emalloc(len); 3073e12c5d1SDavid du Colombier s = cmdline; 3083e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next){ 3093e12c5d1SDavid du Colombier for(t = ap->word;*t;) *s++=*t++; 3103e12c5d1SDavid du Colombier *s++=' '; 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier s[-1]='\n'; 3133e12c5d1SDavid du Colombier poplist(); 3143e12c5d1SDavid du Colombier execcmds(opencore(cmdline, len)); 3153e12c5d1SDavid du Colombier efree(cmdline); 3163e12c5d1SDavid du Colombier } 3173e12c5d1SDavid du Colombier union code dotcmds[14]; 318dc5a79c1SDavid du Colombier 319dc5a79c1SDavid du Colombier void 320dc5a79c1SDavid du Colombier execdot(void) 321dc5a79c1SDavid du Colombier { 3223e12c5d1SDavid du Colombier int iflag = 0; 3233e12c5d1SDavid du Colombier int fd; 3243e12c5d1SDavid du Colombier list *av; 3253e12c5d1SDavid du Colombier thread *p = runq; 326276e7d6dSDavid du Colombier char *zero, *file; 3273e12c5d1SDavid du Colombier word *path; 328276e7d6dSDavid du Colombier static int first = 1; 329276e7d6dSDavid du Colombier 3303e12c5d1SDavid du Colombier if(first){ 3313e12c5d1SDavid du Colombier dotcmds[0].i = 1; 3323e12c5d1SDavid du Colombier dotcmds[1].f = Xmark; 3333e12c5d1SDavid du Colombier dotcmds[2].f = Xword; 3343e12c5d1SDavid du Colombier dotcmds[3].s="0"; 3353e12c5d1SDavid du Colombier dotcmds[4].f = Xlocal; 3363e12c5d1SDavid du Colombier dotcmds[5].f = Xmark; 3373e12c5d1SDavid du Colombier dotcmds[6].f = Xword; 3383e12c5d1SDavid du Colombier dotcmds[7].s="*"; 3393e12c5d1SDavid du Colombier dotcmds[8].f = Xlocal; 3403e12c5d1SDavid du Colombier dotcmds[9].f = Xrdcmds; 3413e12c5d1SDavid du Colombier dotcmds[10].f = Xunlocal; 3423e12c5d1SDavid du Colombier dotcmds[11].f = Xunlocal; 3433e12c5d1SDavid du Colombier dotcmds[12].f = Xreturn; 3443e12c5d1SDavid du Colombier first = 0; 3453e12c5d1SDavid du Colombier } 346219b2ee8SDavid du Colombier else 347219b2ee8SDavid du Colombier eflagok = 1; 3483e12c5d1SDavid du Colombier popword(); 3493e12c5d1SDavid du Colombier if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ 3503e12c5d1SDavid du Colombier iflag = 1; 3513e12c5d1SDavid du Colombier popword(); 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier /* get input file */ 3543e12c5d1SDavid du Colombier if(p->argv->words==0){ 3559a747e4fSDavid du Colombier Xerror1("Usage: . [-i] file [arg ...]"); 3563e12c5d1SDavid du Colombier return; 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier zero = strdup(p->argv->words->word); 3593e12c5d1SDavid du Colombier popword(); 3607dd7cddfSDavid du Colombier fd = -1; 3613e12c5d1SDavid du Colombier for(path = searchpath(zero); path; path = path->next){ 362276e7d6dSDavid du Colombier if(path->word[0] != '\0') 363276e7d6dSDavid du Colombier file = smprint("%s/%s", path->word, zero); 364276e7d6dSDavid du Colombier else 365276e7d6dSDavid du Colombier file = strdup(zero); 366276e7d6dSDavid du Colombier 367276e7d6dSDavid du Colombier fd = open(file, 0); 368276e7d6dSDavid du Colombier free(file); 369276e7d6dSDavid du Colombier if(fd >= 0) 370276e7d6dSDavid du Colombier break; 3713e12c5d1SDavid du Colombier if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ 3723e12c5d1SDavid du Colombier fd = Dup1(0); 373dc5a79c1SDavid du Colombier if(fd>=0) 374dc5a79c1SDavid du Colombier break; 3753e12c5d1SDavid du Colombier } 3763e12c5d1SDavid du Colombier } 3773e12c5d1SDavid du Colombier if(fd<0){ 3787dd7cddfSDavid du Colombier pfmt(err, "%s: ", zero); 3797dd7cddfSDavid du Colombier setstatus("can't open"); 3807dd7cddfSDavid du Colombier Xerror(".: can't open"); 3813e12c5d1SDavid du Colombier return; 3823e12c5d1SDavid du Colombier } 3833e12c5d1SDavid du Colombier /* set up for a new command loop */ 3843e12c5d1SDavid du Colombier start(dotcmds, 1, (struct var *)0); 3853e12c5d1SDavid du Colombier pushredir(RCLOSE, fd, 0); 3863e12c5d1SDavid du Colombier runq->cmdfile = zero; 3873e12c5d1SDavid du Colombier runq->cmdfd = openfd(fd); 3883e12c5d1SDavid du Colombier runq->iflag = iflag; 3893e12c5d1SDavid du Colombier runq->iflast = 0; 3903e12c5d1SDavid du Colombier /* push $* value */ 3913e12c5d1SDavid du Colombier pushlist(); 3923e12c5d1SDavid du Colombier runq->argv->words = p->argv->words; 3933e12c5d1SDavid du Colombier /* free caller's copy of $* */ 3943e12c5d1SDavid du Colombier av = p->argv; 3953e12c5d1SDavid du Colombier p->argv = av->next; 3963e12c5d1SDavid du Colombier efree((char *)av); 3973e12c5d1SDavid du Colombier /* push $0 value */ 3983e12c5d1SDavid du Colombier pushlist(); 3993e12c5d1SDavid du Colombier pushword(zero); 4003e12c5d1SDavid du Colombier ndot++; 4013e12c5d1SDavid du Colombier } 402dc5a79c1SDavid du Colombier 403dc5a79c1SDavid du Colombier void 404dc5a79c1SDavid du Colombier execflag(void) 405dc5a79c1SDavid du Colombier { 4063e12c5d1SDavid du Colombier char *letter, *val; 4073e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 4083e12c5d1SDavid du Colombier case 2: 409d3907fe5SDavid du Colombier setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set"); 4103e12c5d1SDavid du Colombier break; 4113e12c5d1SDavid du Colombier case 3: 4123e12c5d1SDavid du Colombier letter = runq->argv->words->next->word; 4133e12c5d1SDavid du Colombier val = runq->argv->words->next->next->word; 4143e12c5d1SDavid du Colombier if(strlen(letter)==1){ 4153e12c5d1SDavid du Colombier if(strcmp(val, "+")==0){ 416d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = flagset; 4173e12c5d1SDavid du Colombier break; 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier if(strcmp(val, "-")==0){ 420d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = 0; 4213e12c5d1SDavid du Colombier break; 4223e12c5d1SDavid du Colombier } 4233e12c5d1SDavid du Colombier } 4243e12c5d1SDavid du Colombier default: 4259a747e4fSDavid du Colombier Xerror1("Usage: flag [letter] [+-]"); 4263e12c5d1SDavid du Colombier return; 4273e12c5d1SDavid du Colombier } 4283e12c5d1SDavid du Colombier poplist(); 4293e12c5d1SDavid du Colombier } 430dc5a79c1SDavid du Colombier 431dc5a79c1SDavid du Colombier void 43299eb86a7SDavid du Colombier execwhatis(void){ /* mildly wrong -- should fork before writing */ 4333e12c5d1SDavid du Colombier word *a, *b, *path; 4343e12c5d1SDavid du Colombier var *v; 4353e12c5d1SDavid du Colombier struct builtin *bp; 436276e7d6dSDavid du Colombier char *file; 4373e12c5d1SDavid du Colombier struct io out[1]; 4383e12c5d1SDavid du Colombier int found, sep; 4393e12c5d1SDavid du Colombier a = runq->argv->words->next; 4403e12c5d1SDavid du Colombier if(a==0){ 4419a747e4fSDavid du Colombier Xerror1("Usage: whatis name ..."); 4423e12c5d1SDavid du Colombier return; 4433e12c5d1SDavid du Colombier } 4443e12c5d1SDavid du Colombier setstatus(""); 4453e12c5d1SDavid du Colombier out->fd = mapfd(1); 4463e12c5d1SDavid du Colombier out->bufp = out->buf; 4473e12c5d1SDavid du Colombier out->ebuf = &out->buf[NBUF]; 4483e12c5d1SDavid du Colombier out->strp = 0; 4493e12c5d1SDavid du Colombier for(;a;a = a->next){ 4503e12c5d1SDavid du Colombier v = vlook(a->word); 4513e12c5d1SDavid du Colombier if(v->val){ 4523e12c5d1SDavid du Colombier pfmt(out, "%s=", a->word); 4533e12c5d1SDavid du Colombier if(v->val->next==0) 4543e12c5d1SDavid du Colombier pfmt(out, "%q\n", v->val->word); 4553e12c5d1SDavid du Colombier else{ 4563e12c5d1SDavid du Colombier sep='('; 4573e12c5d1SDavid du Colombier for(b = v->val;b && b->word;b = b->next){ 4583e12c5d1SDavid du Colombier pfmt(out, "%c%q", sep, b->word); 4593e12c5d1SDavid du Colombier sep=' '; 4603e12c5d1SDavid du Colombier } 4613e12c5d1SDavid du Colombier pfmt(out, ")\n"); 4623e12c5d1SDavid du Colombier } 4633e12c5d1SDavid du Colombier found = 1; 4643e12c5d1SDavid du Colombier } 4653e12c5d1SDavid du Colombier else 4663e12c5d1SDavid du Colombier found = 0; 4673e12c5d1SDavid du Colombier v = gvlook(a->word); 468dc5a79c1SDavid du Colombier if(v->fn) 469fed0fa9eSDavid du Colombier pfmt(out, "fn %q %s\n", v->name, v->fn[v->pc-1].s); 4703e12c5d1SDavid du Colombier else{ 4713e12c5d1SDavid du Colombier for(bp = Builtin;bp->name;bp++) 4723e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){ 4733e12c5d1SDavid du Colombier pfmt(out, "builtin %s\n", a->word); 4743e12c5d1SDavid du Colombier break; 4753e12c5d1SDavid du Colombier } 4763e12c5d1SDavid du Colombier if(!bp->name){ 477276e7d6dSDavid du Colombier for(path = searchpath(a->word); path; 478276e7d6dSDavid du Colombier path = path->next){ 479276e7d6dSDavid du Colombier if(path->word[0] != '\0') 480276e7d6dSDavid du Colombier file = smprint("%s/%s", 481276e7d6dSDavid du Colombier path->word, a->word); 482276e7d6dSDavid du Colombier else 483276e7d6dSDavid du Colombier file = strdup(a->word); 4843e12c5d1SDavid du Colombier if(Executable(file)){ 4853e12c5d1SDavid du Colombier pfmt(out, "%s\n", file); 486276e7d6dSDavid du Colombier free(file); 4873e12c5d1SDavid du Colombier break; 4883e12c5d1SDavid du Colombier } 489276e7d6dSDavid du Colombier free(file); 4903e12c5d1SDavid du Colombier } 4913e12c5d1SDavid du Colombier if(!path && !found){ 4923e12c5d1SDavid du Colombier pfmt(err, "%s: not found\n", a->word); 4933e12c5d1SDavid du Colombier setstatus("not found"); 4943e12c5d1SDavid du Colombier } 4953e12c5d1SDavid du Colombier } 4963e12c5d1SDavid du Colombier } 4973e12c5d1SDavid du Colombier } 4983e12c5d1SDavid du Colombier poplist(); 4993e12c5d1SDavid du Colombier flush(err); 5003e12c5d1SDavid du Colombier } 501dc5a79c1SDavid du Colombier 502dc5a79c1SDavid du Colombier void 503dc5a79c1SDavid du Colombier execwait(void) 504dc5a79c1SDavid du Colombier { 5053e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 506dc5a79c1SDavid du Colombier default: 507dc5a79c1SDavid du Colombier Xerror1("Usage: wait [pid]"); 508dc5a79c1SDavid du Colombier return; 509dc5a79c1SDavid du Colombier case 2: 510dc5a79c1SDavid du Colombier Waitfor(atoi(runq->argv->words->next->word), 0); 511dc5a79c1SDavid du Colombier break; 512dc5a79c1SDavid du Colombier case 1: 513dc5a79c1SDavid du Colombier Waitfor(-1, 0); 514dc5a79c1SDavid du Colombier break; 5153e12c5d1SDavid du Colombier } 516219b2ee8SDavid du Colombier poplist(); 5173e12c5d1SDavid du Colombier } 518