home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
util
/
csh-5.39.lha
/
Csh
/
src
/
run.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-31
|
22KB
|
931 lines
/*
* 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 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
* Version 5.00L by Urban Mueller 17-Feb-91
* Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
*
*/
#include "shell.h"
int MySyncRun( char *com, char *args, BPTR in, BPTR out, int nosync );
int echofunc(void);
int
do_run( char *str, int nosync )
{
int retcode;
char buf[256]; /* enough space for 100 char cmd name + path stuff */
char *path, *path2, *argline, *copy = NULL, *ext, *end;
if( !*av[0] )
return 0;
if( (retcode=echofunc())>=0 )
return retcode;
a0tospace( av[0] ); /* allow "com mand" */
argline=compile_av(av, 1, ac, ' ', 1);
if (strlen(av[0]) > 100) { ierror(NULL,509); return -1; }
if( ac==1 && isdir(av[0])) {
sprintf(buf,"cd \"%s\"",av[0]);
return execute( buf );
}
IoError=IoErr();
if( (IoError==218 || IoError==225 || IoError==226) && index(av[0],':')) {
ierror( av[0], IoError );
return 20;
}
sprintf(buf,"res_%s",FilePart(av[0])); /* delayed residents */
/* AMK: OS20-GetVar replaces ARP-Getenv */
if (o_resident && GetVar(buf,buf+100,90L,GVF_GLOBAL_ONLY|GVF_BINARY_VAR)>=0L) {
/* AMK: OS20-SetVar replaces ARP-Setenv */
SetVar(buf,NULL,NULL,GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
loadres(buf+100);
}
if( (retcode=MySyncRun(av[0],argline,0,0,nosync))>=0 ) /* AmigaDOS path */
goto done2;
if( retcode == -2 /*PR_NOMEM*/ ) {
ierror( av[0], 103 );
return 20;
}
IoError=IoErr();
if( (IoError==218 || IoError==225 || IoError==226) && index(av[0],':')) {
ierror( av[0], IoError );
return 20;
}
if (path = dofind(av[0],"",buf+80,v_path)) { /* shell path */
DPTR *dp;
BPTR fh;
int stat, script;
if((retcode = MySyncRun(path,argline,0,0,nosync))>=0)
goto done2;
if(dp=dopen(path,&stat)) {
script= dp->fib->fib_Protection&FIBF_SCRIPT;
dclose(dp);
if( !stat && script ) {
char *t,*dynbuf;
int dynret;
buf[0]=0;
if( fh=Open(path,MODE_OLDFILE )) {
Read(fh,buf,79);
Close(fh);
buf[79] = 0;
if(t=index(buf,'\n')) *t=0;
}
dynbuf = salloc(strlen(buf)+strlen(str)+10);
if( buf[0]=='/' && buf[1]=='*' ) {
sprintf(dynbuf, "Rx %s", str );
} else if( (buf[0]!=';' || buf[0]!='#') && buf[1]=='!' ) {
memmove(dynbuf,buf+2,strlen(buf+2)+1);
strcat( dynbuf," ");
strcat( dynbuf,str);
} else {
sprintf(dynbuf,"Execute %s", str );
}
dynret = execute( a0tospace(dynbuf));
free(dynbuf);
return(dynret);
}
}
}
if(!(end=rindex(av[0],'.'))) end=""; /* automatic sourcing */
ext=strcmp(end,".sh") ? ".sh" : "";
if (path = dofind(av[0],ext,buf,v_path)) {
av[1] = buf;
copy = salloc(strlen(str)+3);
sprintf(copy,"x %s",str);
retcode = do_source(copy);
goto done;
}
#if 0
/* what is it good for??? -amk */
copy=salloc(strlen(av[0])+strlen(argline)+5);
sprintf(copy,"%s %s",av[0],argline);
#endif
ext=strcmp(end,".rexx") ? ".rexx" : ""; /* automatic rx-ing */
if( path = dofind(av[0], ext, buf, v_rxpath )) {
copy = salloc(strlen(path)+strlen(argline)+5);
sprintf(copy,"%s %s",path,argline);
#if 1
/* dynamic command line, no limits! -amk */
if ( (retcode=MySyncRun("rx",copy,0,0,0)) >=0 )
goto done;
if (path2 = dofind("rx","",buf,v_path)) {
retcode = MySyncRun(path2,copy,0,0,0);
goto done;
}
#else
/* static command line, limited to 140 chars! -amk */
strcat (path," ");
if( strlen(argline)>140 ) argline[140]=0;
strcat (path,argline);
/* strncpy(path+strlen(path),argline,190); */
if( (retcode=MySyncRun("rx",path,0,0,0)) >=0 ) goto done;
kprintf("balu: %s\n",buf+160);
if (path2 = dofind("rx","",buf+160,v_path)) {
retcode = MySyncRun(path2,path,0,0,0);
goto done;
}
#endif
}
if( !doaction(av[0],"exec",argline)) {
retcode=0;
goto done;
}
retcode = -1;
fprintf(stderr,"Command not found %s\n",av[0]);
done:
if (copy)
free(copy);
done2:
setioerror( IoErr() );
free( argline );
return retcode;
}
#ifndef END_STREAM_CH
#define END_STREAM_CH -1L
#endif
BPTR
new_input, /* for execute'ing a script file */
old_inp_fh, /* old input filehandle */
old_out_fh, /* old output filehandle */
seglist_cmd; /* to be returned from NewLoadSeg */
void set_returncodes(long returncode,long result2)
{
Mycli->cli_ReturnCode = returncode;
Mycli->cli_Result2 = result2;
}
void clean_up_io(void)
{
long ch;
Flush(Output());
ch = UnGetC(Input(),END_STREAM_CH) ? 0 : '\n';
while ((ch != '\n') && (ch != END_STREAM_CH))
ch = FGetC(Input());
}
long command_examine(char *fname,BPTR *plock)
{
/*
Given a filename, attempt to determine if we can process it. Either
by running it, or by 'executing' it (a script).
Returns:
0 = can RunCommand the file
1 = can source/script/execute the file
< 0 = error
*/
struct FileInfoBlock *fib;
long i;
BPTR lock;
*plock = NULL;
if (!(lock=Lock(fname,ACCESS_READ)))
return -1;
if (!(fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))) {
UnLock(lock);
return -9;
}
if (!Examine(lock,fib)) {
UnLock(lock);
FreeDosObject(DOS_FIB,fib);
return -2;
}
i = fib->fib_DirEntryType;
if (i==ST_SOFTLINK) {
/*
Let our caller resolve the link, and if it resolves to a file,
call us again.
*/
UnLock(lock);
FreeDosObject(DOS_FIB,fib);
return -10;
}
if (!((i==ST_FILE) || (i==ST_LINKFILE))) {
UnLock(lock);
FreeDosObject(DOS_FIB,fib);
return -3;
}
i = fib->fib_Protection;
i = (i & 0x70) | (0x0f & ~i);
if (!((i & FIBF_SCRIPT) || (i & FIBF_EXECUTE))) {
/* Not an executable or a script file. */
UnLock(lock);
FreeDosObject(DOS_FIB,fib);
return -4;
}
FreeDosObject(DOS_FIB,fib);
seglist_cmd = NULL;
new_input = NULL;
*plock = ParentDir(lock);
if (i & FIBF_SCRIPT) {
/*
Open the file, but let the 'outside world' dick with CurrentInput.
Not me. Outside of my definition. :)
*/
if (!(new_input=OpenFromLock(lock))) {
UnLock(lock);
UnLock(*plock);
return -5;
}
/* Remember that 'lock' is now INVALID and should not be touched. */
return 1;
}
if (i & FIBF_EXECUTE) {
/* LoadSeg the sucker. */
if (!(seglist_cmd=NewLoadSeg(fname,NULL))) {
#if 0
/* AMK: distinguish between "no memory" and "not an executable" */
if (IoErr()==ERROR_NO_FREE_STORE) {
UnLock(lock);
UnLock(*plock);
return -11;
}
#endif
/* Probably a 'bad' file (i.e., not actually an executable). */
UnLock(lock);
UnLock(*plock);
return -6;
}
UnLock(lock);
return 0;
}
if (lock) UnLock(lock);
if (*plock) UnLock(*plock);
return -7; /* should NEVER reach this point */
}
long command_device(char *device,char *fname)
{
/*
For the Device specified by *device, search each element of the
assign (since it could be a multi-assign) and try to find a
command file. A command file can be either an executable file, or
a script file (one with the script bit set).
Returns:
0 = can RunCommand this file (seglist_cmd set)
1 = can source/script/execute this file (new_input set)
< 0 = error
-8 = Bad device name
Note that this routine generates only one error of its own. All
other results are passed straight thru from command_examine ().
*/
long gotlock, /* we have a directory lock or not */
result = 0, /* from command_examine () */
/* AMK: result initialized with 0 */
done = 0; /* found something we could use */
struct DevProc *dp = NULL; /* for searching multi-assigned paths */
struct MsgPort *fstask; /* for GetFileSysTask () */
BPTR plock, /* parent of fname */
lock, /* on source directory */
dir_lock; /* save current directory */
/*printf("search: %s -> %s\n",device,fname);*/
fstask = GetFileSysTask ();
do {
dp = GetDeviceProc(device,dp);
if (dp) {
SetFileSysTask(dp->dvp_Port);
lock = NULL;
gotlock = 0;
if (dp->dvp_Lock) {
dir_lock = CurrentDir(dp->dvp_Lock);
gotlock = 1;
}
else {
if (lock=Lock(device,ACCESS_R