home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / shell / csh550src.lha / run.c < prev    next >
C/C++ Source or Header  |  1996-05-02  |  23KB  |  959 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_READ)) {
  350.                     dir_lock = CurrentDir(lock);
  351.                     gotlock = 1;
  352.                 }
  353.             }
  354.             if (gotlock) {
  355.                 result = command_examine(fname,&plock);
  356.                 /*
  357.                     NOTE: Philosophically speaking, if result <= -2, what
  358.                     should we do? This means that command_examine () actually
  359.                     found a file by the correct name, but it was unsuitable for
  360.                     some reason.
  361.                     Currently, we continue to search, in hopes that St. Nicholas
  362.                     will soon be here...(ie, we will find a file that meets our
  363.                     criteria). This is questionable as to its correctness.
  364.                 */
  365.                 if (result<0) {
  366.                     done = 0;
  367.                 }
  368.                 else {
  369.                     BPTR hdir_lock;
  370.                     if (plock)
  371.                         hdir_lock = plock;
  372.                     else if (lock)
  373.                         hdir_lock = lock;
  374.                     else if (dp->dvp_Lock)
  375.                         hdir_lock = dp->dvp_Lock;
  376.                     else
  377.                         hdir_lock = NULL;
  378. /*
  379.                     {char buf[256];
  380.                     if (hdir_lock && NameFromLock(hdir_lock,buf,256))
  381.                         printf("hdir_lock: %s\n",buf);
  382.                     }
  383. */
  384.                     done = 1;
  385.                     /*
  386.                     --- This was from XSHell, but wasn't correct ---
  387.                     Myprocess->pr_HomeDir = DupLock(lock?lock:dp->dvp_Lock);
  388.                     */
  389.                     Myprocess->pr_HomeDir = DupLock(hdir_lock);
  390.                     UnLock(plock);
  391.                 }
  392.                 if (lock) {
  393.                     UnLock(lock);
  394.                     lock = NULL;
  395.                 }
  396.                 CurrentDir(dir_lock);
  397.             }
  398.         }
  399.     } while (!done                               &&
  400.          dp && (dp->dvp_Flags & DVPF_ASSIGN) &&
  401.          IoErr() == ERROR_OBJECT_NOT_FOUND);
  402.  
  403.     SetFileSysTask (fstask);
  404.     if (dp) FreeDeviceProc(dp);
  405.  
  406.     if (!done && result >= 0) {
  407.         /* Can happen when GetDeviceProc returns a NULL dp on the first go. */
  408.         result = -8;
  409.     }
  410.  
  411.     return result;
  412. }
  413.  
  414.  
  415.  
  416. long command_processor(long abs_cmd,char *device,char *fname)
  417. {
  418.     /*
  419.     Results:
  420.         Those returned by command_examine () and command_device ().
  421.  
  422.         0 = can RunCommand (seglist_cmd set)
  423.         1 = can source/script/execute (new_input set)
  424.       < 0 = error
  425.     */
  426.  
  427.     struct PathList *pl;    /* to parse the PATH */
  428.     long result,        /* from command_examine () or command_device () */
  429.          sub_cmd;        /* command is in a sub-directory */
  430.     BPTR plock;        /* points to parent directory of fname */
  431.     char buf [256];        /* where to put elements of the Cli Path */
  432.     long i;            /* browse thru prghash_num's */
  433.     char *filepart;        /* file-part of prghash_list items */
  434.     long fnamelen;        /* length of fname */
  435.  
  436.     sub_cmd = abs_cmd & 2;    /* a '/' was found in the input filename */
  437.     abs_cmd &= 1;        /* so it only has one meaning: a ':' was found */
  438.  
  439.     if (*device == '\0')
  440.         abs_cmd = 0;    /* handle special case of empty device */
  441.  
  442.     if (abs_cmd) {        /* absolute path like 'dh0:myprog' */
  443.         result = command_device(device,fname);
  444.         return result;
  445.     }
  446.     if (sub_cmd) {        /* relative path like 'mydir/myprog' */
  447.         result = command_examine (fname, &plock);
  448.         if (result < 0) return result;
  449.         /*
  450.             NOTE: Is the following OK? Or should we DupLock() and then
  451.             UnLock()? I don't see why....
  452.         */
  453.         Myprocess->pr_HomeDir = plock;
  454.         plock = NULL;
  455.         return result;
  456.     }
  457.     /* file in current directory */
  458.     result = command_examine(fname,&plock);
  459.     if (result >= 0) {
  460.         Myprocess->pr_HomeDir = plock;
  461.         plock = NULL;
  462.         return result;
  463.     }
  464.  
  465.     /* BEGIN -- AMK TEST FOR HASH-LIST -- BEGIN */
  466.  
  467.     fnamelen = strlen(fname);
  468.  
  469.     for(i=0; i<prghash_num; i++) {
  470.         if (filepart=FilePart(prghash_list[i])) {
  471.             if ((o_abbrev&2 && strnicmp(fname,filepart,fnamelen)==0)
  472.             || (!(o_abbrev&2) && stricmp(fname,filepart)==0))
  473.             {
  474.                 /*printf("hash hit: %s -> %s\n",fname,prghash_list[i]);*/
  475.                 result = command_examine(prghash_list[i],&plock);
  476.                 if (result >= 0) {
  477.                     Myprocess->pr_HomeDir = plock;
  478.                     plock = NULL;
  479.                     return result;
  480.                 }
  481.             }
  482.         }
  483.     }
  484.  
  485.     if (prghash_num>0 && !(o_abbrev&4))
  486.         return result;
  487.  
  488.     for(i=0; i<prghash_num; i++) {
  489.         if (filepart=FilePart(prghash_list[i])) {
  490.             if (strnicmp(fname,filepart,fnamelen)==0) {
  491.                 /*printf("hash hit: %s -> %s\n",fname,prghash_list[i]);*/
  492.                 result = command_examine(prghash_list[i],&plock);
  493.                 if (result >= 0) {
  494.                     Myprocess->pr_HomeDir = plock;
  495.                     plock = NULL;
  496.                     return result;
  497.                 }
  498.             }
  499.         }
  500.     }
  501.  
  502.     if (prghash_num>0 && !(o_abbrev&8))
  503.         return result;
  504.  
  505.     /* END -- AMK TEST FOR HASH-LIST -- END */
  506.  
  507.     /* DOS search path */
  508.     /* Forbid(); */
  509.     pl = (struct PathList *)BADDR(Mycli->cli_CommandDir);
  510.     while (pl && !dobreak()) {
  511.         if (pl->pl_PathLock) {
  512.             if (NameFromLock(pl->pl_PathLock,buf,256)) {
  513.                 result = command_device(buf,fname);
  514.                 if (result >= 0) {
  515.                     /* Permit(); */
  516.                     return result;
  517.                 }
  518.             }
  519.             else {
  520.                 fprintf(stderr,"csh.command_processor: NameFromLock() failed\n");
  521.             }
  522.         }
  523.         pl = (struct PathList *)BADDR(pl->pl_NextPath);
  524.     }
  525.     /* Permit(); */
  526.  
  527.     /* Last, but CERTAINLY not least, search 'C:' */
  528.     if (!dobreak())
  529.         result = command_device("C:",fname);
  530.  
  531.     return result;
  532. }
  533.  
  534.  
  535.  
  536. /* no endless loop for recursive calls of MySyncRun() */
  537. static BOOL IsRecursiveMySyncRun = FALSE;
  538.  
  539. int
  540. MySyncRun( char *com, char *args, BPTR in, BPTR out, int nosync )
  541. {
  542.     struct Segment *cmdseg = NULL;
  543.     int len=strlen(args);
  544.     char myname[256];
  545.     BPTR myhdir,mymod;
  546.     long abs_cmd = 0;
  547.     char *p,*pname=strdup(com), *ppath=strdup(com), *pdev=strdup(com);
  548.     long rslt = -1;
  549.  
  550. /*
  551.     old_inp_fh = SelectInput (Mycli->cli_CurrentInput);
  552.     old_out_fh = SelectOutput(Mycli->cli_StandardOutput);
  553.     Flush(Input());
  554.     Flush(Output());
  555. */
  556.     GetProgramName(myname,255);
  557.     myhdir = Myprocess->pr_HomeDir;
  558.     mymod  = Mycli->cli_Module;
  559.  
  560.     /* clear it so that we don't "free" ourself on MySyncRun_done: */
  561.     Myprocess->pr_HomeDir = NULL;
  562.     Mycli->cli_Module = NULL;
  563.  
  564.     args[len]='\n'; args[len+1]=0;        /* trailing '\n' */
  565.  
  566.     if (!pname || !ppath || !pdev)
  567.         goto MySyncRun_done;
  568.  
  569.     if (p=FilePart(com))
  570.         strcpy(pname,p);
  571.  
  572.     if (p=strchr(pdev,':')) {
  573.         if (*(p+1)) {        /* is ':' last char? */
  574.             abs_cmd |= 1;
  575.             strcpy(ppath,++p);
  576.             *p='\0';
  577.         }
  578.         else {            /* allow "bla:" for program name */
  579.             strcpy(pdev,"");
  580.             strcpy(ppath,com);
  581.             strcpy(pname,com);
  582.         }
  583.     }
  584.     else strcpy(pdev,"");
  585.  
  586.     if (strchr(ppath,'/'))
  587.         abs_cmd |= 2;
  588.  
  589. #if 0
  590.     kprintf("prog: %s, arg: %s, async: %s\n",com,args,nosync?"yes":"no");
  591.     kprintf("pdev: %s, ppath: %s, pname: %s [%ld]\n",pdev,ppath,pname,abs_cmd);
  592. #endif
  593.  
  594.     seglist_cmd = NULL;
  595.     new_input = NULL;
  596.  
  597.     if (!abs_cmd || strnicmp(com,"C:",2)==0) {
  598.         char *comname = (strnicmp(com,"C:",2)==0) ? FilePart(com) : com ;
  599.         Forbid();
  600.         if (!(cmdseg = FindSegment(comname,NULL,FALSE)))
  601.             cmdseg = FindSegment(comname,NULL,TRUE);
  602.         if (cmdseg) {
  603. /*
  604.     Randell says ...
  605.             if ((cmdseg->seg_UC < CMD_DISABLED) ||
  606.     ... but if a command is disabled why we should execute it?
  607. */
  608.             if ((cmdseg->seg_UC <= CMD_DISABLED) ||
  609.                 (cmdseg->seg_UC == CMD_SYSTEM))
  610.                 cmdseg = NULL;
  611.             else if (cmdseg->seg_UC >= 0)
  612.                 cmdseg->seg_UC++;
  613.         }
  614.         Permit();
  615.         if (cmdseg) {
  616.             seglist_cmd = cmdseg->seg_Seg;
  617.             Myprocess->pr_HomeDir = NULL;
  618.         }
  619.     }
  620.  
  621.     if (!cmdseg) {
  622.         rslt = command_processor(abs_cmd,pdev,ppath);
  623.         /*printf("cmd_processor returned %ld, %ld\n",rslt,IoErr());*/
  624.         if (rslt<0) {
  625.             /*printf("Object not found (rc=%d): %s\n",rslt,pname);*/
  626.             goto MySyncRun_done;
  627.             /*return -1;*/
  628.         }
  629.     }
  630.  
  631.     if (new_input) {                /* rslt = 1 */
  632.         enum {DOS_SCRIPT,REXX_SCRIPT,OTHER_SCRIPT} scp_type;
  633.         char scp_name[256];
  634.         char scmdbuf[256];
  635.         char *exec_buf;
  636.         char *scommand = "execute";
  637.         FILE *sfp;
  638.         int escnum,i;
  639.  
  640.         NameFromFH(new_input,scp_name,255);
  641.         Close(new_input);
  642.         new_input = NULL;
  643.  
  644.         /*kprintf("launch script (%s) %s, %s, %s, args: %s ...\n",scp_name,pdev,ppath,pname,args);*/
  645. #if 0
  646.         sys_tags[1].ti_Tag  = SYS_Output;
  647.         sys_tags[1].ti_Data = (ULONG)Myprocess->pr_COS;
  648. #endif
  649.         scp_type = DOS_SCRIPT;
  650.  
  651.         if (sfp=fopen(scp_name,"r")) {
  652.             char *p;
  653.             if (fgets(scmdbuf,255,sfp)) {
  654.                 if (strncmp(scmdbuf,"/*",2)==0) {
  655.                     scommand = "rx";
  656.                     scp_type = REXX_SCRIPT;
  657.                     /*
  658.                         Space im Filenamen mit:
  659.                         scommand = "rx \"call 'tgled led' rudi\"";
  660.                         Allerdings dann Probleme mit Return-Codes.
  661.                      */
  662.                 }
  663.                 else if (strncmp(scmdbuf,"#!",2)==0 || strncmp(scmdbuf,";!",2)==0) {
  664.                     if (p = strchr(scmdbuf,'\n')) {
  665.                         *p = '\0';
  666.                         for (p=scmdbuf+2; *p==' ' || *p=='\t'; ++p)
  667.                             ;
  668.                         scommand = p;
  669.                         scp_type = OTHER_SCRIPT;
  670.                         
  671.                         if (o_mappath && scommand[0]=='/') {
  672.                             if (p=strchr(scommand+1,'/')) {
  673.                                 ++scommand;
  674.                                 *p = ':';
  675.                             }
  676.                         }
  677.                     }
  678.                     else
  679.                         fprintf(stderr,"%s: first line too long\n",scp_name);
  680.                 }
  681.             }
  682.             fclose(sfp);
  683.         }
  684.  
  685.         /* escape critical chars like <>"=* with * (asterix) */
  686.  
  687.         /* count number of chars to be escaped */
  688.         for (escnum=0,i=strlen(args)-1; i >= 0; --i) {
  689.             if (args[i]=='>' || args[i]=='<' || args[i]=='*') /*|| args[i]=='"' || args[i]=='=')*/
  690.                 ++escnum;
  691.         }
  692.  
  693.         /*kprintf("scommand: %s, scp_name: %s, args: %s",scommand,scp_name,args);*/
  694.  
  695.         if (exec_buf = malloc(strlen(scommand)+2+strlen(scp_name)+2+strlen(args)+1+escnum)) {
  696.  
  697.             /* RunCommand(Execute) doesn't work, must use System() */
  698.  
  699.             if (!IsRecursiveMySyncRun && scp_type!=DOS_SCRIPT && stricmp(scommand,"execute")) {
  700.                 sprintf(exec_buf,"%s%s%s %s",
  701.                     (scp_type!=REXX_SCRIPT) ? "\"" : "",
  702.                     scp_name,
  703.                     (scp_type!=REXX_SCRIPT) ? "\"" : "",
  704.                     args
  705.                 );
  706.                 /*kprintf("yeah, recursive MySyncRun: %s %s\n",scommand,exec_buf);*/
  707.                 IsRecursiveMySyncRun = TRUE;
  708.                 if (MySyncRun(scommand,exec_buf,in,out,nosync) >= 0) {
  709.                     /*kprintf("okay... exit...\n");*/
  710.                     IsRecursiveMySyncRun = FALSE;
  711.                     free(exec_buf);
  712.                     goto MySyncRun_done;
  713.                 }
  714.                 IsRecursiveMySyncRun = FALSE;
  715.             }
  716.  
  717.             sprintf(exec_buf,"%s %s%s%s %s",
  718.                 scommand,
  719.                 (scp_type!=REXX_SCRIPT) ? "\"" : "",
  720.                 scp_name,
  721.                 (scp_type!=REXX_SCRIPT) ? "\"" : "",
  722.                 args
  723.             );
  724.  
  725.             /*kprintf("exec_buf: %s",exec_buf);*/
  726.  
  727.             /*{int i;
  728.             for (i=0; i<strlen(args); i++)
  729.                 printf("args[%d] : %d\n",i,args[i]);
  730.             }*/
  731.  
  732.             /* escape critical chars, end when all chars are found */
  733.  
  734.             for (i=strlen(exec_buf)-1; i>=0 && escnum>0; --i) {
  735.                 if (exec_buf[i]=='>' || exec_buf[i]=='<' || exec_buf[i]=='*') /*|| exec_buf[i]=='"' || exec_buf[i]=='=')*/ {
  736.                     strins(&exec_buf[i],"*");
  737.                     --escnum;
  738.                 }
  739.             }
  740.  
  741.             {char *p;
  742.             if (p = strchr(exec_buf,'\n'))
  743.                 *p = '\0';
  744.             }
  745.  
  746.             /*kprintf("exec_buf: %s\n",exec_buf);*/
  747.  
  748.             /*kprintf("start: |%s|\n",exec_buf);*/
  749.  
  750. #define SYSTEM_MAXLEN 512
  751. /* eigentlich sogar 518 */
  752.  
  753. #if 0
  754.             if (getenv("cshexeclen")) {
  755.                 long elen = atoi(getenv("cshexeclen"));
  756.                 if (strlen(exec_buf) > elen) {
  757.                     kprintf("csh: command line too long, cutting at %ld\n",elen);
  758.                     exec_buf[elen] = '\0';
  759.                 }
  760.             }
  761. #endif
  762.             if (strlen(exec_buf) > SYSTEM_MAXLEN) {
  763.                 fprintf(stderr,"csh: command line too long (cutting at %ld)\n",SYSTEM_MAXLEN);
  764.                 exec_buf[SYSTEM_MAXLEN] = '\0';
  765.             }
  766.  
  767.             rslt = SystemTags(exec_buf,SYS_Input,(ULONG)Input(),SYS_Output,(ULONG)Output(),TAG_END);
  768.             /*kprintf("  end: return code %ld\n",(LONG)rslt);*/
  769.             free(exec_buf);
  770.         }
  771.         else {
  772.             fprintf(stderr,"%s: we are out of memory for System()\n",scp_name);
  773.             set_returncodes(RETURN_FAIL,ERROR_NO_FREE_STORE);
  774.             rslt = RETURN_FAIL;
  775.         }
  776.  
  777.         /*clean_up_io();*/
  778.     }
  779.  
  780.     if (seglist_cmd) {                /* rslt = 0 */
  781.         struct Task *mytask;
  782.         ULONG old_sigalloc;
  783.         BYTE old_pri;
  784.  
  785.         /*
  786.          *  This is inspired by Gary Duncan who was inspired by Wshell ;-)
  787.          *  Save the old signal mask and task priority to see if some
  788.          *  programs don't deallocate their allocated signals or modify
  789.          *  the task priority.
  790.          */
  791.  
  792.         mytask       = (struct Task *)Myprocess;    /* just for readability.. */
  793.         old_sigalloc = mytask->tc_SigAlloc;        /* hold values before command execution */
  794.         old_pri      = mytask->tc_Node.ln_Pri;        /* hold values before command execution */
  795.  
  796.         SetIoErr(0);
  797.  
  798.         if (!SetProgramName(pname))
  799.             SetProgramName("CSH-program");
  800.  
  801.         if (Mycli->cli_DefaultStack < 1000)
  802.             Mycli->cli_DefaultStack=4000;
  803.  
  804.         Mycli->cli_Module = seglist_cmd;
  805.         rslt = RunCommand(seglist_cmd,Mycli->cli_DefaultStack*4,args,strlen(args));
  806.  
  807.         if ((rslt == -1) && (IoErr()==ERROR_NO_FREE_STORE)) {
  808.             fprintf(stderr,"we are out of memory for RunCommand()\n");
  809.             set_returncodes(RETURN_FAIL,ERROR_NO_FREE_STORE);
  810.             rslt = RETURN_FAIL;
  811.             SetProgramName(myname);
  812.             goto MySyncRun_done;
  813.         }
  814.  
  815.         set_returncodes(rslt,IoErr());
  816.  
  817.         SetProgramName(myname);
  818.  
  819.         /*
  820.          *  now see if naughty command messed things up ...
  821.          */
  822.         if (old_sigalloc != mytask->tc_SigAlloc) {
  823.             fprintf(stderr, "Warning! Unreleased signal(s); (%08X)\n",
  824.                     old_sigalloc ^ mytask->tc_SigAlloc);
  825.         }
  826.         if (old_pri != mytask->tc_Node.ln_Pri) {
  827.             fprintf(stderr, "Warning! CLI priority changed from %d to %d\n",
  828.                     old_pri, mytask->tc_Node.ln_Pri);
  829.         }
  830.     }
  831.  
  832. MySyncRun_done:
  833.     if (cmdseg) {
  834.         Forbid();
  835.         if (cmdseg->seg_UC>0)
  836.             cmdseg->seg_UC--;
  837.         Permit();
  838.         Mycli->cli_Module = NULL;
  839.     }
  840.  
  841.     if (!cmdseg && seglist_cmd) {
  842.         if (Mycli->cli_Module)
  843.             UnLoadSeg(Mycli->cli_Module);
  844.         Mycli->cli_Module = NULL;
  845.         seglist_cmd = NULL;
  846.     }
  847.  
  848.     if (Myprocess->pr_HomeDir) {
  849.         /*
  850.         char hd[256];
  851.         if (NameFromLock(Myprocess->pr_HomeDir,hd,255))
  852.             printf("homedir set to %s, now unlocking.\n",hd);
  853.         else {
  854.             fprintf(stderr,"csh.MySyncRun: NameFromLock() failed\n");
  855.             printf("homedir's name too long, now unlocking.\n");
  856.         }
  857.         */
  858.         UnLock(Myprocess->pr_HomeDir);
  859.         Myprocess->pr_HomeDir = NULL;
  860.     }
  861.  
  862.     Myprocess->pr_HomeDir = myhdir;
  863.     Mycli->cli_Module     = mymod;
  864.  
  865.     if (pname) free(pname);
  866.     if (ppath) free(ppath);
  867.     if (pdev)  free(pdev);
  868.  
  869.     /*clean_up_io();*/
  870.  
  871. /*
  872.     old_out_fh = SelectOutput (Mycli->cli_StandardOutput);
  873.     old_inp_fh = SelectInput  (Mycli->cli_CurrentInput);
  874. */
  875.  
  876.     return rslt;
  877. #if 0
  878.     if (done) return rslt;
  879.  
  880.     char buf2[200];
  881.     args[len]=0;        /* remove trailing '\n' */
  882.  
  883.     printf("trying old style...\n");
  884.  
  885.     if( nosync ) {
  886.         sprintf(buf2,"%s %s",com,args);
  887.         Execute(buf2,0,Myprocess->pr_COS);
  888.         return 0;
  889.     }
  890.  
  891.     if( (ret= SyncRun( com, args, in, out ))>=0 )
  892.         return ret;
  893.  
  894.     if( ret==PR_NOMEM /* -2L */ ) {
  895.         ierror(NULL,103);
  896.         return 20;
  897.     }
  898.  
  899.     return -1;
  900. #endif
  901. }
  902.  
  903.  
  904. #if 0
  905. int
  906. do_which( char *str )
  907. {
  908.     char *got, *com=av[1];
  909.  
  910.     if( get_var(LEVEL_ALIAS,com) ) {
  911.         printf("Shell Alias '%s'\n",com);
  912.         return 0;
  913.     }
  914.  
  915.     if( *(got=find_internal( com ))>1 ) {
  916.         printf("Shell Internal '%s'\n",got);
  917.         return 0;
  918.     }
  919.  
  920.  
  921.  
  922.     printf( "Not found\n" );
  923.     return 20;
  924. }
  925. #endif
  926.  
  927.  
  928. char *
  929. dofind( char *cmd, char *ext, char *buf, char *path)
  930. {
  931.     char *ptr, *s=path, *ret=NULL;
  932.  
  933.     Myprocess->pr_WindowPtr = (APTR)(-1);
  934.     sprintf(buf,"%s%s",cmd,ext);
  935.     if (exists(buf)) {
  936.         ret=buf;
  937.         goto terminate;
  938.     }
  939.     if ((char*)FilePart(buf)==buf) {
  940.         if( *path=='_' )
  941.             s = get_var(LEVEL_SET, path);
  942.         while (s && *s) {
  943.             for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++;
  944.             if( ptr[-1]!=':' && ptr[-1]!='/')
  945.                 *ptr++='/';
  946.             sprintf(ptr, "%s%s", cmd, ext);
  947.             if (exists(buf)) {
  948.                 ret=buf;
  949.                 goto terminate;
  950.             }
  951.             if (*s) s++;
  952.         }
  953.     }
  954. terminate:
  955.     Myprocess->pr_WindowPtr = o_noreq ? (APTR) -1L : 0L/*Mywindow*/;
  956.     return ret;
  957. }
  958.  
  959.