V9/sys/sys/nami.c

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

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/inode.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/buf.h"
#include "../h/conf.h"

/*
 * Convert a pathname into a pointer to
 * a locked inode.
 *
 * func = function called to get next char of name
 *	&uchar if name is in user space
 *	&schar if name is in system space
 *	length guaranteed <= BUFSIZE if func != uchar
 * flagp
	0 for ordinary searches
	else ->flag structure with more parameters
 * follow = 1 if links are to be followed at the end of the name
 */

struct inode *
namei(func, flagp, follow)
int		(*func)();
struct argnamei	*flagp;
int		follow;
{
	register int	i;
	register char	*cp;
	struct nx	p;

	p.nbp = geteblk();
	if(func == uchar) {
		if((i = fustrlen(u.u_dirp)) < 0) {
			u.u_error = EFAULT;
			brelse(p.nbp);
			return NULL;
		}
		if(i > BUFSIZE) {
			u.u_error = ENOENT;
			brelse(p.nbp);
			return NULL;
		}
		bcopy(u.u_dirp, p.nbp->b_un.b_addr, i);
#ifdef	CHAOS
		u.u_dirp += i;
#endif
	} else {
		cp = p.nbp->b_un.b_addr;
		do; while(*cp++ = (*func)());
	}
	if(flagp != NULL) {
		cp = p.nbp->b_un.b_addr;
		while(i = *cp++) {
			if(i & 0200) {
				u.u_error = ENOENT;
				brelse(p.nbp);
				return NULL;
			}
		}
	}
	cp = p.nbp->b_un.b_addr;
	if(*cp == '/') {
		while(*cp == '/')
			cp++;
		if((p.dp = u.u_rdir) == NULL)
			p.dp = rootdir;
	} else
		p.dp = u.u_cdir;
	p.nlink = 0;
	p.cp = cp;
	plock(p.dp);
	p.dp->i_count++;

	for (;;) {
		switch((*fstypsw[p.dp->i_fstyp].t_nami)(&p, &flagp, follow)) {
		case 1:
			iput(p.dp);
			brelse(p.nbp);
			return NULL;
		case 2:
			if(*p.cp)
				break;
		case 0:
			brelse(p.nbp);
			return p.dp;
		default:
			panic("namei ret");
		}
	}
}

/*
 * for filesystems without namei code
 */

int
nullnami()
{
	u.u_error = ENODEV;
	return (1);
}

/*
 * Return the next character from the
 * kernel string pointed at by dirp.
 */
schar()
{

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

/*
 * Return the next character from the
 * user string pointed at by dirp.
 */
uchar()
{
	register c;

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