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 */ 12*d3907fe5SDavid du Colombier int 133e12c5d1SDavid du Colombier exitnext(void){ 143e12c5d1SDavid du Colombier union code *c=&runq->code[runq->pc]; 153e12c5d1SDavid 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(); 1333e12c5d1SDavid du Colombier start(func->fn, func->pc, (struct var *)0); 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; 1593e12c5d1SDavid du Colombier char dir[512]; 1603e12c5d1SDavid du Colombier setstatus("can't cd"); 1613e12c5d1SDavid du Colombier cdpath = vlook("cdpath")->val; 1623e12c5d1SDavid du Colombier switch(count(a)){ 1633e12c5d1SDavid du Colombier default: 1643e12c5d1SDavid du Colombier pfmt(err, "Usage: cd [directory]\n"); 1653e12c5d1SDavid du Colombier break; 1663e12c5d1SDavid du Colombier case 2: 167dc5a79c1SDavid du Colombier if(a->next->word[0]=='/' || cdpath==0) 168dc5a79c1SDavid du Colombier cdpath=&nullpath; 1693e12c5d1SDavid du Colombier for(;cdpath;cdpath = cdpath->next){ 1703e12c5d1SDavid du Colombier strcpy(dir, cdpath->word); 171dc5a79c1SDavid du Colombier if(dir[0]) 172dc5a79c1SDavid du Colombier strcat(dir, "/"); 1733e12c5d1SDavid du Colombier strcat(dir, a->next->word); 1747dd7cddfSDavid du Colombier if(dochdir(dir)>=0){ 1753e12c5d1SDavid du Colombier if(strlen(cdpath->word) 1763e12c5d1SDavid du Colombier && strcmp(cdpath->word, ".")!=0) 1773e12c5d1SDavid du Colombier pfmt(err, "%s\n", dir); 1783e12c5d1SDavid du Colombier setstatus(""); 1793e12c5d1SDavid du Colombier break; 1803e12c5d1SDavid du Colombier } 1813e12c5d1SDavid du Colombier } 182dc5a79c1SDavid du Colombier if(cdpath==0) 183dc5a79c1SDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->next->word); 1843e12c5d1SDavid du Colombier break; 1853e12c5d1SDavid du Colombier case 1: 1863e12c5d1SDavid du Colombier a = vlook("home")->val; 1873e12c5d1SDavid du Colombier if(count(a)>=1){ 1887dd7cddfSDavid du Colombier if(dochdir(a->word)>=0) 1893e12c5d1SDavid du Colombier setstatus(""); 1903e12c5d1SDavid du Colombier else 1919a747e4fSDavid du Colombier pfmt(err, "Can't cd %s: %r\n", a->word); 1923e12c5d1SDavid du Colombier } 1933e12c5d1SDavid du Colombier else 1943e12c5d1SDavid du Colombier pfmt(err, "Can't cd -- $home empty\n"); 1953e12c5d1SDavid du Colombier break; 1963e12c5d1SDavid du Colombier } 1973e12c5d1SDavid du Colombier poplist(); 1983e12c5d1SDavid du Colombier } 199dc5a79c1SDavid du Colombier 200dc5a79c1SDavid du Colombier void 201dc5a79c1SDavid du Colombier execexit(void) 202dc5a79c1SDavid du Colombier { 2033e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 204dc5a79c1SDavid du Colombier default: 205dc5a79c1SDavid du Colombier pfmt(err, "Usage: exit [status]\nExiting anyway\n"); 206dc5a79c1SDavid du Colombier case 2: 207dc5a79c1SDavid du Colombier setstatus(runq->argv->words->next->word); 2083e12c5d1SDavid du Colombier case 1: Xexit(); 2093e12c5d1SDavid du Colombier } 2103e12c5d1SDavid du Colombier } 211dc5a79c1SDavid du Colombier 212dc5a79c1SDavid du Colombier void 213dc5a79c1SDavid du Colombier execshift(void) 214dc5a79c1SDavid du Colombier { 2153e12c5d1SDavid du Colombier int n; 2163e12c5d1SDavid du Colombier word *a; 2173e12c5d1SDavid du Colombier var *star; 2183e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 2193e12c5d1SDavid du Colombier default: 2203e12c5d1SDavid du Colombier pfmt(err, "Usage: shift [n]\n"); 2213e12c5d1SDavid du Colombier setstatus("shift usage"); 2223e12c5d1SDavid du Colombier poplist(); 2233e12c5d1SDavid du Colombier return; 224dc5a79c1SDavid du Colombier case 2: 225dc5a79c1SDavid du Colombier n = atoi(runq->argv->words->next->word); 226dc5a79c1SDavid du Colombier break; 227dc5a79c1SDavid du Colombier case 1: 228dc5a79c1SDavid du Colombier n = 1; 229dc5a79c1SDavid du Colombier break; 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier star = vlook("*"); 2323e12c5d1SDavid du Colombier for(;n && star->val;--n){ 2333e12c5d1SDavid du Colombier a = star->val->next; 2343e12c5d1SDavid du Colombier efree(star->val->word); 2353e12c5d1SDavid du Colombier efree((char *)star->val); 2363e12c5d1SDavid du Colombier star->val = a; 2373e12c5d1SDavid du Colombier star->changed = 1; 2383e12c5d1SDavid du Colombier } 2393e12c5d1SDavid du Colombier setstatus(""); 2403e12c5d1SDavid du Colombier poplist(); 2413e12c5d1SDavid du Colombier } 242dc5a79c1SDavid du Colombier 243dc5a79c1SDavid du Colombier int 244dc5a79c1SDavid du Colombier octal(char *s) 2453e12c5d1SDavid du Colombier { 2463e12c5d1SDavid du Colombier int n = 0; 2473e12c5d1SDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n') s++; 2483e12c5d1SDavid du Colombier while('0'<=*s && *s<='7') n = n*8+*s++-'0'; 2493e12c5d1SDavid du Colombier return n; 2503e12c5d1SDavid du Colombier } 251dc5a79c1SDavid du Colombier 252dc5a79c1SDavid du Colombier int 253dc5a79c1SDavid du Colombier mapfd(int fd) 2543e12c5d1SDavid du Colombier { 2553e12c5d1SDavid du Colombier redir *rp; 2563e12c5d1SDavid du Colombier for(rp = runq->redir;rp;rp = rp->next){ 2573e12c5d1SDavid du Colombier switch(rp->type){ 2583e12c5d1SDavid du Colombier case RCLOSE: 259dc5a79c1SDavid du Colombier if(rp->from==fd) 260dc5a79c1SDavid du Colombier fd=-1; 2613e12c5d1SDavid du Colombier break; 2623e12c5d1SDavid du Colombier case RDUP: 2633e12c5d1SDavid du Colombier case ROPEN: 264dc5a79c1SDavid du Colombier if(rp->to==fd) 265dc5a79c1SDavid du Colombier fd = rp->from; 2663e12c5d1SDavid du Colombier break; 2673e12c5d1SDavid du Colombier } 2683e12c5d1SDavid du Colombier } 2693e12c5d1SDavid du Colombier return fd; 2703e12c5d1SDavid du Colombier } 2713e12c5d1SDavid du Colombier union code rdcmds[4]; 272dc5a79c1SDavid du Colombier 273dc5a79c1SDavid du Colombier void 274dc5a79c1SDavid du Colombier execcmds(io *f) 2753e12c5d1SDavid du Colombier { 2763e12c5d1SDavid du Colombier static int first = 1; 2773e12c5d1SDavid du Colombier if(first){ 2783e12c5d1SDavid du Colombier rdcmds[0].i = 1; 2793e12c5d1SDavid du Colombier rdcmds[1].f = Xrdcmds; 2803e12c5d1SDavid du Colombier rdcmds[2].f = Xreturn; 2813e12c5d1SDavid du Colombier first = 0; 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier start(rdcmds, 1, runq->local); 2843e12c5d1SDavid du Colombier runq->cmdfd = f; 2853e12c5d1SDavid du Colombier runq->iflast = 0; 2863e12c5d1SDavid du Colombier } 287dc5a79c1SDavid du Colombier 288dc5a79c1SDavid du Colombier void 289dc5a79c1SDavid du Colombier execeval(void) 290dc5a79c1SDavid du Colombier { 2913e12c5d1SDavid du Colombier char *cmdline, *s, *t; 2923e12c5d1SDavid du Colombier int len = 0; 2933e12c5d1SDavid du Colombier word *ap; 2943e12c5d1SDavid du Colombier if(count(runq->argv->words)<=1){ 2959a747e4fSDavid du Colombier Xerror1("Usage: eval cmd ..."); 2963e12c5d1SDavid du Colombier return; 2973e12c5d1SDavid du Colombier } 298219b2ee8SDavid du Colombier eflagok = 1; 2993e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next) 3003e12c5d1SDavid du Colombier len+=1+strlen(ap->word); 3013e12c5d1SDavid du Colombier cmdline = emalloc(len); 3023e12c5d1SDavid du Colombier s = cmdline; 3033e12c5d1SDavid du Colombier for(ap = runq->argv->words->next;ap;ap = ap->next){ 3043e12c5d1SDavid du Colombier for(t = ap->word;*t;) *s++=*t++; 3053e12c5d1SDavid du Colombier *s++=' '; 3063e12c5d1SDavid du Colombier } 3073e12c5d1SDavid du Colombier s[-1]='\n'; 3083e12c5d1SDavid du Colombier poplist(); 3093e12c5d1SDavid du Colombier execcmds(opencore(cmdline, len)); 3103e12c5d1SDavid du Colombier efree(cmdline); 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier union code dotcmds[14]; 313dc5a79c1SDavid du Colombier 314dc5a79c1SDavid du Colombier void 315dc5a79c1SDavid du Colombier execdot(void) 316dc5a79c1SDavid du Colombier { 3173e12c5d1SDavid du Colombier int iflag = 0; 3183e12c5d1SDavid du Colombier int fd; 3193e12c5d1SDavid du Colombier list *av; 3203e12c5d1SDavid du Colombier thread *p = runq; 3213e12c5d1SDavid du Colombier char *zero; 3223e12c5d1SDavid du Colombier static int first = 1; 3233e12c5d1SDavid du Colombier char file[512]; 3243e12c5d1SDavid du Colombier word *path; 3253e12c5d1SDavid du Colombier if(first){ 3263e12c5d1SDavid du Colombier dotcmds[0].i = 1; 3273e12c5d1SDavid du Colombier dotcmds[1].f = Xmark; 3283e12c5d1SDavid du Colombier dotcmds[2].f = Xword; 3293e12c5d1SDavid du Colombier dotcmds[3].s="0"; 3303e12c5d1SDavid du Colombier dotcmds[4].f = Xlocal; 3313e12c5d1SDavid du Colombier dotcmds[5].f = Xmark; 3323e12c5d1SDavid du Colombier dotcmds[6].f = Xword; 3333e12c5d1SDavid du Colombier dotcmds[7].s="*"; 3343e12c5d1SDavid du Colombier dotcmds[8].f = Xlocal; 3353e12c5d1SDavid du Colombier dotcmds[9].f = Xrdcmds; 3363e12c5d1SDavid du Colombier dotcmds[10].f = Xunlocal; 3373e12c5d1SDavid du Colombier dotcmds[11].f = Xunlocal; 3383e12c5d1SDavid du Colombier dotcmds[12].f = Xreturn; 3393e12c5d1SDavid du Colombier first = 0; 3403e12c5d1SDavid du Colombier } 341219b2ee8SDavid du Colombier else 342219b2ee8SDavid du Colombier eflagok = 1; 3433e12c5d1SDavid du Colombier popword(); 3443e12c5d1SDavid du Colombier if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ 3453e12c5d1SDavid du Colombier iflag = 1; 3463e12c5d1SDavid du Colombier popword(); 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier /* get input file */ 3493e12c5d1SDavid du Colombier if(p->argv->words==0){ 3509a747e4fSDavid du Colombier Xerror1("Usage: . [-i] file [arg ...]"); 3513e12c5d1SDavid du Colombier return; 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier zero = strdup(p->argv->words->word); 3543e12c5d1SDavid du Colombier popword(); 3557dd7cddfSDavid du Colombier fd=-1; 3563e12c5d1SDavid du Colombier for(path = searchpath(zero);path;path = path->next){ 3573e12c5d1SDavid du Colombier strcpy(file, path->word); 358dc5a79c1SDavid du Colombier if(file[0]) 359dc5a79c1SDavid du Colombier strcat(file, "/"); 3603e12c5d1SDavid du Colombier strcat(file, zero); 3613e12c5d1SDavid du Colombier if((fd = open(file, 0))>=0) break; 3623e12c5d1SDavid du Colombier if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ 3633e12c5d1SDavid du Colombier fd = Dup1(0); 364dc5a79c1SDavid du Colombier if(fd>=0) 365dc5a79c1SDavid du Colombier break; 3663e12c5d1SDavid du Colombier } 3673e12c5d1SDavid du Colombier } 3683e12c5d1SDavid du Colombier if(fd<0){ 3697dd7cddfSDavid du Colombier pfmt(err, "%s: ", zero); 3707dd7cddfSDavid du Colombier setstatus("can't open"); 3717dd7cddfSDavid du Colombier Xerror(".: can't open"); 3723e12c5d1SDavid du Colombier return; 3733e12c5d1SDavid du Colombier } 3743e12c5d1SDavid du Colombier /* set up for a new command loop */ 3753e12c5d1SDavid du Colombier start(dotcmds, 1, (struct var *)0); 3763e12c5d1SDavid du Colombier pushredir(RCLOSE, fd, 0); 3773e12c5d1SDavid du Colombier runq->cmdfile = zero; 3783e12c5d1SDavid du Colombier runq->cmdfd = openfd(fd); 3793e12c5d1SDavid du Colombier runq->iflag = iflag; 3803e12c5d1SDavid du Colombier runq->iflast = 0; 3813e12c5d1SDavid du Colombier /* push $* value */ 3823e12c5d1SDavid du Colombier pushlist(); 3833e12c5d1SDavid du Colombier runq->argv->words = p->argv->words; 3843e12c5d1SDavid du Colombier /* free caller's copy of $* */ 3853e12c5d1SDavid du Colombier av = p->argv; 3863e12c5d1SDavid du Colombier p->argv = av->next; 3873e12c5d1SDavid du Colombier efree((char *)av); 3883e12c5d1SDavid du Colombier /* push $0 value */ 3893e12c5d1SDavid du Colombier pushlist(); 3903e12c5d1SDavid du Colombier pushword(zero); 3913e12c5d1SDavid du Colombier ndot++; 3923e12c5d1SDavid du Colombier } 393dc5a79c1SDavid du Colombier 394dc5a79c1SDavid du Colombier void 395dc5a79c1SDavid du Colombier execflag(void) 396dc5a79c1SDavid du Colombier { 3973e12c5d1SDavid du Colombier char *letter, *val; 3983e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 3993e12c5d1SDavid du Colombier case 2: 400*d3907fe5SDavid du Colombier setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set"); 4013e12c5d1SDavid du Colombier break; 4023e12c5d1SDavid du Colombier case 3: 4033e12c5d1SDavid du Colombier letter = runq->argv->words->next->word; 4043e12c5d1SDavid du Colombier val = runq->argv->words->next->next->word; 4053e12c5d1SDavid du Colombier if(strlen(letter)==1){ 4063e12c5d1SDavid du Colombier if(strcmp(val, "+")==0){ 407*d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = flagset; 4083e12c5d1SDavid du Colombier break; 4093e12c5d1SDavid du Colombier } 4103e12c5d1SDavid du Colombier if(strcmp(val, "-")==0){ 411*d3907fe5SDavid du Colombier flag[(uchar)letter[0]] = 0; 4123e12c5d1SDavid du Colombier break; 4133e12c5d1SDavid du Colombier } 4143e12c5d1SDavid du Colombier } 4153e12c5d1SDavid du Colombier default: 4169a747e4fSDavid du Colombier Xerror1("Usage: flag [letter] [+-]"); 4173e12c5d1SDavid du Colombier return; 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier poplist(); 4203e12c5d1SDavid du Colombier } 421dc5a79c1SDavid du Colombier 422dc5a79c1SDavid du Colombier void 423dc5a79c1SDavid du Colombier execwhatis(void){ /* mildly wrong -- should fork before writing */ 4243e12c5d1SDavid du Colombier word *a, *b, *path; 4253e12c5d1SDavid du Colombier var *v; 4263e12c5d1SDavid du Colombier struct builtin *bp; 4273e12c5d1SDavid du Colombier char file[512]; 4283e12c5d1SDavid du Colombier struct io out[1]; 4293e12c5d1SDavid du Colombier int found, sep; 4303e12c5d1SDavid du Colombier a = runq->argv->words->next; 4313e12c5d1SDavid du Colombier if(a==0){ 4329a747e4fSDavid du Colombier Xerror1("Usage: whatis name ..."); 4333e12c5d1SDavid du Colombier return; 4343e12c5d1SDavid du Colombier } 4353e12c5d1SDavid du Colombier setstatus(""); 4363e12c5d1SDavid du Colombier out->fd = mapfd(1); 4373e12c5d1SDavid du Colombier out->bufp = out->buf; 4383e12c5d1SDavid du Colombier out->ebuf = &out->buf[NBUF]; 4393e12c5d1SDavid du Colombier out->strp = 0; 4403e12c5d1SDavid du Colombier for(;a;a = a->next){ 4413e12c5d1SDavid du Colombier v = vlook(a->word); 4423e12c5d1SDavid du Colombier if(v->val){ 4433e12c5d1SDavid du Colombier pfmt(out, "%s=", a->word); 4443e12c5d1SDavid du Colombier if(v->val->next==0) 4453e12c5d1SDavid du Colombier pfmt(out, "%q\n", v->val->word); 4463e12c5d1SDavid du Colombier else{ 4473e12c5d1SDavid du Colombier sep='('; 4483e12c5d1SDavid du Colombier for(b = v->val;b && b->word;b = b->next){ 4493e12c5d1SDavid du Colombier pfmt(out, "%c%q", sep, b->word); 4503e12c5d1SDavid du Colombier sep=' '; 4513e12c5d1SDavid du Colombier } 4523e12c5d1SDavid du Colombier pfmt(out, ")\n"); 4533e12c5d1SDavid du Colombier } 4543e12c5d1SDavid du Colombier found = 1; 4553e12c5d1SDavid du Colombier } 4563e12c5d1SDavid du Colombier else 4573e12c5d1SDavid du Colombier found = 0; 4583e12c5d1SDavid du Colombier v = gvlook(a->word); 459dc5a79c1SDavid du Colombier if(v->fn) 460dc5a79c1SDavid du Colombier pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s); 4613e12c5d1SDavid du Colombier else{ 4623e12c5d1SDavid du Colombier for(bp = Builtin;bp->name;bp++) 4633e12c5d1SDavid du Colombier if(strcmp(a->word, bp->name)==0){ 4643e12c5d1SDavid du Colombier pfmt(out, "builtin %s\n", a->word); 4653e12c5d1SDavid du Colombier break; 4663e12c5d1SDavid du Colombier } 4673e12c5d1SDavid du Colombier if(!bp->name){ 4683e12c5d1SDavid du Colombier for(path = searchpath(a->word);path;path = path->next){ 4693e12c5d1SDavid du Colombier strcpy(file, path->word); 470dc5a79c1SDavid du Colombier if(file[0]) 471dc5a79c1SDavid du Colombier strcat(file, "/"); 4723e12c5d1SDavid du Colombier strcat(file, a->word); 4733e12c5d1SDavid du Colombier if(Executable(file)){ 4743e12c5d1SDavid du Colombier pfmt(out, "%s\n", file); 4753e12c5d1SDavid du Colombier break; 4763e12c5d1SDavid du Colombier } 4773e12c5d1SDavid du Colombier } 4783e12c5d1SDavid du Colombier if(!path && !found){ 4793e12c5d1SDavid du Colombier pfmt(err, "%s: not found\n", a->word); 4803e12c5d1SDavid du Colombier setstatus("not found"); 4813e12c5d1SDavid du Colombier } 4823e12c5d1SDavid du Colombier } 4833e12c5d1SDavid du Colombier } 4843e12c5d1SDavid du Colombier } 4853e12c5d1SDavid du Colombier poplist(); 4863e12c5d1SDavid du Colombier flush(err); 4873e12c5d1SDavid du Colombier } 488dc5a79c1SDavid du Colombier 489dc5a79c1SDavid du Colombier void 490dc5a79c1SDavid du Colombier execwait(void) 491dc5a79c1SDavid du Colombier { 4923e12c5d1SDavid du Colombier switch(count(runq->argv->words)){ 493dc5a79c1SDavid du Colombier default: 494dc5a79c1SDavid du Colombier Xerror1("Usage: wait [pid]"); 495dc5a79c1SDavid du Colombier return; 496dc5a79c1SDavid du Colombier case 2: 497dc5a79c1SDavid du Colombier Waitfor(atoi(runq->argv->words->next->word), 0); 498dc5a79c1SDavid du Colombier break; 499dc5a79c1SDavid du Colombier case 1: 500dc5a79c1SDavid du Colombier Waitfor(-1, 0); 501dc5a79c1SDavid du Colombier break; 5023e12c5d1SDavid du Colombier } 503219b2ee8SDavid du Colombier poplist(); 5043e12c5d1SDavid du Colombier } 505