/*static char *SCCSID = "@(#)findip.c	6.2 92/01/31";*/
#include <os2.h>
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "volume.h"
#include "storage.h"
#include "tables.h"
#include "frame.h"
#include "assert.h"

#include "pr_DIR.h"
#include "pr_MISC.h"


/*
 *	FindIP - Find Insertion Point
 *
 *	FindIP scans a directory block looking for the proper
 *	insertion point for a DIRENT structure.
 *
 *	FindIP is a low level guy - it doesn't worry about down pointers,
 *	etc.  It just looks at this one directory block.  Also, it doesn't
 *	do string comparisons, it looks for a record whose downpointer
 *	matches a target value and sets the insert point to right
 *	before that record.
 *
 *	ENTRY	lsnDnPtr = target down pointer value (LSN)
 *		pdbToSearch = address of directory block
 *
 *	EXIT	Returns insertion point (pointer to a DIRENT just
 *				before where we want to insert) if
 *				insertion point found
 *
 *		Returns NULL if insertion point not found
 *
 *	HISTORY
 *	    27-Sep-1988 10:14:54 by Bill McJohn [t-billm]
 *				brought up to date with 9/23/88 assembly code
 */

PDIRENT
FindIP (lsnDnPtr, pdbToSearch)
LSN lsnDnPtr;			/* down pointer that we're looking for */
PDIRBLK pdbToSearch;		/* pointer to a directory block */

{
	PDIRENT pdeReturn;	/* pointer to a directory entry, moved later */

	ASSERT_DB(pdbToSearch);


	/*
	 * The last byte of the dir block that is to be searched is the	 *
	 * beginning of the first directory entry.  Therefore the memory *
	 * beginning at this space is cast as directory entry.		 *
	 */
	pdeReturn = (PDIRENT)(&(pdbToSearch -> bFirst));


	/*
	 * Search through directory entires until find LSN at end of	*
	 * directory entry matches the lsnDnPtr parameter.  If so, the	*
	 * dir. ent. being checked is returned.  The last directory	*
	 * entry in the list contains a flag which marks the end.  If	*
	 * this dir ent doesn't match, an unsuccessful search.  NULL is *
	 * returned.							*
	 */
	while ((pdeReturn -> fFlags & DF_END) == 0)  {

		/* If a match, return a pointer to this directory entry.  */
		if (BTP (pdeReturn) == lsnDnPtr)
			return pdeReturn;

		/*
		 * If a match not found, update the pointer to directory *
		 * entry to point to the next one.  The pointer is moved *
		 * ahead cchentry number of bytes.  Cchentry in each di- *
		 * rectory entry holds the length of that entry and is	 *
		 * the first element of the directory entry record.	 *
		 */
		pdeReturn = NEXT_ENTRY (pdeReturn);

	}

	if (BTP (pdeReturn) == lsnDnPtr) {

		/* Final dir ent matches */
		return pdeReturn;
	}

	/* No matching dir. ent. found, return NULL */
	return NULL;

}
