home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / ext / symlink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  2.0 KB  |  109 lines

  1. /*
  2.  *  linux/fs/ext/symlink.c
  3.  *
  4.  *  Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
  5.  *
  6.  *  from
  7.  *
  8.  *  linux/fs/minix/symlink.c
  9.  *
  10.  *  Copyright (C) 1991, 1992  Linus Torvalds
  11.  *
  12.  *  ext symlink handling code
  13.  */
  14.  
  15. #include <asm/segment.h>
  16.  
  17. #include <linux/errno.h>
  18. #include <linux/sched.h>
  19. #include <linux/fs.h>
  20. #include <linux/ext_fs.h>
  21. #include <linux/stat.h>
  22.  
  23. static int ext_readlink(struct inode *, char *, int);
  24. static int ext_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  25.  
  26. /*
  27.  * symlinks can't do much...
  28.  */
  29. struct inode_operations ext_symlink_inode_operations = {
  30.     NULL,            /* no file-operations */
  31.     NULL,            /* create */
  32.     NULL,            /* lookup */
  33.     NULL,            /* link */
  34.     NULL,            /* unlink */
  35.     NULL,            /* symlink */
  36.     NULL,            /* mkdir */
  37.     NULL,            /* rmdir */
  38.     NULL,            /* mknod */
  39.     NULL,            /* rename */
  40.     ext_readlink,        /* readlink */
  41.     ext_follow_link,    /* follow_link */
  42.     NULL,            /* bmap */
  43.     NULL,            /* truncate */
  44.     NULL            /* permission */
  45. };
  46.  
  47. static int ext_follow_link(struct inode * dir, struct inode * inode,
  48.     int flag, int mode, struct inode ** res_inode)
  49. {
  50.     int error;
  51.     struct buffer_head * bh;
  52.  
  53.     *res_inode = NULL;
  54.     if (!dir) {
  55.         dir = current->root;
  56.         dir->i_count++;
  57.     }
  58.     if (!inode) {
  59.         iput(dir);
  60.         return -ENOENT;
  61.     }
  62.     if (!S_ISLNK(inode->i_mode)) {
  63.         iput(dir);
  64.         *res_inode = inode;
  65.         return 0;
  66.     }
  67.     if (current->link_count > 5) {
  68.         iput(dir);
  69.         iput(inode);
  70.         return -ELOOP;
  71.     }
  72.     if (!(bh = ext_bread(inode, 0, 0))) {
  73.         iput(inode);
  74.         iput(dir);
  75.         return -EIO;
  76.     }
  77.     iput(inode);
  78.     current->link_count++;
  79.     error = open_namei(bh->b_data,flag,mode,res_inode,dir);
  80.     current->link_count--;
  81.     brelse(bh);
  82.     return error;
  83. }
  84.  
  85. static int ext_readlink(struct inode * inode, char * buffer, int buflen)
  86. {
  87.     struct buffer_head * bh;
  88.     int i;
  89.     char c;
  90.  
  91.     if (!S_ISLNK(inode->i_mode)) {
  92.         iput(inode);
  93.         return -EINVAL;
  94.     }
  95.     if (buflen > 1023)
  96.         buflen = 1023;
  97.     bh = ext_bread(inode, 0, 0);
  98.     iput(inode);
  99.     if (!bh)
  100.         return 0;
  101.     i = 0;
  102.     while (i<buflen && (c = bh->b_data[i])) {
  103.         i++;
  104.         put_fs_byte(c,buffer++);
  105.     }
  106.     brelse(bh);
  107.     return i;
  108. }
  109.