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 #ifdef MODULE
10 #include <linux/module.h>
11 #endif
12
13 #include <asm/segment.h>
14
15 #include <linux/fs.h>
16 #include <linux/msdos_fs.h>
17 #include <linux/errno.h>
18 #include <linux/stat.h>
19 #include <linux/string.h>
20
21 #include "msbuffer.h"
22
23
24 #define PRINTK(X)
25
26 static int msdos_dir_read(struct inode * inode,struct file * filp, char * buf,int count)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
27 {
28 return -EISDIR;
29 }
30
31 static struct file_operations msdos_dir_operations = {
32 NULL, /* lseek - default */
33 msdos_dir_read, /* read */
34 NULL, /* write - bad */
35 msdos_readdir, /* readdir */
36 NULL, /* select - default */
37 NULL, /* ioctl - default */
38 NULL, /* mmap */
39 NULL, /* no special open code */
40 NULL, /* no special release code */
41 file_fsync /* fsync */
42 };
43
44 struct inode_operations msdos_dir_inode_operations = {
45 &msdos_dir_operations, /* default directory file-ops */
46 msdos_create, /* create */
47 msdos_lookup, /* lookup */
48 NULL, /* link */
49 msdos_unlink, /* unlink */
50 NULL, /* symlink */
51 msdos_mkdir, /* mkdir */
52 msdos_rmdir, /* rmdir */
53 NULL, /* mknod */
54 msdos_rename, /* rename */
55 NULL, /* readlink */
56 NULL, /* follow_link */
57 msdos_bmap, /* bmap */
58 NULL, /* truncate */
59 NULL /* permission */
60 };
61
62 int msdos_readdir(
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
63 struct inode *inode,
64 struct file *filp,
65 void *dirent,
66 filldir_t filldir)
67 {
68 struct super_block *sb = inode->i_sb;
69 int ino,i,i2,last;
70 char c;
71 struct buffer_head *bh;
72 struct msdos_dir_entry *de;
73 unsigned long oldpos = filp->f_pos;
74
75 if (!inode || !S_ISDIR(inode->i_mode))
76 return -EBADF;
77 /* Fake . and .. for the root directory. */
78 if (inode->i_ino == MSDOS_ROOT_INO) {
79 while (oldpos < 2) {
80 if (filldir(dirent, "..", oldpos+1, oldpos, MSDOS_ROOT_INO) < 0)
81 return 0;
82 oldpos++;
83 filp->f_pos++;
84 }
85 if (oldpos == 2)
86 filp->f_pos = 0;
87 }
88 if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1))
89 return -ENOENT;
90 bh = NULL;
91 while ((ino = msdos_get_entry(inode,&filp->f_pos,&bh,&de)) > -1) {
92 if (!IS_FREE(de->name) && !(de->attr & ATTR_VOLUME)) {
93 char bufname[12];
94 char *ptname = bufname;
95 for (i = last = 0; i < 8; i++) {
96 if (!(c = de->name[i])) break;
97 if (c >= 'A' && c <= 'Z') c += 32;
98 if (c != ' ')
99 last = i+1;
100 ptname[i] = c;
101 }
102 i = last;
103 ptname[i] = '.';
104 i++;
105 for (i2 = 0; i2 < 3; i2++) {
106 if (!(c = de->ext[i2])) break;
107 if (c >= 'A' && c <= 'Z') c += 32;
108 if (c != ' ')
109 last = i+1;
110 ptname[i] = c;
111 i++;
112 }
113 if ((i = last) != 0) {
114 if (!strcmp(de->name,MSDOS_DOT))
115 ino = inode->i_ino;
116 else if (!strcmp(de->name,MSDOS_DOTDOT))
117 ino = msdos_parent_ino(inode,0);
118 if (filldir(dirent, bufname, i, oldpos, ino) < 0) {
119 filp->f_pos = oldpos;
120 break;
121 }
122 }
123 }
124 oldpos = filp->f_pos;
125 }
126 if (bh) brelse(bh);
127 return 0;
128 }