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 >
C/C++ Source or Header  |  1994-08-31  |  22KB  |  931 lines

  1. /*
  2.  * RUN.C
  3.  *
  4.  * (c)1986 Matthew Dillon     9 October 1986
  5.  *
  6.  *    RUN   handles running of external commands.
  7.  *
  8.  * Version 2.07M by Steve Drew 10-Sep-87
  9.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  10.  * Version 5.00L by Urban Mueller 17-Feb-91
  11.  * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
  12.  *
  13.  */
  14.  
  15. #include "shell.h"
  16.  
  17. int MySyncRun( char *com, char *args, BPTR in, BPTR out, int nosync );
  18. int echofunc(void);
  19.  
  20. int
  21. do_run( char *str, int nosync )
  22. {
  23.     int retcode;
  24.     char buf[256];        /* enough space for 100 char cmd name + path stuff */
  25.     char *path, *path2, *argline, *copy = NULL, *ext, *end;
  26.  
  27.     if( !*av[0] )
  28.         return 0;
  29.  
  30.     if( (retcode=echofunc())>=0 )
  31.         return retcode;
  32.  
  33.     a0tospace( av[0] );                                 /* allow "com mand" */
  34.  
  35.     argline=compile_av(av, 1, ac, ' ', 1);
  36.  
  37.     if (strlen(av[0]) > 100) { ierror(NULL,509); return -1; }
  38.  
  39.     if( ac==1 && isdir(av[0])) {
  40.         sprintf(buf,"cd \"%s\"",av[0]);
  41.         return execute( buf );
  42.     }
  43.  
  44.     IoError=IoErr();
  45.     if( (IoError==218 || IoError==225 || IoError==226) && index(av[0],':')) {
  46.         ierror( av[0], IoError );
  47.         return 20;
  48.     }
  49.  
  50.     sprintf(buf,"res_%s",FilePart(av[0]));               /* delayed residents */
  51.     /* AMK: OS20-GetVar replaces ARP-Getenv */
  52.     if (o_resident && GetVar(buf,buf+100,90L,GVF_GLOBAL_ONLY|GVF_BINARY_VAR)>=0L) {
  53.         /* AMK: OS20-SetVar replaces ARP-Setenv */
  54.         SetVar(buf,NULL,NULL,GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  55.         loadres(buf+100);
  56.     }
  57.  
  58.     if( (retcode=MySyncRun(av[0],argline,0,0,nosync))>=0 )   /* AmigaDOS path */
  59.         goto done2;
  60.  
  61.     if( retcode == -2 /*PR_NOMEM*/ ) {
  62.         ierror( av[0], 103 );
  63.         return 20;
  64.     }
  65.  
  66.     IoError=IoErr();
  67.     if( (IoError==218 || IoError==225 || IoError==226) && index(av[0],':')) {
  68.         ierror( av[0], IoError );
  69.         return 20;
  70.     }
  71.  
  72.     if (path = dofind(av[0],"",buf+80,v_path)) {             /* shell path    */
  73.         DPTR *dp;
  74.         BPTR fh;
  75.         int stat, script;
  76.         if((retcode = MySyncRun(path,argline,0,0,nosync))>=0)
  77.             goto done2;
  78.         if(dp=dopen(path,&stat)) {
  79.             script= dp->fib->fib_Protection&FIBF_SCRIPT;
  80.             dclose(dp);
  81.             if( !stat && script ) {
  82.                 char *t,*dynbuf;
  83.                 int dynret;
  84.                 buf[0]=0;
  85.                 if( fh=Open(path,MODE_OLDFILE )) {
  86.                     Read(fh,buf,79);
  87.                     Close(fh);
  88.                     buf[79] = 0;
  89.                     if(t=index(buf,'\n')) *t=0;
  90.                 }
  91.  
  92.                 dynbuf = salloc(strlen(buf)+strlen(str)+10);
  93.  
  94.                 if( buf[0]=='/' && buf[1]=='*' ) {
  95.                     sprintf(dynbuf, "Rx %s", str );
  96.                 } else if( (buf[0]!=';' || buf[0]!='#') && buf[1]=='!' ) {
  97.                     memmove(dynbuf,buf+2,strlen(buf+2)+1);
  98.                     strcat( dynbuf," ");
  99.                     strcat( dynbuf,str);
  100.                 } else {
  101.                     sprintf(dynbuf,"Execute %s", str );
  102.                 }
  103.                 dynret = execute( a0tospace(dynbuf));
  104.  
  105.                 free(dynbuf);
  106.                 return(dynret);
  107.             }
  108.         }
  109.     }
  110.  
  111.     if(!(end=rindex(av[0],'.'))) end="";               /* automatic sourcing */
  112.     ext=strcmp(end,".sh") ? ".sh" : "";
  113.     if (path = dofind(av[0],ext,buf,v_path)) {
  114.         av[1] = buf;
  115.         copy = salloc(strlen(str)+3);
  116.         sprintf(copy,"x %s",str);
  117.         retcode = do_source(copy);
  118.         goto done;
  119.     }
  120.  
  121. #if 0
  122.     /* what is it good for??? -amk */
  123.     copy=salloc(strlen(av[0])+strlen(argline)+5);
  124.     sprintf(copy,"%s %s",av[0],argline);
  125. #endif
  126.  
  127.     ext=strcmp(end,".rexx") ? ".rexx" : "";           /* automatic rx-ing   */
  128.     if( path = dofind(av[0], ext, buf, v_rxpath )) {
  129.         copy = salloc(strlen(path)+strlen(argline)+5);
  130.         sprintf(copy,"%s %s",path,argline);
  131. #if 1
  132. /* dynamic command line, no limits! -amk */
  133.         if ( (retcode=MySyncRun("rx",copy,0,0,0)) >=0 )
  134.             goto done;
  135.         if (path2 = dofind("rx","",buf,v_path)) {
  136.             retcode = MySyncRun(path2,copy,0,0,0);
  137.             goto done;
  138.         }
  139. #else
  140. /* static command line, limited to 140 chars! -amk */
  141.         strcat (path," ");
  142.         if( strlen(argline)>140 ) argline[140]=0;
  143.         strcat (path,argline);
  144. /*        strncpy(path+strlen(path),argline,190); */
  145.         if( (retcode=MySyncRun("rx",path,0,0,0)) >=0 ) goto done;
  146.         kprintf("balu: %s\n",buf+160);
  147.         if (path2 = dofind("rx","",buf+160,v_path)) {
  148.             retcode = MySyncRun(path2,path,0,0,0);
  149.             goto done;
  150.         }
  151. #endif
  152.  
  153.     }
  154.  
  155.     if( !doaction(av[0],"exec",argline)) {
  156.         retcode=0;
  157.         goto done;
  158.     }
  159.  
  160.     retcode = -1;
  161.     fprintf(stderr,"Command not found %s\n",av[0]);
  162.  
  163. done:
  164.     if (copy)
  165.         free(copy);
  166. done2:
  167.     setioerror( IoErr() );
  168.     free( argline );
  169.     return retcode;
  170. }
  171.  
  172.  
  173.  
  174. #ifndef END_STREAM_CH
  175. #define END_STREAM_CH -1L
  176. #endif
  177. BPTR
  178.     new_input,    /* for execute'ing a script file */
  179.     old_inp_fh,    /* old input filehandle */
  180.     old_out_fh,    /* old output filehandle */
  181.     seglist_cmd;    /* to be returned from NewLoadSeg */
  182.  
  183.  
  184. void set_returncodes(long returncode,long result2)
  185. {
  186.     Mycli->cli_ReturnCode = returncode;
  187.     Mycli->cli_Result2    = result2;
  188. }
  189.  
  190.  
  191.  
  192. void clean_up_io(void)
  193. {
  194.     long ch;
  195.     Flush(Output());
  196.     ch = UnGetC(Input(),END_STREAM_CH) ? 0 : '\n';
  197.     while ((ch != '\n') && (ch != END_STREAM_CH))
  198.         ch = FGetC(Input());
  199. }
  200.  
  201. long command_examine(char *fname,BPTR *plock)
  202. {
  203.     /*
  204.     Given a filename, attempt to determine if we can process it. Either
  205.     by running it, or by 'executing' it (a script).
  206.  
  207.     Returns:
  208.         0 = can RunCommand the file
  209.         1 = can source/script/execute the file
  210.       < 0 = error
  211.     */
  212.     struct FileInfoBlock *fib;
  213.     long i;
  214.     BPTR lock;
  215.  
  216.     *plock = NULL;
  217.  
  218.     if (!(lock=Lock(fname,ACCESS_READ)))
  219.         return -1;
  220.  
  221.     if (!(fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))) {
  222.         UnLock(lock);
  223.         return -9;
  224.     }
  225.  
  226.     if (!Examine(lock,fib)) {
  227.         UnLock(lock);
  228.         FreeDosObject(DOS_FIB,fib);
  229.         return -2;
  230.     }
  231.  
  232.     i = fib->fib_DirEntryType;
  233.  
  234.     if (i==ST_SOFTLINK) {
  235.         /*
  236.            Let our caller resolve the link, and if it resolves to a file,
  237.            call us again.
  238.         */
  239.         UnLock(lock);
  240.         FreeDosObject(DOS_FIB,fib);
  241.         return -10;
  242.     }
  243.  
  244.     if (!((i==ST_FILE) || (i==ST_LINKFILE))) {
  245.         UnLock(lock);
  246.         FreeDosObject(DOS_FIB,fib);
  247.         return -3;
  248.     }
  249.  
  250.     i = fib->fib_Protection;
  251.     i = (i & 0x70) | (0x0f & ~i);
  252.     if (!((i & FIBF_SCRIPT) || (i & FIBF_EXECUTE))) {
  253.         /* Not an executable or a script file. */
  254.         UnLock(lock);
  255.         FreeDosObject(DOS_FIB,fib);
  256.         return -4;
  257.     }
  258.  
  259.     FreeDosObject(DOS_FIB,fib);
  260.     seglist_cmd = NULL;
  261.     new_input = NULL;
  262.     *plock = ParentDir(lock);
  263.  
  264.     if (i & FIBF_SCRIPT) {
  265.         /*
  266.             Open the file, but let the 'outside world' dick with CurrentInput.
  267.             Not me. Outside of my definition. :)
  268.         */
  269.         if (!(new_input=OpenFromLock(lock))) {
  270.             UnLock(lock);
  271.             UnLock(*plock);
  272.             return -5;
  273.         }
  274.         /* Remember that 'lock' is now INVALID and should not be touched. */
  275.         return 1;
  276.     }
  277.  
  278.     if (i & FIBF_EXECUTE) {
  279.         /* LoadSeg the sucker. */
  280.         if (!(seglist_cmd=NewLoadSeg(fname,NULL))) {
  281. #if 0
  282.             /* AMK: distinguish between "no memory" and "not an executable" */
  283.             if (IoErr()==ERROR_NO_FREE_STORE) {
  284.                 UnLock(lock);
  285.                 UnLock(*plock);
  286.                 return -11;
  287.             }
  288. #endif
  289.             /* Probably a 'bad' file (i.e., not actually an executable). */
  290.             UnLock(lock);
  291.             UnLock(*plock);
  292.             return -6;
  293.         }
  294.         UnLock(lock);
  295.         return 0;
  296.     }
  297.  
  298.     if (lock) UnLock(lock);
  299.     if (*plock) UnLock(*plock);
  300.     return -7;    /* should NEVER reach this point */
  301. }
  302.  
  303.  
  304.  
  305. long command_device(char *device,char *fname)
  306. {
  307.     /*
  308.     For the Device specified by *device, search each element of the
  309.     assign (since it could be a multi-assign) and try to find a
  310.     command file. A command file can be either an executable file, or
  311.     a script file (one with the script bit set).
  312.  
  313.     Returns:
  314.         0 = can RunCommand this file (seglist_cmd set)
  315.         1 = can source/script/execute this file (new_input set)
  316.       < 0 = error
  317.        -8 = Bad device name
  318.  
  319.     Note that this routine generates only one error of its own. All
  320.     other results are passed straight thru from command_examine ().
  321.     */
  322.  
  323.     long gotlock,            /* we have a directory lock or not */
  324.          result = 0,        /* from command_examine () */
  325.          /* AMK: result initialized with 0 */
  326.          done = 0;            /* found something we could use */
  327.     struct DevProc *dp = NULL;    /* for searching multi-assigned paths */
  328.     struct MsgPort *fstask;        /* for GetFileSysTask () */
  329.     BPTR plock,            /* parent of fname */
  330.          lock,            /* on source directory */
  331.          dir_lock;            /* save current directory */
  332.  
  333.     /*printf("search: %s -> %s\n",device,fname);*/
  334.  
  335.     fstask = GetFileSysTask ();
  336.  
  337.     do {
  338.         dp = GetDeviceProc(device,dp);
  339.         if (dp) {
  340.             SetFileSysTask(dp->dvp_Port);
  341.  
  342.             lock = NULL;
  343.             gotlock = 0;
  344.             if (dp->dvp_Lock) {
  345.                 dir_lock = CurrentDir(dp->dvp_Lock);
  346.                 gotlock = 1;
  347.             }
  348.             else {
  349.                 if (lock=Lock(device,ACCESS_R