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 / msdos / dir.c next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  2.9 KB  |  115 lines

  1. /*
  2.  *  linux/fs/msdos/dir.c
  3.  *
  4.  *  Written 1992,1993 by Werner Almesberger
  5.  *
  6.  *  MS-DOS directory handling functions
  7.  */
  8.  
  9. #include <asm/segment.h>
  10.  
  11. #include <linux/fs.h>
  12. #include <linux/msdos_fs.h>
  13. #include <linux/errno.h>
  14. #include <linux/stat.h>
  15.  
  16.  
  17. static int msdos_dir_read(struct inode * inode,struct file * filp, char * buf,int count)
  18. {
  19.     return -EISDIR;
  20. }
  21.  
  22. static int msdos_readdir(struct inode *inode,struct file *filp,
  23.     struct dirent *dirent,int count);
  24.  
  25.  
  26. static struct file_operations msdos_dir_operations = {
  27.     NULL,            /* lseek - default */
  28.     msdos_dir_read,        /* read */
  29.     NULL,            /* write - bad */
  30.     msdos_readdir,        /* readdir */
  31.     NULL,            /* select - default */
  32.     NULL,            /* ioctl - default */
  33.     NULL,            /* mmap */
  34.     NULL,            /* no special open code */
  35.     NULL,            /* no special release code */
  36.     file_fsync        /* fsync */
  37. };
  38.  
  39. struct inode_operations msdos_dir_inode_operations = {
  40.     &msdos_dir_operations,    /* default directory file-ops */
  41.     msdos_create,        /* create */
  42.     msdos_lookup,        /* lookup */
  43.     NULL,            /* link */
  44.     msdos_unlink,        /* unlink */
  45.     NULL,            /* symlink */
  46.     msdos_mkdir,        /* mkdir */
  47.     msdos_rmdir,        /* rmdir */
  48.     NULL,            /* mknod */
  49.     msdos_rename,        /* rename */
  50.     NULL,            /* readlink */
  51.     NULL,            /* follow_link */
  52.     msdos_bmap,        /* bmap */
  53.     NULL,            /* truncate */
  54.     NULL            /* permission */
  55. };
  56.  
  57. static int msdos_readdir(struct inode *inode,struct file *filp,
  58.     struct dirent *dirent,int count)
  59. {
  60.     int ino,i,i2,last;
  61.     char c,*walk;
  62.     struct buffer_head *bh;
  63.     struct msdos_dir_entry *de;
  64.  
  65.     if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF;
  66.     if (inode->i_ino == MSDOS_ROOT_INO) {
  67. /* Fake . and .. for the root directory. */
  68.         if (filp->f_pos == 2) filp->f_pos = 0;
  69.         else if (filp->f_pos < 2) {
  70.                 walk = filp->f_pos++ ? ".." : ".";
  71.                 for (i = 0; *walk; walk++)
  72.                     put_fs_byte(*walk,dirent->d_name+i++);
  73.                 put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino);
  74.                 put_fs_byte(0,dirent->d_name+i);
  75.                 put_fs_word(i,&dirent->d_reclen);
  76.                 return i;
  77.             }
  78.     }
  79.     if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT;
  80.     bh = NULL;
  81.     while ((ino = msdos_get_entry(inode,&filp->f_pos,&bh,&de)) > -1) {
  82.         if (!IS_FREE(de->name) && !(de->attr & ATTR_VOLUME)) {
  83.             for (i = last = 0; i < 8; i++) {
  84.                 if (!(c = de->name[i])) break;
  85.                 if (c >= 'A' && c <= 'Z') c += 32;
  86.                 if (c != ' ') last = i+1;
  87.                 put_fs_byte(c,i+dirent->d_name);
  88.             }
  89.             i = last;
  90.             put_fs_byte('.',i+dirent->d_name);
  91.             i++;
  92.             for (i2 = 0; i2 < 3; i2++) {
  93.                 if (!(c = de->ext[i2])) break;
  94.                 if (c >= 'A' && c <= 'Z') c += 32;
  95.                 if (c != ' ') last = i+1;
  96.                 put_fs_byte(c,i+dirent->d_name);
  97.                 i++;
  98.             }
  99.             if ((i = last) != 0) {
  100.                 if (!strcmp(de->name,MSDOS_DOT))
  101.                     ino = inode->i_ino;
  102.                 else if (!strcmp(de->name,MSDOS_DOTDOT))
  103.                         ino = msdos_parent_ino(inode,0);
  104.                 put_fs_long(ino,&dirent->d_ino);
  105.                 put_fs_byte(0,i+dirent->d_name);
  106.                 put_fs_word(i,&dirent->d_reclen);
  107.                 brelse(bh);
  108.                 return i;
  109.             }
  110.         }
  111.     }
  112.     if (bh) brelse(bh);
  113.     return 0;
  114. }
  115.