home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / ken / nami.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  3.4 KB  |  201 lines

  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. }
  201.