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

schar defined in line 206; used 2 times
uchar defined in line 216; used 2 times
Last modified: 1979-05-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1058
Valid CSS Valid XHTML 1.0 Strict