#include "ktypes.h"
#include "filesys.h"
#include "dir.h"


static char     what[] = "@(#)dir.c	1.2";


/*
 * routines for KSOS directory interpretation.
 */

readd(dirp, bno, blk)
	struct filep    *dirp;          /* dir file pointer */
	long            bno;            /* block no in dir */
	struct dblk     *blk;           /* VAR contents of dir block */
{
  char my_buffer[BLKSZ];
  char *BUFFER = &my_buffer[0];

#ifdef DEBUG
printf("readd: bno %d\n",bno);
dumpfilep("readd (dirp)",dirp);
#endif

	if (get_file_block(dirp, bno, BUFFER) < 0)
		return -1;

	move(BUFFER, blk, sizeof *blk);
#ifdef DEBUG
dumpdblk("readd (blk)", blk);
#endif
	return 0;
}


lookup(parent, name, child)
	struct filep            *parent, *child;
	char                    *name;
{
	register struct dent    *de;
	long                    bno;
	struct dblk             dblk;
	struct jnode            pjn;

#ifdef DEBUG
printf("lookup: name %s\n",name);
dumpfilep("lookup (parent)",parent);
#endif
	if (readj(&parent->f_ext, parent->f_jnumb, &pjn) < 0)
		return -1;
#ifdef DEBUG
dumpjnode("lookup (pjn)",&pjn);
#endif

	if (pjn.j_kind != JNODE)
		return -1;

	parent->f_blocks = *(cardinal32*)pjn.j_high;

	for (bno = 0; bno < *(cardinal32*)pjn.j_high; bno++)
		if (readd(parent, bno, &dblk) >= 0)
		{
			for (de = dblk.d_blk; de < dblk.d_blk + DENT; de++)
				if (de->d_seid.nsp == SAME_NSP
				&& dcmp(name, de->d_name))
				{
					move(&parent->f_ext, &child->f_ext, sizeof child->f_ext);
					child->f_jnumb = de->d_seid.uniq_id1;
					return 0;
				}
		}

	return -1;
}


dcmp(n1, n2)
	char                    *n1, *n2;
{
	register char           c1, c2;
	register int            i;

	i = DNAM;

	for (;;)
	{
		c1 = *n1++;
		if (c1 == '/')
			c1 = 0;

		if (i-- > 0)
			c2 = *n2++;
		else
			c2 = 0;

		if (c1 != c2)
			return 0;

		if (c1 == 0)
			return 1;
	}
}


/*
 * The following routines are exported.
 */


fileopen(ex, name, fp)
	struct extp             *ex;
	char                    *name;
	struct filep            *fp;
{
	struct filep            pp;
	struct jnode            fjn;

	/* pp starts at root directory */
#ifdef DEBUG
printf("fileopen: name %s: sizeof pp.f_ext %d\n",name,(sizeof pp.f_ext));
dumpextp("fileopen (ex)",ex);
#endif
	move(ex, &pp.f_ext, sizeof pp.f_ext);

	pp.f_jnumb = ROOTLOC;

	while (*name == '/')
		name++;

	while (*name)
	{
#ifdef DEBUG
dumpfilep("fileopen (pp in loop)",&pp);
#endif
		if (lookup(&pp, name, fp) < 0)
			return -1;

		move(fp, &pp, sizeof pp);

		while (*name != 0 && *name != '/')
			name++;

		while (*name == '/')
			name++;
	}

	if (readj(ex, fp->f_jnumb, &fjn) < 0
	|| fjn.j_kind != JNODE)
		return -1;

	fp->f_blocks = *(cardinal32*)fjn.j_high;

	return 0;
}
