home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / umsdos / symlink.c < prev   
Encoding:
C/C++ Source or Header  |  1995-01-23  |  3.2 KB  |  149 lines

  1. /*
  2.  *  linux/fs/umsdos/file.c
  3.  *
  4.  *  Written 1992 by Jacques Gelinas
  5.  *    inspired from linux/fs/msdos/file.c Werner Almesberger
  6.  *
  7.  *  Extended MS-DOS regular file handling primitives
  8.  */
  9. #ifdef MODULE
  10. #include <linux/module.h>
  11. #endif
  12.  
  13. #include <asm/segment.h>
  14. #include <asm/system.h>
  15.  
  16. #include <linux/sched.h>
  17. #include <linux/fs.h>
  18. #include <linux/msdos_fs.h>
  19. #include <linux/errno.h>
  20. #include <linux/fcntl.h>
  21. #include <linux/stat.h>
  22. #include <linux/umsdos_fs.h>
  23. #include <linux/malloc.h>
  24.  
  25. #define PRINTK(x)
  26. #define Printk(x)    printk x
  27. /*
  28.     Read the data associate with the symlink.
  29.     Return length read in buffer or  a negative error code.
  30. */
  31. static int umsdos_readlink_x (
  32.     struct inode *inode,
  33.     char *buffer,
  34.     int (*msdos_read)(struct inode *, struct file *, char *, int),
  35.     int bufsiz)
  36. {
  37.     int ret = inode->i_size;
  38.     struct file filp;
  39.     filp.f_pos = 0;
  40.     filp.f_reada = 0;
  41.     if (ret > bufsiz) ret = bufsiz;
  42.     if ((*msdos_read) (inode, &filp, buffer,ret) != ret){
  43.         ret = -EIO;
  44.     }
  45.     return ret;
  46. }
  47. /*
  48.     Follow a symbolic link chain by calling open_namei recursively
  49.     until an inode is found.
  50.  
  51.     Return 0 if ok, or a negative error code if not.
  52. */
  53. static int UMSDOS_follow_link(
  54.     struct inode * dir,
  55.     struct inode * inode,
  56.     int flag,
  57.     int mode,
  58.     struct inode ** res_inode)
  59. {
  60.     int ret = -ELOOP;
  61.     *res_inode = NULL;
  62.     if (current->link_count < 5) {
  63.         char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);
  64.         if (path == NULL){
  65.             ret = -ENOMEM;
  66.         }else{
  67.             if (!dir) {
  68.                 dir = current->fs[1].root;
  69.                 dir->i_count++;
  70.             }
  71.             if (!inode){
  72.                 PRINTK (("symlink: inode = NULL\n"));
  73.                 ret = -ENOENT;
  74.             }else if (!S_ISLNK(inode->i_mode)){
  75.                 PRINTK (("symlink: Not ISLNK\n"));
  76.                 *res_inode = inode;
  77.                 inode = NULL;
  78.                 ret = 0;
  79.             }else{
  80.                 ret = umsdos_readlink_x (inode,path
  81.                     ,umsdos_file_read_kmem,PATH_MAX-1);
  82.                 if (ret > 0){
  83.                     path[ret] = '\0';
  84.                     PRINTK (("follow :%s: %d ",path,ret));
  85.                     iput(inode);
  86.                     inode = NULL;
  87.                     current->link_count++;
  88.                     ret = open_namei(path,flag,mode,res_inode,dir);
  89.                     current->link_count--;
  90.                     dir = NULL;
  91.                 }else{
  92.                     ret = -EIO;
  93.                 }
  94.             }
  95.             kfree (path);
  96.         }
  97.     }    
  98.     iput(inode);
  99.     iput(dir);
  100.     PRINTK (("follow_link ret %d\n",ret));
  101.     return ret;
  102. }
  103.  
  104. static int UMSDOS_readlink(struct inode * inode, char * buffer, int buflen)
  105. {
  106.     int ret = -EINVAL;
  107.     if (S_ISLNK(inode->i_mode)) {
  108.         ret = umsdos_readlink_x (inode,buffer,msdos_file_read,buflen);
  109.     }
  110.     PRINTK (("readlink %d %x bufsiz %d\n",ret,inode->i_mode,buflen));
  111.     iput(inode);
  112.     return ret;
  113.     
  114. }
  115.  
  116. static struct file_operations umsdos_symlink_operations = {
  117.     NULL,                /* lseek - default */
  118.     NULL,                /* read */
  119.     NULL,                /* write */
  120.     NULL,                /* readdir - bad */
  121.     NULL,                /* select - default */
  122.     NULL,                /* ioctl - default */
  123.     NULL,                /* mmap */
  124.     NULL,                /* no special open is needed */
  125.     NULL,                /* release */
  126.     NULL                /* fsync */
  127. };
  128.  
  129. struct inode_operations umsdos_symlink_inode_operations = {
  130.     &umsdos_symlink_operations,    /* default file operations */
  131.     NULL,            /* create */
  132.     NULL,            /* lookup */
  133.     NULL,            /* link */
  134.     NULL,            /* unlink */
  135.     NULL,            /* symlink */
  136.     NULL,            /* mkdir */
  137.     NULL,            /* rmdir */
  138.     NULL,            /* mknod */
  139.     NULL,            /* rename */
  140.     UMSDOS_readlink,    /* readlink */
  141.     UMSDOS_follow_link,    /* follow_link */
  142.     NULL,            /* bmap */
  143.     NULL,            /* truncate */
  144.     NULL            /* permission */
  145. };
  146.  
  147.  
  148.  
  149.