/********************************************************************
 ** NETWORK FILESYSTEM - DOS HANDLER
 **
 ** (c) Spak, Darrell Tam, c9107253@ee.newcastle.edu.au (1994)
 ** phone (Australia) 049-829-710
 **                   +49-829-710
 ** (c) SST 1994
 **
 ** EXAMINE OBJECT
 **
 ** TABS to 4
 ********************************************************************/

#include "/snd/everything.h"
#include "deadheads.h"
#include "root_protos.h"
#include "globs_protos.h"
#include "xtra_protos.h"
#include "lowest_protos.h"

#define EXAMINE_PKTMSG_SIZE sizeof(struct ExaminePktMsg)
/** this is just a variation of the "doofus" format */
struct ExaminePktMsg {
	struct	DoofusPktMsg	dpm;

	struct	NFSExamine			examinereq;	/* request structure */
	struct	NFSStdReturn		examineret;	/* return structure */
	struct	LockKey				*lk;
};


/********************************************************************/
static long handle_examine_net(struct ExaminePktMsg *expm)
/********************************************************************/
{
struct DosPacket *dosmsg = expm->dpm.dp_original;
	dosmsg->dp_Res1 = expm->examineret.remote_res1;
	dosmsg->dp_Res2 = expm->examineret.remote_res2;
	if(expm->dpm.net.pm.smsg.result != PAR_OK)
		{ dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_DISK; }
	return(AR_FLAG_RETURNDOSMSG | AR_FLAG_FREEDOOF);
}


/********************************************************************/
	long action_examine_object(struct DosPacket *dosmsg,
									struct MsgPort *dm_retport)
/********************************************************************

 ********************************************************************/
{
struct FileLock *fl = BTOC(dosmsg->dp_Arg1);
struct FileInfoBlock *fib = BTOC(dosmsg->dp_Arg2);

	if(fl) {
	struct LockKey *lk = (struct LockKey *)fl->fl_Key;
		switch(lk->Type) {

		/** EXAMINE ROOT LOCK */

			case LK_ROOT: {
			char *vol_name = BTOC(DevList->dl_Name);
				fib->fib_DiskKey = 0;
				fib->fib_DirEntryType = 2;
				CopyMem(vol_name, fib->fib_FileName, vol_name[0]+1);
				fib->fib_Protection = 0;
				fib->fib_EntryType = 2;
				fib->fib_Size = 0;
				fib->fib_NumBlocks = 1;
				CopyMem(&DevList->dl_VolumeDate, &fib->fib_Date, sizeof(struct DateStamp));
				fib->fib_Comment[0] = 0;
			}
			break;


		/** EXAMINE A REMOTE LOCK */

			case LK_REMOTE: {
			struct ExaminePktMsg *expm;

				if(!(expm = AllocMem(EXAMINE_PKTMSG_SIZE, MEMF_PUBLIC))) {
					dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_FREE_STORE;
					return(AR_FLAG_RETURNDOSMSG);
				}
				expm->examinereq.request		= REQUEST_EXAMINE;
				expm->examinereq.remote_majic	= lk->remote.majic;
				expm->examinereq.remote_il		= lk->remote.remote_il;
				expm->lk = lk;
				INIT_DOOFPKTMSG(&expm->dpm,
					handle_examine_net,						/* our routine to call */
					netrepport,								/* net reply port */
					dosmsg, dm_retport,						/* dos msg & reply port */
					EXAMINE_PKTMSG_SIZE,					/* saved stuff */
					lk->remote.machine, lk->remote.service,	/* FileArg1 */
					&expm->examinereq, sizeof(struct NFSExamine),/* net-service-request */
					NULL, 0,								/* send-body */
					fib, sizeof(*fib),						/* result-body */
					&expm->examineret, sizeof(struct NFSStdReturn));
															/* return stuff */
				PutMsg(NET_SERV_PORT(lk), expm);
				return(0);
			}

		/** EXAMINE A LOCK ON A "MACHINE" DIRECTORY */
			case LK_MACHINE:
				fib->fib_DiskKey = 0;
				fib->fib_DirEntryType = 2;
				fib->fib_FileName[0] = 2;
				fib->fib_FileName[1] = '0';
				fib->fib_FileName[2] = lk->machine.machine;
				fib->fib_Protection = 0;
				fib->fib_EntryType = 2;
				fib->fib_Size = 0;
				fib->fib_NumBlocks = 1;
				CopyMem(&DevList->dl_VolumeDate, &fib->fib_Date, sizeof(struct DateStamp));
				fib->fib_Comment[0] = 0;
			break;

			default:
				dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
			break;
		}
	}

/** NO FILE LOCK ?? */
	else
		{ dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_OBJECT_NOT_FOUND; }

	return(AR_FLAG_RETURNDOSMSG);
}





/********************************************************************/
long action_examine_next(struct DosPacket *dosmsg,
									struct MsgPort *dm_retport)
/********************************************************************/
{ /* Lock, FileInfoBlock : Boolean */
struct FileLock *fl = BTOC(dosmsg->dp_Arg1);
struct FileInfoBlock *fib = BTOC(dosmsg->dp_Arg2);

	if(fl) {
	struct LockKey *lk = (struct LockKey *)fl->fl_Key;
		switch(lk->Type) {

		/** EXAMINE ROOT LOCK */

			case LK_ROOT: {
			char *vol_name = BTOC(DevList->dl_Name);
				if(fib->fib_FileName[0] == vol_name[0]) {
					fib->fib_DiskKey = 0;
					fib->fib_DirEntryType = 2;
					fib->fib_FileName[0] = 2;
					fib->fib_FileName[1] = '0';
					fib->fib_FileName[2] = 'B';
					fib->fib_Protection = 0;
					fib->fib_EntryType = 2;
					fib->fib_Size = 0;
					fib->fib_NumBlocks = 1;
					CopyMem("\016Remote machine", fib->fib_Comment, 15);
				}
				else
				{ dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_MORE_ENTRIES; }

			}
			break;


		/** EXAMINE A REMOTE LOCK */
			case LK_REMOTE: {
			struct ExaminePktMsg *expm;
				if(!(expm = AllocMem(EXAMINE_PKTMSG_SIZE, MEMF_PUBLIC))) {
					dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_FREE_STORE;
					return(AR_FLAG_RETURNDOSMSG);
				}
				expm->examinereq.request		= REQUEST_EXAMINENEXT;
				expm->examinereq.remote_majic	= lk->remote.majic;
				expm->examinereq.remote_il		= lk->remote.remote_il;
				expm->lk = lk;
				INIT_DOOFPKTMSG(&expm->dpm,
					handle_examine_net,						/* our routine to call */
					netrepport,								/* net reply port */
					dosmsg, dm_retport,						/* dos msg & reply port */
					EXAMINE_PKTMSG_SIZE,					/* saved stuff */
					lk->remote.machine, lk->remote.service,	/* FileArg1 */
					&expm->examinereq, sizeof(struct NFSExamine),/* net-service-request */
					fib, sizeof(*fib),						/* send-body */
					fib, sizeof(*fib),						/* result-body */
					&expm->examineret, sizeof(struct NFSStdReturn));
															/* return stuff */
				PutMsg(NET_SERV_PORT(lk), expm);
				return(0);
			}

		/** EXAMINE A LOCK ON A "MACHINE" DIRECTORY */
			case LK_MACHINE:
				dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_MORE_ENTRIES;
			break;

			default:
				dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
			break;
		}
	}

/** NO FILE LOCK ?? */
	else
		{ dosmsg->dp_Res1 = 0; dosmsg->dp_Res2 = ERROR_NO_MORE_ENTRIES; }

	return(AR_FLAG_RETURNDOSMSG);
}

