/****************************************************************************
 *
 *  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;
}
