#include "nfsthings.h"

/** 
 **   INTERNAL METHOD FOR KEEPING FILEHANDLES & LOCKS
 **/

/** INTERNAL FILE HANDLES (fh_Arg1 on caller machine) POINT TO THIS */
struct InternalFH {
	struct	InternalFH	*next, *prev;
	struct	FileHandle realfh;		/* the actual local_fh as filled by other dos-handlers */
									/* internal list of FileHandles */
	long	majic;
	short	machine;				/* machine this fh belongs to */
	short	pad;
	struct	Remember *mem;			/* nothing at the moment */
	void	*extra1;				/* nothing at the moment */
	void	*extra2;				/* ditto */
};
#define IFH_SIZE (sizeof(struct InternalFH))


/** service_lock on remote machine points to this on the server machine */
struct InternalLock {
	struct	InternalLock *next, *prev;
	struct	FileLock *reallock;
									/* internal list of FileLocks */
	long	majic;					/* the majic number for lock checking */
	short	machine;				/* machine this lock "belongs" to */
	short	pad;
	void	*temp;					/* temporary use for stuff */
};
#define IL_SIZE (sizeof(struct InternalLock))



/**
 **
 ** basic structure for open, close, read, write commands
 **
 **/

struct IFHDosMsg {
	struct DosMsg 	dosmsg;
	struct InternalFH *ifh;			/* points to our internal file handle */
	struct PktMsgRecv *pktmsg;		/* complete requesting pkt msg */
};
#define IFHMSG_RES1(a) ((a)->dosmsg.sp.sp_Pkt.dp_Res1)
#define IFHMSG_RES2(a) ((a)->dosmsg.sp.sp_Pkt.dp_Res2)





#define INIT_IFHDOSMSG(idm, replyport, function, ifh_o, pmsg_o) \
	\
	(INIT_DOS_MSG(&((idm)->dosmsg), replyport, function), \
	(idm)->ifh = (ifh_o), \
	(idm)->pktmsg = (pmsg_o))

/**
 **
 ** ONLY DOES THE ARGUMENTS! don't use for re-using messages since the replyport
 ** may be over written
 **
 **/

#define INIT_ARGS_IFHDOSMSG(ifhdm, action, arg1, arg2, arg3) \
	\
	((ifhdm)->dosmsg.sp.sp_Pkt.dp_Type = (action), \
	(ifhdm)->dosmsg.sp.sp_Pkt.dp_Arg1 = (long)(arg1), \
	(ifhdm)->dosmsg.sp.sp_Pkt.dp_Arg2 = (long)(arg2), \
	(ifhdm)->dosmsg.sp.sp_Pkt.dp_Arg3 = (long)(arg3))


/** when the "DMA" packet is returned, call this function & pass data */

/* things used in the nfs_action files */

/** allocate memory for a (dospkt + more usually) but return nomem if none! */
#define ACT_ALLOCMSG_THINGY(a,b) \
		\
		if(!((a) = AllocMem((b), MEMF_PUBLIC))) \
			return(&nfs_res_nomem);

/* set the user variables up for our function and do a put msg */
#define ACT_INIT_RETURN_PMR(pmr_o, func_o, data_o, return_mem, req_struct) \
	((pmr_o)->user.user1 = func_o,\
	(pmr_o)->user.user2 = (long)data_o,\
	INTERNAL_PREP_PKTMSG_DMA(&(pmr_o)->pm,\
				EMEM_RETURNMSG, SERV_RETURN,\
				return_mem, (req_struct)->sr.return_len))

/** init the IFH dos msg structure and send it off to the port in the file handle
 ** - use this in action's requiring an input to be the internal file handle, eg
 ** action_seek
 **/

#define ACT_PUT_IFHDOSMSG(custom_pktmsg, return_port,\
						routine_to_call, ifh_o, pktmsgrecv) \
		\
		(INIT_IFHDOSMSG(&(custom_pktmsg)->dm, return_port,\
						routine_to_call, ifh_o, pktmsgrecv), \
		PutMsg((ifh_o)->realfh.fh_Type, custom_pktmsg) )




/** Will use error checking and all that kind of stuff soon */
/** at the moment the checking is rudimentary */

#define GET_INTERNALFH(a, b) (((b)==((struct InternalFH *)(a))->majic)?\
										(struct InternalFH *)(a): NULL)
#define RES_INTERNALFH(a) ((long)(a))
#define GET_INTERNALLOCK(a, b) (((b)==((struct InternalLock *)(a))->majic)?\
										(struct InternalLock *)(a): NULL )
#define RES_INTERNALLOCK(a) ((long)(a))
#define GET_MAJIC (majic_code++)

