/* PIV.c
 *
 * (c) Copyright 1991 J. Edward Hanway
 * May be redistributed freely for non-commercial purposes as long
 * as the copyright notice remains intact.
 *
 * Spiffs up the 'Please Insert volume FOO:' requester with additional
 * options allowing you to assign or mount the volume.
 *
 * $Id: PIV.c,v 1.1 91/03/13 22:33:20 jeh Exp $
 *
 * $Log:	PIV.c,v $
 * Revision 1.1  91/03/13  22:33:20  jeh
 * Initial revision
 * 
 */
 
#include <exec/types.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <string.h>

#include "PIV.h"

#define LVOAutoRequest -0x015c
#define SAY(s)	Write(_Backstdout, s, strlen(s))

/* stuff for SAS cback.o */

LONG  _stack      = 4000;
char  *_procname  = "_PIV";
LONG  priority    = 0;
LONG  _BackGroundIO = 1;

extern BPTR _Backstdout;

extern long __asm call_AutoRequest(register __a0 struct Window *,
                    register __a1 struct IntuiText *,
                    register __a2 struct IntuiText *,
                    register __a3 struct IntuiText *,
                    register __d0 LONG,
                    register __d1 LONG,
                    register __d2 ULONG,
                    register __d3 ULONG);

extern long do_req(struct Window *, char *);

APTR real_AutoRequest;
BPTR nilfh;

long __asm __saveds
my_AutoRequest(register __a0 struct Window *window,
               register __a1 struct IntuiText *body,
               register __a2 struct IntuiText *posText,
               register __a3 struct IntuiText *negText,
               register __d0 LONG pFlag,
               register __d1 LONG nFlag,
               register __d2 ULONG width,
               register __d3 ULONG height)
{
	if(body->NextText && !strcmp(body->IText, "Please insert volume")) {
		return do_req(window, body->NextText->IText); 
	}
      
	return call_AutoRequest(window, body, posText, negText, pFlag, nFlag, width, height);
}

void
_tinymain(char *s)
{
	struct Task *other_task;
	
	if(_Backstdout) {
		SAY("PIV 1.0 for AmigaDOS 1.3\n\xA9 1991 J. E. Hanway\nFreely redistributable for non-commercial use.\n");
	}
	
	/* If already installed, kill the installed version and exit.
	 */
	Forbid();
	if(other_task = FindTask("*PIV")) {
		Signal(other_task, SIGBREAKF_CTRL_C);
	} else {
		struct Task *this_task = FindTask(NULL);
		this_task->tc_Node.ln_Name[0] = '*';
	}
	Permit();
	
	
	if(other_task) {
		SAY("Removed\n");
		Close(_Backstdout);
	} else {
		if(IntuitionBase = OpenLibrary("intuition.library", 0L)) {
			nilfh = Open("NIL:", MODE_OLDFILE);
			init_semaphores();

			real_AutoRequest = SetFunction(IntuitionBase, (LONG) LVOAutoRequest, (APTR) &my_AutoRequest);

			if(_Backstdout) {
				SAY("Installed\n");
				Close(_Backstdout);
			}
		
			/* allow "break <thistask>" to remove */
			Wait(SIGBREAKF_CTRL_C);
   
			(void) SetFunction(IntuitionBase, (LONG) LVOAutoRequest, real_AutoRequest);

			/* If someone called AutoRequest the microsecond before we
			 * restored it, this should give the code time to grab the inuse
			 * semaphore.  (There are short windows of vulnerability at the
			 * beginning and end of the routine where the inuse semaphore
			 * may be free.)
			 */
			Delay(2);

			/* With the function restored, no new requesters should be started,
			 * but some may be in progress.
			 *
			 * We must wait until the use count drops to zero before
			 * exiting the program.  The inuse semaphore will become
			 * available when no one is in the code.
			 */

			ObtainSemaphore(&inuse_sema);

			Delay(2);

			Close(nilfh);
			CloseLibrary(IntuitionBase);

		} else {
			if(_Backstdout) {
				SAY("Failed\n");
				Close(_Backstdout);
			}
		}
	}
}

