1: #
2: #include "../param.h"
3: #include "../inode.h"
4: #include "../user.h"
5: #include "../systm.h"
6: #include "../buf.h"
7:
8: /*
9: * Convert a pathname into a pointer to
10: * an inode. Note that the inode is locked.
11: *
12: * func = function called to get next char of name
13: * &uchar if name is in user space
14: * &schar if name is in system space
15: * flag = 0 if name is sought
16: * 1 if name is to be created
17: * 2 if name is to be deleted
18: */
19: namei(func, flag)
20: int (*func)();
21: {
22: register struct inode *dp;
23: register c;
24: register char *cp;
25: int eo, *bp;
26:
27: /*
28: * If name starts with '/' start from
29: * root; otherwise start from current dir.
30: */
31:
32: dp = u.u_cdir;
33: if((c=(*func)()) == '/')
34: dp = rootdir;
35: iget(dp->i_dev, dp->i_number);
36: while(c == '/')
37: c = (*func)();
38: if(c == '\0' && flag != 0) {
39: u.u_error = ENOENT;
40: goto out;
41: }
42:
43: cloop:
44: /*
45: * Here dp contains pointer
46: * to last component matched.
47: */
48:
49: if(u.u_error)
50: goto out;
51: if(c == '\0')
52: return(dp);
53:
54: /*
55: * If there is another component,
56: * dp must be a directory and
57: * must have x permission.
58: */
59:
60: if((dp->i_mode&IFMT) != IFDIR) {
61: u.u_error = ENOTDIR;
62: goto out;
63: }
64: if(access(dp, IEXEC))
65: goto out;
66:
67: /*
68: * Gather up name into
69: * users' dir buffer.
70: */
71:
72: cp = &u.u_dbuf[0];
73: while(c!='/' && c!='\0' && u.u_error==0) {
74: if(cp < &u.u_dbuf[DIRSIZ])
75: *cp++ = c;
76: c = (*func)();
77: }
78: while(cp < &u.u_dbuf[DIRSIZ])
79: *cp++ = '\0';
80: while(c == '/')
81: c = (*func)();
82: if(u.u_error)
83: goto out;
84:
85: /*
86: * Set up to search a directory.
87: */
88:
89: u.u_offset[1] = 0;
90: u.u_offset[0] = 0;
91: u.u_segflg = 1;
92: eo = 0;
93: u.u_count = ldiv(dp->i_size1, DIRSIZ+2);
94: bp = NULL;
95:
96: eloop:
97:
98: /*
99: * If at the end of the directory,
100: * the search failed. Report what
101: * is appropriate as per flag.
102: */
103:
104: if(u.u_count == 0) {
105: if(bp != NULL)
106: brelse(bp);
107: if(flag==1 && c=='\0') {
108: if(access(dp, IWRITE))
109: goto out;
110: u.u_pdir = dp;
111: if(eo)
112: u.u_offset[1] = eo-DIRSIZ-2; else
113: dp->i_flag =| IUPD;
114: return(NULL);
115: }
116: u.u_error = ENOENT;
117: goto out;
118: }
119:
120: /*
121: * If offset is on a block boundary,
122: * read the next directory block.
123: * Release previous if it exists.
124: */
125:
126: if((u.u_offset[1]&0777) == 0) {
127: if(bp != NULL)
128: brelse(bp);
129: bp = bread(dp->i_dev,
130: bmap(dp, ldiv(u.u_offset[1], 512)));
131: }
132:
133: /*
134: * Note first empty directory slot
135: * in eo for possible creat.
136: * String compare the directory entry
137: * and the current component.
138: * If they do not match, go back to eloop.
139: */
140:
141: bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, (DIRSIZ+2)/2);
142: u.u_offset[1] =+ DIRSIZ+2;
143: u.u_count--;
144: if(u.u_dent.u_ino == 0) {
145: if(eo == 0)
146: eo = u.u_offset[1];
147: goto eloop;
148: }
149: for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++)
150: if(*cp != cp[u.u_dent.u_name - u.u_dbuf])
151: goto eloop;
152:
153: /*
154: * Here a component matched in a directory.
155: * If there is more pathname, go back to
156: * cloop, otherwise return.
157: */
158:
159: if(bp != NULL)
160: brelse(bp);
161: if(flag==2 && c=='\0') {
162: if(access(dp, IWRITE))
163: goto out;
164: return(dp);
165: }
166: bp = dp->i_dev;
167: iput(dp);
168: dp = iget(bp, u.u_dent.u_ino);
169: if(dp == NULL)
170: return(NULL);
171: goto cloop;
172:
173: out:
174: iput(dp);
175: return(NULL);
176: }
177:
178: /*
179: * Return the next character from the
180: * kernel string pointed at by dirp.
181: */
182: schar()
183: {
184:
185: return(*u.u_dirp++ & 0377);
186: }
187:
188: /*
189: * Return the next character from the
190: * user string pointed at by dirp.
191: */
192: uchar()
193: {
194: register c;
195:
196: c = fubyte(u.u_dirp++);
197: if(c == -1)
198: u.u_error = EFAULT;
199: return(c);
200: }
Defined functions
namei
defined in line
19; used 13 times