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