/*
DATE: 1-July-88
Test of ASyncRun by A. Kirk, co-author of AMIC-TERM, author of AMIC-TALK.
Freely distributable if ARC file and this message remains intact.
Revisions, corrections, or extensions welcome. 

Leave Email on:
AMIC-2000, 707-579-0523, a. kirk.
BIX                       alkirk.
VOICE      707-546-8532.

Compiled with MANX 3.6a

cc asr.c
ln asr.o -larp -lc

Feel free to use this code for anything.
*/

  

#include <libraries/dosextens.h>
#include <libraries/dos.h>
#include <libraries/filehandler.h>

#include <intuition/intuition.h>

#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/exec.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <exec/ports.h>


#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>

#include <libraries/arpbase.h>
#include <arpfunctions.h>

#ifdef NULL
#undef NULL
#endif
#define NULL 0L

struct ArpBase             *ArpBase = NULL;
struct ProcessControlBlock *AcB     = NULL;
struct MsgPort             *Myport  = NULL;
struct ZombieMsg           *Zm      = NULL;
struct Library             *IB      = NULL, *DB= NULL;
extern UBYTE               *AllocMem();
extern struct MsgPort      *CreatePort();
struct Library             *OpenLibrary();
extern VOID                *CloseLibrary();
extern long                AsyncRun();  

struct UserAnchor {
	struct	AnchorPath	ua_AP;
	BYTE	moremem[255];
};

/*
char *cmd[12] = {
                "ls",
                "dir",
                "ls",
                "dir",
                "am",
                "info",
                "ls",
                "dir",
                "ls",
                "dir",
                "am",
                "info",
                };
*/


VOID doit(i,j)
register char *i,*j; 
{

    long cli;

    Zm->zm_ExecMessage.mn_ReplyPort = Myport;
    AcB->pcb_StackSize   = 25000L;
    AcB->pcb_Pri         = 0;
    AcB->pcb_LastGasp    = Zm;
    AcB->pcb_Control     = (BYTE)(PRB_SAVEIO);

    cli = ASyncRun(i,j,AcB);
        
    if(cli > -1)
       Wait(1L << Myport->mp_SigBit);
    else
       Printf("%s failed, ASyncRun returned %ld\n",i,cli);

}

main(argc,argv)
SHORT argc;
BYTE **argv;
{

    extern    struct FileHandle *Open();
    extern    VOID              Close();

    register                    char *s = NULL, *r = NULL;

    struct    FileHandle        *redir  = NULL;

    struct    UserAnchor        *Anchor = NULL;

    LONG                        Result  = 0,    ci = 0;
    char                        temp[255];
    UBYTE                       i;


    ArpBase = (struct ArpBase *)OpenLibrary(ArpName, ArpVersion);
    IB      = ArpBase->IntuiBase;
    DB      = ArpBase->DosBase;

    Myport  = CreatePort("test",0L);

    Zm  = (struct ZombieMsg *)ArpAlloc((ULONG)sizeof(struct ZombieMsg));
    AcB = (struct ProcessControlBlock *)ArpAlloc((ULONG)sizeof(struct ProcessControlBlock));

    Myport->mp_Node.ln_Type = NT_MSGPORT;
    Myport->mp_Flags        = PA_SIGNAL;

    if(!(Zm && Myport && AcB))
       goto out;


    Puts("");

    Puts("Error message returned only upon failure.\n");

 
t:  temp[0] = '\0';
    Puts("Type '1' <CR>  to check performance of ASuncRun with files in the current Directory.");
    Puts("Type '2' <CR>  to test individual command with ASyncRun and wait for return.");
    Puts("Type 'Control \\' to terminate.\n");

    putchar('?');

    if(gets(temp) == NULL) 
        goto out;

    switch (temp[0])
    {
        case '1': goto a;
        case '2': goto b;
        case '': goto out;
        default : Puts("\nThats not what I need!! Try again.\n");
                  goto t;
    }

 
a:  if(Anchor = (struct UserAnchor *)ArpAlloc((ULONG)sizeof( *Anchor )))
	Anchor->ua_AP.ap_Length = 255;
		
    Result = FindFirst( "*", Anchor);

    while (Result == 0)
    {
       Puts(Anchor->ua_AP.ap_Buf);

       if (Anchor->ua_AP.ap_Info.fib_DirEntryType < 0)
          doit(Anchor->ua_AP.ap_Buf,"\n");

       Result = FindNext(Anchor);
    }

    FreeAnchorChain(Anchor);

    if (Result == ERROR_BUFFER_OVERFLOW)
	    Puts("I should have allocated a larger buffer. Sorry!");
    goto out;



/*  Scott: 


  for(i=0;i<12;i++)
  {
    Zm->zm_ExecMessage.mn_ReplyPort = Myport;
    AcB->pcb_StackSize   = 25000L;
    AcB->pcb_Pri         = 0;
    AcB->pcb_LastGasp    = Zm;
    AcB->pcb_Control     = (BYTE)(PRB_SAVEIO);

    ci = ASyncRun(cmd[i],NOCMD,AcB);
        
    if(ci > -1)
       Wait(1L << Myport->mp_SigBit);
    else
       Printf("%s failed, ASyncRun returned %ld\n",temp,ci);
  }
 
  Puts("first test done");  if this hasn't failed, should continue to next 


*************************************************/

  
b:  Puts("");
    Puts("Type 'Control \\' to terminate.\n");
    Puts("Redirection nust be:  |command >nnnnn args|\n");

    for(;;)        /* THIS SECTION READS INPUT AND PASSES IT TO ASYNCRUN */
    {
       putchar(':');
       
       for(i=0; i<254 ;i++)
           temp[i] = '\0';
          

       if(gets(temp) == NULL) 
           break;                               /*  CNTRL \ breaks */

       for(s=temp; *s && !isspace(*s); s++)  
           ;

       if(s == &temp)                           /*  CR  */
           continue;

       *s++ = '\0';

       if (*s)
       {
           while(*s && isspace(*s))
              s++;
       }

       else 
           s    = "\n";

       if(s[0] == '>')
       {
           s++;
           for(r=s; *r && !isspace(*r);r++)
              ;
           *r++ = '\0';
           redir = Open(s,MODE_NEWFILE);

           if(!redir)
           {
               Printf("Unable to open redirection file: %s\n",s);
               continue;
           } 
   
           AcB->p_Output = redir;
           while(*r && isspace(*r))
              r++;

           if(!*r)
              r = "\n";

       }
       else
          r = s;
       
       doit(temp,r);
       AcB->p_Output = NULL;
       s = NULL;   
       r = NULL;

/*       if(redir)
          Close(redir);*/  /* should be able todo this, but crashes if we try */
   }

out:
    DeletePort(Myport);
    CloseLibrary(ArpBase);


}