This source file includes following definitions.
- msdos_dir_read
- msdos_readdir
1
2
3
4
5
6
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 #include <linux/string.h>
16
17 #include "msbuffer.h"
18
19 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
20 #define ROUND_UP(x) (((x)+3) & ~3)
21
22
23 #define PRINTK(X)
24
25 static int msdos_dir_read(struct inode * inode,struct file * filp, char * buf,int count)
26 {
27 return -EISDIR;
28 }
29
30 static struct file_operations msdos_dir_operations = {
31 NULL,
32 msdos_dir_read,
33 NULL,
34 msdos_readdir,
35 NULL,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 file_fsync
41 };
42
43 struct inode_operations msdos_dir_inode_operations = {
44 &msdos_dir_operations,
45 msdos_create,
46 msdos_lookup,
47 NULL,
48 msdos_unlink,
49 NULL,
50 msdos_mkdir,
51 msdos_rmdir,
52 NULL,
53 msdos_rename,
54 NULL,
55 NULL,
56 msdos_bmap,
57 NULL,
58 NULL
59 };
60
61 int msdos_readdir(
62 struct inode *inode,
63 struct file *filp,
64 struct dirent *dirent,
65 int count)
66 {
67 struct super_block *sb = inode->i_sb;
68 int ino,i,i2,last;
69 char c,*walk;
70 struct buffer_head *bh;
71 struct msdos_dir_entry *de;
72
73 if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF;
74 if (inode->i_ino == MSDOS_ROOT_INO) {
75
76 if (filp->f_pos == 2) filp->f_pos = 0;
77 else if (filp->f_pos < 2) {
78 walk = filp->f_pos++ ? ".." : ".";
79 for (i = 0; *walk; walk++)
80 put_fs_byte(*walk,dirent->d_name+i++);
81 put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino);
82 put_fs_byte(0,dirent->d_name+i);
83 put_fs_word(i,&dirent->d_reclen);
84 return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
85 }
86 }
87 if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT;
88 bh = NULL;
89 while ((ino = msdos_get_entry(inode,&filp->f_pos,&bh,&de)) > -1) {
90 if (!IS_FREE(de->name) && !(de->attr & ATTR_VOLUME)) {
91 char bufname[13];
92 char *ptname = bufname;
93 for (i = last = 0; i < 8; i++) {
94 if (!(c = de->name[i])) break;
95 if (c >= 'A' && c <= 'Z') c += 32;
96 if (c != ' ')
97 last = i+1;
98 ptname[i] = c;
99 }
100 i = last;
101 ptname[i] = '.';
102 i++;
103 for (i2 = 0; i2 < 3; i2++) {
104 if (!(c = de->ext[i2])) break;
105 if (c >= 'A' && c <= 'Z') c += 32;
106 if (c != ' ')
107 last = i+1;
108 ptname[i] = c;
109 i++;
110 }
111 if ((i = last) != 0) {
112 if (!strcmp(de->name,MSDOS_DOT))
113 ino = inode->i_ino;
114 else if (!strcmp(de->name,MSDOS_DOTDOT))
115 ino = msdos_parent_ino(inode,0);
116 bufname[i] = '\0';
117 put_fs_long(ino,&dirent->d_ino);
118 memcpy_tofs(dirent->d_name,bufname,i+1);
119 put_fs_word(i,&dirent->d_reclen);
120 PRINTK (("readdir avant brelse\n"));
121 brelse(bh);
122 PRINTK (("readdir retourne %d\n",i));
123 return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
124 }
125 }
126 }
127 if (bh) brelse(bh);
128 return 0;
129 }