Add original unix v6
This commit is contained in:
+200
@@ -0,0 +1,200 @@
|
||||
#
|
||||
#include "../param.h"
|
||||
#include "../inode.h"
|
||||
#include "../user.h"
|
||||
#include "../systm.h"
|
||||
#include "../buf.h"
|
||||
|
||||
/*
|
||||
* Convert a pathname into a pointer to
|
||||
* an inode. Note that the inode is locked.
|
||||
*
|
||||
* func = function called to get next char of name
|
||||
* &uchar if name is in user space
|
||||
* &schar if name is in system space
|
||||
* flag = 0 if name is sought
|
||||
* 1 if name is to be created
|
||||
* 2 if name is to be deleted
|
||||
*/
|
||||
namei(func, flag)
|
||||
int (*func)();
|
||||
{
|
||||
register struct inode *dp;
|
||||
register c;
|
||||
register char *cp;
|
||||
int eo, *bp;
|
||||
|
||||
/*
|
||||
* If name starts with '/' start from
|
||||
* root; otherwise start from current dir.
|
||||
*/
|
||||
|
||||
dp = u.u_cdir;
|
||||
if((c=(*func)()) == '/')
|
||||
dp = rootdir;
|
||||
iget(dp->i_dev, dp->i_number);
|
||||
while(c == '/')
|
||||
c = (*func)();
|
||||
if(c == '\0' && flag != 0) {
|
||||
u.u_error = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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,
|
||||
* dp 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.
|
||||
*/
|
||||
|
||||
cp = &u.u_dbuf[0];
|
||||
while(c!='/' && c!='\0' && u.u_error==0) {
|
||||
if(cp < &u.u_dbuf[DIRSIZ])
|
||||
*cp++ = c;
|
||||
c = (*func)();
|
||||
}
|
||||
while(cp < &u.u_dbuf[DIRSIZ])
|
||||
*cp++ = '\0';
|
||||
while(c == '/')
|
||||
c = (*func)();
|
||||
if(u.u_error)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Set up to search a directory.
|
||||
*/
|
||||
|
||||
u.u_offset[1] = 0;
|
||||
u.u_offset[0] = 0;
|
||||
u.u_segflg = 1;
|
||||
eo = 0;
|
||||
u.u_count = ldiv(dp->i_size1, DIRSIZ+2);
|
||||
bp = NULL;
|
||||
|
||||
eloop:
|
||||
|
||||
/*
|
||||
* If at the end of the directory,
|
||||
* the search failed. Report what
|
||||
* is appropriate as per flag.
|
||||
*/
|
||||
|
||||
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 offset is on a block boundary,
|
||||
* read the next directory block.
|
||||
* Release previous if it exists.
|
||||
*/
|
||||
|
||||
if((u.u_offset[1]&0777) == 0) {
|
||||
if(bp != NULL)
|
||||
brelse(bp);
|
||||
bp = bread(dp->i_dev,
|
||||
bmap(dp, ldiv(u.u_offset[1], 512)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Note first empty directory slot
|
||||
* in eo for possible creat.
|
||||
* String compare the directory entry
|
||||
* and the current component.
|
||||
* If they do not match, go back to eloop.
|
||||
*/
|
||||
|
||||
bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, (DIRSIZ+2)/2);
|
||||
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(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++)
|
||||
if(*cp != cp[u.u_dent.u_name - u.u_dbuf])
|
||||
goto eloop;
|
||||
|
||||
/*
|
||||
* Here a component matched in a directory.
|
||||
* If there is more pathname, go back to
|
||||
* cloop, otherwise return.
|
||||
*/
|
||||
|
||||
if(bp != NULL)
|
||||
brelse(bp);
|
||||
if(flag==2 && c=='\0') {
|
||||
if(access(dp, IWRITE))
|
||||
goto out;
|
||||
return(dp);
|
||||
}
|
||||
bp = dp->i_dev;
|
||||
iput(dp);
|
||||
dp = iget(bp, u.u_dent.u_ino);
|
||||
if(dp == NULL)
|
||||
return(NULL);
|
||||
goto cloop;
|
||||
|
||||
out:
|
||||
iput(dp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
return(c);
|
||||
}
|
||||
Reference in New Issue
Block a user