/* vfs_lookup.c 4.7 81/05/18 */
* 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
register struct inode
*dp
;
register struct direct
*ep
;
* If name starts with '/' start from
* root; otherwise start from current dir.
if ((dp
= u
.u_rdir
) == NULL
)
(void) iget(dp
->i_dev
, dp
->i_number
);
if(c
== '\0' && flag
!= 0)
* Here dp contains pointer
* to last component matched.
* If the current node is a character
* special file with the SUID bit set, return anyway.
* This lets the Chaos open decode the rest of the name in its own
if((dp
->i_mode
&(IFMT
|ISUID
)) == (IFCHR
|ISUID
)) {
u
.u_dirp
--; /* back up to the slash or null */
* If there is another component,
while (c
!= '/' && c
!= '\0' && u
.u_error
== 0 ) {
if (mpxip
!=NULL
&& c
=='!')
if (flag
==1 && c
== ('/'|0200)) {
if (cp
< &u
.u_dbuf
[DIRSIZ
])
while(cp
< &u
.u_dbuf
[DIRSIZ
])
if (c
== '!' && mpxip
!= NULL
) {
* dp must be a directory and
* must have X permission.
if((dp
->i_mode
&IFMT
) != IFDIR
)
(void) access(dp
, IEXEC
);
* set up to search a directory
if (dp
== u
.u_rdir
&& u
.u_dbuf
[0] == '.' &&
u
.u_dbuf
[1] == '.' && u
.u_dbuf
[2] == 0)
* If at the end of the directory,
* the search failed. Report what
* is appropriate as per flag.
if(u
.u_offset
>= dp
->i_size
) {
if(flag
==1 && c
=='\0' && dp
->i_nlink
) {
u
.u_offset
= eo
-sizeof(struct direct
);
* If offset is on a block boundary,
* read the next directory block.
* Release previous if it exists.
if((u
.u_offset
&BMASK
) == 0) {
bmap(dp
, (daddr_t
)(u
.u_offset
>>BSHIFT
), B_READ
));
if (bp
->b_flags
& B_ERROR
) {
ep
= (struct direct
*)bp
->b_un
.b_addr
;
* 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.
u
.u_offset
+= sizeof(struct direct
);
for(i
=0; i
<DIRSIZ
; i
++) {
if(u
.u_dbuf
[i
] != ep
->d_name
[i
])
* Here a component matched in a directory.
* If there is more pathname, go back to
* cloop, otherwise return.
bcopy((caddr_t
)ep
, (caddr_t
)&u
.u_dent
, sizeof(struct direct
));
if(u
.u_dent
.d_ino
== ROOTINO
)
if(dp
->i_number
== ROOTINO
)
if(u
.u_dent
.d_name
[1] == '.')
if(mount
[i
].m_bufp
!= NULL
)
if(mount
[i
].m_dev
== d
) {
dp
= iget(d
, u
.u_dent
.d_ino
);
* Return the next character from the
* kernel string pointed at by dirp.
return(*u
.u_dirp
++ & 0377);
* Return the next character from the
* user string pointed at by dirp.