/****************************************************************************
 *
 *  null driver V0.0 (c)CopyRight 1988, Gunnar Nordmark.  All Rights Reserved.
 *  
 *  null-handler Ver. 0.0  20-Jul-1988
 *
 *  Gunnar Nordmark
 *  Nora strand 5
 *  182 34 DANDERYD
 *  SWEDEN
 *
 *  |You may freely distribute this source as long as |
 *  |the Copyright notice is left intact.	      |
 ***************************************************************************/

#undef  BADDR
#define BADDR(x)   ((APTR)((long)x << 2))

#define ACTION_FINDINPUT	1005L
#define ACTION_FINDOUTPUT	1006L
#define ACTION_END	 	1007L

#define DOS_FALSE    		0L
#define DOS_TRUE     	       -1L

/* My Globals */

long		    SysBase;
struct Process      *myproc;

_main()
{
    extern void returnpkt();		/* sends back the packet          */
    extern void returnpktplain();	/* use args in Res1               */
    extern struct DosPacket *taskwait();

    	   char       *version = 	"Ver 0.0 (c) Gunnar Nordmark 1988";
    struct DosPacket  *mypkt;      	/* a pointer to the dos packet    */
    struct DeviceNode *mynode;     	/* our device node (parmpkt Arg3) */
    struct FileHandle *fh;	 	/* a pointer to our file handle	  */
    long	      run = TRUE;	/* handler main loop flag	  */
    int		      null_open = 0;	/* null open count		  */

 
	/* Initializing the handler */

    myproc      = (struct Process *)FindTask(0L);
    mypkt       = taskwait(myproc);      /* Wait for my startup message */

	/* I don't need the name or extra info passed in Arg1/2 */

    mynode      	= (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
    mynode->dn_Task 	= &myproc->pr_MsgPort; 
    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2); 

	/* done initial stuff, now for some work */

    while(run) {
	mypkt = taskwait(myproc);

	switch(mypkt->dp_Type) {	/* find what action to perform */

	case ACTION_FINDINPUT:
	case ACTION_FINDOUTPUT:

	    null_open++;

	    fh = (struct FileHandle  *)BADDR(mypkt->dp_Arg1);
	    fh->fh_Arg1 = mypkt->dp_Type;
	    fh->fh_Port = (struct MsgPort *)DOS_FALSE; /* not interactive */

	    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
	    break;

	case ACTION_READ:

	    returnpkt(mypkt, myproc, 0, mypkt->dp_Res2); /* zero-length=EOF */
	    break;

	case ACTION_WRITE:
	    
	    mypkt->dp_Res1 = mypkt->dp_Arg3;  /* tell em we wrote them all */
	    returnpktplain(mypkt, myproc);
	    break;

	case ACTION_END:

	    if (--null_open == 0)
		run = 0;

	    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
	    break;

	default:

	    returnpkt(mypkt, myproc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
	    break;
	}
    } /* end while */
    mynode->dn_Task = FALSE; 
}
