4 * Written 1992,1993 by Werner Almesberger
6 * MS-DOS directory handling functions
9 #include <asm/segment.h>
12 #include <linux/msdos_fs.h>
13 #include <linux/errno.h>
14 #include <linux/stat.h>
17 static int msdos_dir_read(struct inode
* inode
,struct file
* filp
, char * buf
,int count
)
22 static int msdos_readdir(struct inode
*inode
,struct file
*filp
,
23 struct dirent
*dirent
,int count
);
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 */
34 NULL
, /* no special open code */
35 NULL
, /* no special release code */
36 file_fsync
/* fsync */
39 struct inode_operations msdos_dir_inode_operations
= {
40 &msdos_dir_operations
, /* default directory file-ops */
41 msdos_create
, /* create */
42 msdos_lookup
, /* lookup */
44 msdos_unlink
, /* unlink */
46 msdos_mkdir
, /* mkdir */
47 msdos_rmdir
, /* rmdir */
49 msdos_rename
, /* rename */
51 NULL
, /* follow_link */
52 msdos_bmap
, /* bmap */
57 static int msdos_readdir(struct inode
*inode
,struct file
*filp
,
58 struct dirent
*dirent
,int count
)
62 struct buffer_head
*bh
;
63 struct msdos_dir_entry
*de
;
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
);
79 if (filp
->f_pos
& (sizeof(struct msdos_dir_entry
)-1)) return -ENOENT
;
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
);
90 put_fs_byte('.',i
+dirent
->d_name
);
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
);
99 if ((i
= last
) != 0) {
100 if (!strcmp(de
->name
,MSDOS_DOT
))
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
);