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
schar defined in line 182; never used
uchar defined in line 192; used 2 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1119
Valid CSS Valid XHTML 1.0 Strict