/* * RUN.C * * (c)1986 Matthew Dillon 9 October 1986 * * RUN handles running of external commands. * * Version 2.07M by Steve Drew 10-Sep-87 * * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89 * */ extern char *v_path; char *FindIt(); do_run(str) char *str; { int i, len, retcode; char buf[200]; /* enough space for 100 char cmd name + path stuff */ char *path; char *p = av[0]; char **args = av+1; while(*p++) *p &= 0x7F; /* allow "com mand" */ while(*args) { /* if any arg contains a space then */ if (index(*args,' ')) { /* surround with quotes, since must */ i = strlen(*args); /* of specified via "arg u ment" on */ movmem(*args,(*args)+1,i); /* original command line. */ args[0][0] = args[0][i+1] = '\"'; /* mpush in execom.c has */ args[0][i+2] = '\0'; /* allowed for these 2 extra bytes. */ } ++args; } if ((len = strlen(av[0])) > 100) { ierror(NULL,509); return -1; } if (path = FindIt(av[0],"",buf)) retcode = myfexecv(path, av); else { Myprocess->pr_WindowPtr = (APTR)(-1); /* * manx's fexecv code only allows us 38 * chars for command name. */ if (len > 37) av[0][37] = '\0'; retcode = myfexecv(av[0], av); Myprocess->pr_WindowPtr = NULL; } if (retcode < 0) { char *copy; if ((path = FindIt(av[0],".sh",buf)) == NULL) { fprintf(stderr,"Command Not Found %s\n",av[0]); return -1; } av[1] = buf; /* particular to do_source() */ copy = malloc(strlen(str)+3); sprintf(copy,"x %s",str); retcode = do_source(copy); free(copy); } return retcode; } char *dofind(cmd, ext, buf) char *cmd, *ext, *buf; { char *ptr, *s; sprintf(buf,"%s%s",cmd,ext); if (exists(buf)) return buf; if (BaseName(buf)==buf) { s = get_var(LEVEL_SET, v_path); while (*s) { for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++; sprintf(ptr, "%s%s", cmd, ext); if (exists(buf)) return buf; if (*s) s++; } } return NULL; } char *FindIt(cmd,ext,buf) char *cmd, *ext, *buf; { char *response; Myprocess->pr_WindowPtr = (APTR)(-1); response=dofind(cmd,ext,buf); Myprocess->pr_WindowPtr = NULL; return response; } myfexecv(cmd, argv) char *cmd, **argv; { long ret_val; struct FileHandle *fhp; APTR sav_ret; register char **ap, *cp, *arg; long len, seg, sav, stksiz; char buf[40]; union { long *lp; long ll; } l, stk; long oldcin, oldcout; long doexec(); extern long _savsp; if (seg = LoadPrg(cmd)) goto found; l.lp = (long *) Mycli->cli_CommandDir; while (l.ll) { l.ll <<= 2; sav = CurrentDir(l.lp[1]); seg = LoadPrg(cmd); CurrentDir(sav); if (seg) goto found; l.ll = *l.lp; } sprintf(buf, "c:%s", cmd); if (seg = LoadPrg(buf)) goto found; return -1; found: stksiz = 4 * Mycli->cli_DefaultStack; if ((stk.lp = AllocMem(stksiz+8, 0L)) == 0) { UnLoadPrg(seg); return -1; } for (len=0,ap=argv+1;*ap;ap++) len += strlen(*ap) + 1; if (len==0) len++; if ((cp = arg = AllocMem(len, 0L)) == 0) { UnLoadPrg(seg); FreeMem(stk.lp, stksiz+8); return -1; } *stk.lp = stksiz + 8; stk.ll += stksiz; stk.lp[0] = stksiz; stk.lp[1] = ((long *)_savsp)[2]; sav_ret = Myprocess->pr_ReturnAddr; Myprocess->pr_ReturnAddr = (APTR) stk.lp; sav = Mycli->cli_Module; Mycli->cli_Module = seg; for (ap=argv+1;*ap;ap++) { strcpy(cp, *ap); if (ap[1]) strcat(cp, " "); cp += strlen(cp); } if (len==1) arg[1]='\0'; arg[len-1] = '\n'; cp = (char *)((long)Mycli->cli_CommandName << 2); movmem(cp, buf, 40); strcpy(cp+1, cmd); cp[0] = strlen(cmd); fhp = (struct FileHandle *) (Myprocess->pr_CIS << 2); strncpy(fhp->fh_Buf<<2, arg, (int)(len < 200?len:199)); fhp->fh_Pos = 0; fhp->fh_End = len < 200?len:199; oldcin = Myprocess->pr_CIS; oldcout = Myprocess->pr_COS; ret_val = doexec(len, stksiz, stksiz+8, len, arg, (seg+1)<<2, stk.ll); Myprocess->pr_CIS = oldcin; Myprocess->pr_COS = oldcout; fhp->fh_Pos = fhp->fh_End; UnLoadPrg(Mycli->cli_Module); Myprocess->pr_ReturnAddr = sav_ret; Mycli->cli_Module = sav; FreeMem(arg, len); movmem(buf, cp, 40); return ret_val; } static long doexec() { #asm movem.l d3-d7/a2-a5,-(sp) ;save registers lea savsp(pc),a0 move.l sp,(a0) ;save our sp movem.l 8(a5),d0/d2/d3/d4/a0/a4/a7 ;load params move.l 4(sp),a3 ;get old sp from CLI movem.l 4(a3),a1/a2/a5/a6 ;get BCPL environment move.l d0,12(a1) ;set length move.l a0,d1 ;copy to dreg lsr.l #2,d1 ;convert to BPTR move.l d1,8(a1) ;set ptr move.l a0,d1 ;copy to d1 as well jsr (a4) ;call new program movem.l (sp)+,d2/d3 ;get stk siz and old sp move.l sp,a1 ;save current sp move.l savsp(pc),sp ;get back our sp movem.l (sp)+,d3-d7/a2-a5 ;get back registers move.l d0,-(sp) ;save return code sub.l d2,a1 ;back up a bit sub.l #8,a1 ;back up over header move.l (a1),d0 ;get size to free move.l 4,a6 ;get ExecBase jsr -210(a6) ;free the memory move.l (sp)+,d0 ;get the return code #endasm } #asm savsp: dc.l 0 #endasm