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 / isofs / symlink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  2.0 KB  |  107 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. #include <asm/segment.h>
  13.  
  14. #include <linux/errno.h>
  15. #include <linux/sched.h>
  16. #include <linux/fs.h>
  17. #include <linux/iso_fs.h>
  18. #include <linux/stat.h>
  19. #include <linux/malloc.h>
  20.  
  21. static int isofs_readlink(struct inode *, char *, int);
  22. static int isofs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  23.  
  24. /*
  25.  * symlinks can't do much...
  26.  */
  27. struct inode_operations isofs_symlink_inode_operations = {
  28.     NULL,            /* no file-operations */
  29.     NULL,            /* create */
  30.     NULL,            /* lookup */
  31.     NULL,            /* link */
  32.     NULL,            /* unlink */
  33.     NULL,            /* symlink */
  34.     NULL,            /* mkdir */
  35.     NULL,            /* rmdir */
  36.     NULL,            /* mknod */
  37.     NULL,            /* rename */
  38.     isofs_readlink,        /* readlink */
  39.     isofs_follow_link,    /* follow_link */
  40.     NULL,            /* bmap */
  41.     NULL,            /* truncate */
  42.     NULL            /* permission */
  43. };
  44.  
  45. static int isofs_follow_link(struct inode * dir, struct inode * inode,
  46.     int flag, int mode, struct inode ** res_inode)
  47. {
  48.     int error;
  49.     char * pnt;
  50.  
  51.     if (!dir) {
  52.         dir = current->root;
  53.         dir->i_count++;
  54.     }
  55.     if (!inode) {
  56.         iput(dir);
  57.         *res_inode = NULL;
  58.         return -ENOENT;
  59.     }
  60.     if (!S_ISLNK(inode->i_mode)) {
  61.         iput(dir);
  62.         *res_inode = inode;
  63.         return 0;
  64.     }
  65.     if ((current->link_count > 5) ||
  66.        !(pnt = get_rock_ridge_symlink(inode))) {
  67.         iput(dir);
  68.         iput(inode);
  69.         *res_inode = NULL;
  70.         return -ELOOP;
  71.     }
  72.     iput(inode);
  73.     current->link_count++;
  74.     error = open_namei(pnt,flag,mode,res_inode,dir);
  75.     current->link_count--;
  76.     kfree(pnt);
  77.     return error;
  78. }
  79.  
  80. static int isofs_readlink(struct inode * inode, char * buffer, int buflen)
  81. {
  82.         char * pnt;
  83.     int i;
  84.     char c;
  85.  
  86.     if (!S_ISLNK(inode->i_mode)) {
  87.         iput(inode);
  88.         return -EINVAL;
  89.     }
  90.  
  91.     if (buflen > 1023)
  92.         buflen = 1023;
  93.     pnt = get_rock_ridge_symlink(inode);
  94.  
  95.     iput(inode);
  96.     if (!pnt)
  97.         return 0;
  98.     i = 0;
  99.  
  100.     while (i<buflen && (c = pnt[i])) {
  101.         i++;
  102.         put_fs_byte(c,buffer++);
  103.     }
  104.     kfree(pnt);
  105.     return i;
  106. }
  107.