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 / isofs / symlink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  2.1 KB  |  111 lines

  1. /*
  2.  *  linux/fs/isofs/symlink.c
  3.  *
  4.  *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
  5.  *
  6.  *  Copyright (C) 1991, 1992  Linus Torvalds
  7.  *
  8.  *  isofs symlink handling code.  This is only used with the Rock Ridge
  9.  *  extensions to iso9660
  10.  */
  11.  
  12. #ifdef MODULE
  13. #include <linux/module.h>
  14. #endif
  15.  
  16. #include <asm/segment.h>
  17.  
  18. #include <linux/errno.h>
  19. #include <linux/sched.h>
  20. #include <linux/fs.h>
  21. #include <linux/iso_fs.h>
  22. #include <linux/stat.h>
  23. #include <linux/malloc.h>
  24.  
  25. static int isofs_readlink(struct inode *, char *, int);
  26. static int isofs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  27.  
  28. /*
  29.  * symlinks can't do much...
  30.  */
  31. struct inode_operations isofs_symlink_inode_operations = {
  32.     NULL,            /* no file-operations */
  33.     NULL,            /* create */
  34.     NULL,            /* lookup */
  35.     NULL,            /* link */
  36.     NULL,            /* unlink */
  37.     NULL,            /* symlink */
  38.     NULL,            /* mkdir */
  39.     NULL,            /* rmdir */
  40.     NULL,            /* mknod */
  41.     NULL,            /* rename */
  42.     isofs_readlink,        /* readlink */
  43.     isofs_follow_link,    /* follow_link */
  44.     NULL,            /* bmap */
  45.     NULL,            /* truncate */
  46.     NULL            /* permission */
  47. };
  48.  
  49. static int isofs_follow_link(struct inode * dir, struct inode * inode,
  50.     int flag, int mode, struct inode ** res_inode)
  51. {
  52.     int error;
  53.     char * pnt;
  54.  
  55.     if (!dir) {
  56.         dir = current->fs->root;
  57.         dir->i_count++;
  58.     }
  59.     if (!inode) {
  60.         iput(dir);
  61.         *res_inode = NULL;
  62.         return -ENOENT;
  63.     }
  64.     if (!S_ISLNK(inode->i_mode)) {
  65.         iput(dir);
  66.         *res_inode = inode;
  67.         return 0;
  68.     }
  69.     if ((current->link_count > 5) ||
  70.        !(pnt = get_rock_ridge_symlink(inode))) {
  71.         iput(dir);
  72.         iput(inode);
  73.         *res_inode = NULL;
  74.         return -ELOOP;
  75.     }
  76.     iput(inode);
  77.     current->link_count++;
  78.     error = open_namei(pnt,flag,mode,res_inode,dir);
  79.     current->link_count--;
  80.     kfree(pnt);
  81.     return error;
  82. }
  83.  
  84. static int isofs_readlink(struct inode * inode, char * buffer, int buflen)
  85. {
  86.         char * pnt;
  87.     int i;
  88.     char c;
  89.  
  90.     if (!S_ISLNK(inode->i_mode)) {
  91.         iput(inode);
  92.         return -EINVAL;
  93.     }
  94.  
  95.     if (buflen > 1023)
  96.         buflen = 1023;
  97.     pnt = get_rock_ridge_symlink(inode);
  98.  
  99.     iput(inode);
  100.     if (!pnt)
  101.         return 0;
  102.     i = 0;
  103.  
  104.     while (i<buflen && (c = pnt[i])) {
  105.         i++;
  106.         put_fs_byte(c,buffer++);
  107.     }
  108.     kfree(pnt);
  109.     return i;
  110. }
  111.