/*
	written by Daniel Balster, dbalster@uni-paderborn.de
*/

#include <exec/exec.h>
#include <dos/dos.h>
#include <devices/cd.h>
#include <proto/exec.h>
#include <proto/dos.h>

#define AllocStruct(X)	AllocVec(sizeof(struct X),MEMF_CLEAR|MEMF_PUBLIC)
#define FreeStruct(X)	if (X) FreeVec(X)

#define CHANGESIGNAL	(1L<<(ULONG)signal)

/* get the external assembler-irq code */

extern VOID ChangeNotifier (VOID);

ULONG signal;

#define TEMPLATE "DEVICE/A,UNIT/N/A,INSERT,REMOVE,QUIET/S"

struct {
	STRPTR	device;
	ULONG	unit;
	STRPTR	insert;
	STRPTR	remove;
	BOOL	quiet;
	ULONG	pads[11];
} args = {0};

int main (void)
{
	struct RDArgs *rdargs;
	struct MsgPort *mp;
	struct IOStdReq *ior;
	struct Interrupt *irq;
	
	ULONG signals;
	BOOL quit = FALSE;

	if (!(signal = AllocSignal(-1))) return RETURN_FAIL;	/* we *NEED* a signal */

	if (rdargs=ReadArgs(TEMPLATE,(LONG*)&(args),NULL))
	{
		if(!args.quiet) PutStr("MediaNotify 1.0.0 - ©1995 by Daniel Balster\n");

		if (irq=AllocStruct(Interrupt))
		{
			if(mp=CreateMsgPort())
			{
				if(ior=(struct IOStdReq*)CreateIORequest(mp,sizeof(struct IOStdReq)))
				{
					if(!OpenDevice(args.device,*(ULONG*)args.unit,ior,0))
					{
						if(!args.quiet) PutStr("MediaNotify Handler installed.\n");

						irq->is_Code		= ChangeNotifier;
						irq->is_Data		= (APTR) FindTask(0);
						irq->is_Node.ln_Pri	= 10;
						irq->is_Node.ln_Type	= NT_INTERRUPT;
						irq->is_Node.ln_Name	= "MediaNotify Handler";

						ior->io_Command	= TD_ADDCHANGEINT;
						ior->io_Flags	= 0;
						ior->io_Length	= sizeof(struct Interrupt);
						ior->io_Data	= (APTR) irq;
						SendIO(ior);
						
						if(!ior->io_Error)
						{

						while (!quit)
						{
							signals = Wait (SIGBREAKF_CTRL_C|CHANGESIGNAL);
							
							if (signals&SIGBREAKF_CTRL_C)
							{
								quit=TRUE;
							}
							
							if (signals&CHANGESIGNAL)
							{
								ior->io_Command	= TD_CHANGESTATE;
								ior->io_Flags	= IOF_QUICK;
								ior->io_Length	= 0;
								DoIO(ior);
							
								if (ior->io_Actual)
								{
									if(!args.quiet) PutStr("Medium was removed.\n");
									Execute(args.remove,NULL,NULL);
								}
								else
								{
									if(!args.quiet) PutStr("Medium was inserted.\n");								
									Execute(args.insert,NULL,NULL);
								}
							}
						}

							if(!args.quiet) PutStr("MediaNotify Handler removed.\n");

							ior->io_Command	= TD_REMCHANGEINT;
							ior->io_Flags	= 0;
							ior->io_Length	= sizeof(struct Interrupt);
							ior->io_Data	= (APTR) irq;
							DoIO(ior);
						}
						else PrintFault (IoErr(),0);
						
						CloseDevice((struct IORequest*)ior);

					} /* opendev err */
				
					DeleteIORequest((struct IORequest*)ior);
				} /* ioreq err */

				DeleteMsgPort(mp);
			} /* msgport err */
			
			FreeStruct(irq);
		} /* irq node err */
		
		FreeArgs(rdargs);
	} else PrintFault(IoErr(),0);

	FreeSignal (signal);

	return RETURN_OK;
}
