/* 
**      This module is the workhorse of Flist.
**      It is here that the commands typed in by the user are:
**
**      a: Scanned for special commands
**      b: replaced for filename expansion
**      c: prepped for ASyncRun
**      d: Run as a Task.
**
*/

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/tasks.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <devices/console.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include "libraries/arpbase.h"
#include "flist.h"

struct ZombieMsg zombie;
struct ProcessControlBlock PCB;

/* Some external variables here */

extern struct Window *winptr;
extern int errno;

#define PCB_SETS PRF_SAVEIO|PRF_INTERACTIVE

long DoDOS(str)
char *str;
{
        long ret;

        if (str[0] != 0) {
                ret = spawnproc(str);
                if (!ret)
                        DisplayBeep(NULL);
        }
}

long spawnproc(str)
char *str;
{
        long i, j, ret;
        char command[90], args[90], buf[90];
        struct ZombieMsg *reply;
        struct MsgPort *port;
        struct FileHandle *fh;
                
        port = winptr->UserPort;

        fh = Open("CON:0/0/640/80/Flist at Work",MODE_NEWFILE);
        if (fh == NULL) {
                auto_req(" I can't seem to Open CON:");
                return FALSE;
        }

        zombie.zm_ExecMessage.mn_ReplyPort = port;
        
        PCB.pcb_StackSize = 10000;      /* Maybe this should be bigger? */
        PCB.pcb_Pri = 0;                /* Everybody runs at 0 */
        PCB.pcb_Control = PCB_SETS;
        PCB.pcb_TrapCode = NULL;        /* Use the defaults */
        PCB.pcb_Input = fh;
        PCB.pcb_Output = fh;
        PCB.pcb_LoadedCode = NULL;
        PCB.pcb_LastGasp = &zombie;     /* I want to be told when the 
                                           process dies */
        PCB.pcb_WBProcess = NULL;
        PCB.pcb_Console.pcb_SplatFile = fh;
        PCB.pcb_Console.pcb_ConName = NULL;

        for(i=0;str[i] != ' ' && str[i] != '\0' && i < 89;i++)
                        command[i] = str[i];

        command[i] = 0;

        /* Now if this isn't weird syntax, I don't know what is */

        if (str[i] == '\0') {
                args[0] = '\n';
                args[1] = '\0';
        } else {
                ++i;
                for(j=0;str[j+i] != '\0' && (j-i < 89);j++)
                                args[j] = str[j+i];
                args[j] = '\0';
        }

#ifdef DEBUG
        sprintf(&buf[0],"Sending -%s- to Execute.",str);
        SetWindowTitles(winptr,0L,buf);
#endif
   /*     ret = ASyncRun(&command[0], &args[0], &PCB); */
   
        ret = Execute(str,NULL,fh);
        Delay(30L);
        
        if (!ret){
                sprintf(&buf[0],"*** ERROR *** Execute returns - %d", IoErr());
                SetWindowTitles(winptr,0L,buf);
                DisplayBeep(NULL);
                Close(fh);
                return FALSE;
        } else {
/*                reply = (struct ZombieMsg *)WaitPort(port); */

                /* Wait for the user to terminate the window */

                ret = Read(fh, buf, 1L);
                sprintf(&buf[0]," Task died with return of %d", ret);
                SetWindowTitles(winptr,0L,buf);
                Delay(30); 
                Close(fh);
        }
}SHAR_EOF
cat << \SHAR_EOF > arpdos.c
/* 
        This module is the workhorse of Flist.
        It is here that the commands typed in by the user are:
  
        a: Scanned for special commands
        b: replaced for filename expansion
        c: prepped for ASyncRun
        d: Run as a Task.
  
*/

#include <stdio.h>
#include "flist.h"

/* Some external variables here */

extern struct Window *winptr;
extern int errno;
extern struct FileLock *lock;
extern long mousey;

#define PCB_SETS PRF_SAVEIO|PRF_INTERACTIVE

long DoDOS(str)
char *str;
{
    long ret;

    if (str[0] != 0) {
            ret = spawnproc(str);
            if (!ret)
                    DisplayBeep(NULL);
    }
    return ret;
}

long spawnproc(str)
char *str;
{
        long i, j, ret, ret1, pnt;
        char command[90], args[90], buf[1000], path[1000];
        struct FileHandle *fh;

    /*  In case your wondering, I'm trying to put the window under the 
        mouse. Why? Because I want to make it easy to kill it later! */

        i = (mousey > 119) ? 120: mousey;

        sprintf(buf,"CON:0/%d/640/80/Flist at Work", i);
        fh = Open(buf,MODE_NEWFILE);
        if (fh == NULL) {
                auto_req(" I can't seem to Open CON:");
                return FALSE;
        }

/*  Here be the LARGEST Kluge I have ever run across in AmigaDOS...
    Execute() must be fed the command 'cd current.directory' as part
    of the string, if you expect to be executing out of the current
    directory that is! */

        PathName(lock, path);
        strcpy(buf, "cd \"");
        strcat(buf, path);
        pnt = strlen(buf);
        strcat(buf, "\"\n");
        strcat(buf, str); 

#ifdef DEBUG
        sprintf(path,"Sending -%s- to Execute.",buf);
        SetWindowTitles(winptr,-1L,path);
#endif

        ret = Execute(buf,NULL,fh);
        
        if (!ret){
#ifdef DEBUG 
                sprintf(&buf[0],"*** ERROR *** Execute returns - %ld", IoErr());
                SetWindowTitles(winptr,-1L,buf);
#endif
                DisplayBeep(NULL);
                Close(fh);
                return FALSE;
        } else {

        /* Wait for the user to terminate the window */

                buf[0] = 0x9b;  buf[1] = 0x34;
                buf[2] = 0x30;  buf[3] = 0x3b;
                buf[4] = 0x33;  buf[5] = 0x33;
                buf[6] = 0x6d;  buf[7] = 0x0;
                strcat(buf, " Hit return to continue"); 
                Write(fh, buf, strlen(buf));
                ret1 = Read(fh, buf, 1L);
                Close(fh);
        }
        return TRUE;
}
