V4/nsys/ken/nami.c

Compare this file to the similar file:
Show the results in this format:

#include "/sys/nsys/param.h"
#include "/sys/nsys/inode.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/systm.h"
#include "/sys/nsys/buf.h"

namei(func, flag)
int (*func)();
int flag;

/*
 * func = function called to get name
 *	&uchar if name is in user space
 *	&schar if name is in system space
 * flag = 0 if name is saught
 *	1 if name is to be created
 *	2 if name is to be deleted
 * return is incremented locked inode.
 *	NULL if name not found
 */

{
	struct inode *dp;
	int *bp;
	int i, j, c, eo;

	/*
	 * start from indicated
	 * directory
	 */

	if((c=(*func)()) == '/')
		dp = rootdir; else
		dp = u.u_cdir;
	iget(dp->i_dev, dp->i_number);
	while(c == '/')
		c = (*func)();

cloop:
	/*
	 * here dp contains pointer
	 * to last component matched.
	 */

	if(u.u_error)
		goto out;
	if(c == '\0')
		return(dp);

	/*
	 * if there is another component,
	 * must be a directory and
	 * must have x permission
	 */

	if((dp->i_mode&IFMT) != IFDIR) {
		u.u_error = ENOTDIR;
		goto out;
	}

	if(access(dp, IEXEC))
		goto out;

	/*
	 * gather up name into
	 * users' dir buffer
	 */

	for(i=0; c!='/' && c!='\0' && u.u_error==0; i++) {
		if(i < DIRSIZ)
			u.u_dbuf[i] = c;
		c = (*func)();
	}
	while(i < DIRSIZ)
		u.u_dbuf[i++] = '\0';
	while(c == '/')
		c = (*func)();
	if(u.u_error)
		goto out;

	/*
	 * search the directory
	 */

	u.u_offset[1] = 0;
	u.u_offset[0] = 0;
	u.u_segflg = 1;
	eo = 0;
	u.u_count = ldiv(0, dp->i_size1, 16);
	u.u_offset[1] = 0;
	bp = NULL;

eloop:
	i = lrem(0, u.u_offset[1], 512);
	if(u.u_count == 0) {
		if(bp != NULL)
			brelse(bp);
		if(flag==1 && c=='\0') {
			if(access(dp, IWRITE))
				goto out;
			u.u_pdir = dp;
			if(eo)
				u.u_offset[1] = eo-DIRSIZ-2; else
				dp->i_flag =| IUPD;
			return(NULL);
		}
		u.u_error = ENOENT;
		goto out;
	}
	if(i == 0) {
		if(bp != NULL)
			brelse(bp);
		bp = bread(dp->i_dev,
			bmap(dp, ldiv(0, u.u_offset[1], 512)));
	}
	for(j = -2; j<DIRSIZ; j++)
		u.u_dent.u_name[j] =
			bp->b_addr[i++];
	u.u_offset[1] =+ DIRSIZ+2;
	u.u_count--;
	if(u.u_dent.u_ino == 0) {
		if(eo == 0)
			eo = u.u_offset[1];
		goto eloop;
	}
	for(i=0; i<DIRSIZ; i++)
		if(u.u_dbuf[i] != u.u_dent.u_name[i])
			goto eloop;
	if(bp != NULL)
		brelse(bp);
	if(flag==2 && c=='\0') {
		if(access(dp, IWRITE))
			goto out;
		return(dp);
	}
	i = dp->i_dev;
	iput(dp);
	dp = iget(i, u.u_dent.u_ino);
	if(dp == NULL)
		return(NULL);
	goto cloop;

out:
	iput(dp);
	return(NULL);
}

schar()
{

	return(*u.u_dirp++ & 0377);
}

uchar()
{
	int c;

	c = fubyte(u.u_dirp++);
	if(c == -1)
		u.u_error = EFAULT;
	return(c);
}