/* libsup.c	-- exec library routines for XPR Kermit */

#include <exec/lists.h>
#include <exec/resident.h>
#include <functions.h>
#include "ckxker.h"
#include "version.h"

/*lint -esym(530,XProtocolBase)		suppress "not initialized" for this */

void myInit(void);
long myOpen(void);
long myClose(void);
long myExpunge(void);

#pragma amicall(XProtocolBase, 0x06, myOpen())
#pragma amicall(XProtocolBase, 0x0c, myClose())
#pragma amicall(XProtocolBase, 0x12, myExpunge())

/* library initialization table, used for AUTOINIT libraries			*/
struct InitTable {
	unsigned long	it_DataSize;		  /* library data space size		*/
	void			**it_FuncTable;		  /* table of entry points			*/
	void 			*it_DataInit;		  /* table of data initializers		*/
	void			(*it_InitFunc)(void); /* initialization function to run	*/
};

void *libfunctab[] = {	/* my function table */
	myOpen,					/* standard open	*/
	myClose,				/* standard close	*/
	myExpunge,				/* standard expunge	*/
	0,

	/* ------	user UTILITIES */
	XProtocolCleanup,
	XProtocolSetup,
	XProtocolSend,
	XProtocolReceive,

	(void *)-1				/* end of function vector table */
};

struct InitTable myInitTab =  {
	sizeof (struct XProtocolBase),
	libfunctab,
	0,						/* will initialize my data in funkymain()	*/
	myInit
};

char myname[] = "xprkermit.library";
char myid[] = "xprkermit " VSTRING " (" __DATE__ ")\r\n";

extern struct Resident	myRomTag;

long
_main(struct XProtocolBase *XProtocolBase, unsigned long seglist)
{
	XProtocolBase->xp_SegList = seglist;

	/* ----- init. library structure  -----		*/
	XProtocolBase->xp_Lib.lib_Node.ln_Type = NT_LIBRARY;
	XProtocolBase->xp_Lib.lib_Node.ln_Name = (char *) myname;	
	XProtocolBase->xp_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
	XProtocolBase->xp_Lib.lib_Version = myRomTag.rt_Version;
	XProtocolBase->xp_Lib.lib_Revision = REVISION;
	XProtocolBase->xp_Lib.lib_IdString = (APTR) myid;
	return 0;
}

long myOpen(void)
{
	struct XProtocolBase *XProtocolBase;
/*
 * We are (should be :-) Re-entrant!
 */
	/* mark us as having another customer				*/
	XProtocolBase->xp_Lib.lib_OpenCnt++;

	/* prevent delayed expunges (standard procedure)		*/
	XProtocolBase->xp_Lib.lib_Flags &= ~LIBF_DELEXP;

	return ((long) XProtocolBase);
}

long
myClose(void)
{
	struct XProtocolBase *XProtocolBase;
	long retval = 0;

	if (--XProtocolBase->xp_Lib.lib_OpenCnt == 0) {

		if  (XProtocolBase->xp_Lib.lib_Flags & LIBF_DELEXP) {
			/* no more people have me open,
			 * and I have a delayed expunge pending
			 */
			retval = myExpunge(); /* return segment list	*/
		}
	}

	return (retval);
}

long myExpunge(void)

{
	struct XProtocolBase *XProtocolBase;
	unsigned long seglist = 0;
	long libsize;
	extern struct Library *DOSBase;

	if (XProtocolBase->xp_Lib.lib_OpenCnt == 0) {
		/* really expunge: remove libbase and freemem	*/

		seglist	= XProtocolBase->xp_SegList;

		Remove(&XProtocolBase->xp_Lib.lib_Node);
								/* i'm no longer an installed library	*/

		libsize = XProtocolBase->xp_Lib.lib_NegSize+XProtocolBase->xp_Lib.lib_PosSize;
		FreeMem((char *)XProtocolBase-XProtocolBase->xp_Lib.lib_NegSize, libsize);
		CloseLibrary(DOSBase);		/* keep the counts even */
	}
	else
		XProtocolBase->xp_Lib.lib_Flags |= LIBF_DELEXP;

	/* return NULL or real seglist				*/
	return ((long) seglist);
}

