]> git.sur5r.net Git - u-boot/blob - fs/fat/file.c
cmd_bootm.c: Correct BOOTM_ERR_OVERLAP handling
[u-boot] / fs / fat / file.c
1 /*
2  * file.c
3  *
4  * Mini "VFS" by Marcus Sundberg
5  *
6  * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6
7  * 2003-03-10 - kharris@nexus-tech.net - ported to uboot
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <common.h>
29 #include <config.h>
30 #include <malloc.h>
31 #include <fat.h>
32 #include <linux/stat.h>
33 #include <linux/time.h>
34
35 /* Supported filesystems */
36 static const struct filesystem filesystems[] = {
37         { file_fat_detectfs,  file_fat_ls,  file_fat_read,  "FAT" },
38 };
39 #define NUM_FILESYS     (sizeof(filesystems)/sizeof(struct filesystem))
40
41 /* The filesystem which was last detected */
42 static int current_filesystem = FSTYPE_NONE;
43
44 /* The current working directory */
45 #define CWD_LEN         511
46 char file_cwd[CWD_LEN+1] = "/";
47
48 const char *
49 file_getfsname(int idx)
50 {
51         if (idx < 0 || idx >= NUM_FILESYS)
52                 return NULL;
53
54         return filesystems[idx].name;
55 }
56
57 static void
58 pathcpy(char *dest, const char *src)
59 {
60         char *origdest = dest;
61
62         do {
63                 if (dest-file_cwd >= CWD_LEN) {
64                         *dest = '\0';
65                         return;
66                 }
67                 *(dest) = *(src);
68                 if (*src == '\0') {
69                         if (dest-- != origdest && ISDIRDELIM(*dest)) {
70                                 *dest = '\0';
71                         }
72                         return;
73                 }
74                 ++dest;
75
76                 if (ISDIRDELIM(*src))
77                         while (ISDIRDELIM(*src)) src++;
78                 else
79                         src++;
80         } while (1);
81 }
82
83 int
84 file_cd(const char *path)
85 {
86         if (ISDIRDELIM(*path)) {
87                 while (ISDIRDELIM(*path)) path++;
88                 strncpy(file_cwd+1, path, CWD_LEN-1);
89         } else {
90                 const char *origpath = path;
91                 char *tmpstr = file_cwd;
92                 int back = 0;
93
94                 while (*tmpstr != '\0') tmpstr++;
95                 do {
96                         tmpstr--;
97                 } while (ISDIRDELIM(*tmpstr));
98
99                 while (*path == '.') {
100                         path++;
101                         while (*path == '.') {
102                                 path++;
103                                 back++;
104                         }
105                         if (*path != '\0' && !ISDIRDELIM(*path)) {
106                                 path = origpath;
107                                 back = 0;
108                                 break;
109                         }
110                         while (ISDIRDELIM(*path)) path++;
111                         origpath = path;
112                 }
113
114                 while (back--) {
115                         /* Strip off path component */
116                         while (!ISDIRDELIM(*tmpstr)) {
117                                 tmpstr--;
118                         }
119                         if (tmpstr == file_cwd) {
120                                 /* Incremented again right after the loop. */
121                                 tmpstr--;
122                                 break;
123                         }
124                         /* Skip delimiters */
125                         while (ISDIRDELIM(*tmpstr)) tmpstr--;
126                 }
127                 tmpstr++;
128                 if (*path == '\0') {
129                         if (tmpstr == file_cwd) {
130                                 *tmpstr = '/';
131                                 tmpstr++;
132                         }
133                         *tmpstr = '\0';
134                         return 0;
135                 }
136                 *tmpstr = '/';
137                 pathcpy(tmpstr+1, path);
138         }
139
140         return 0;
141 }
142
143 int
144 file_detectfs(void)
145 {
146         int i;
147
148         current_filesystem = FSTYPE_NONE;
149
150         for (i = 0; i < NUM_FILESYS; i++) {
151                 if (filesystems[i].detect() == 0) {
152                         strcpy(file_cwd, "/");
153                         current_filesystem = i;
154                         break;
155                 }
156         }
157
158         return current_filesystem;
159 }
160
161 int
162 file_ls(const char *dir)
163 {
164         char fullpath[1024];
165         const char *arg;
166
167         if (current_filesystem == FSTYPE_NONE) {
168                 printf("Can't list files without a filesystem!\n");
169                 return -1;
170         }
171
172         if (ISDIRDELIM(*dir)) {
173                 arg = dir;
174         } else {
175                 sprintf(fullpath, "%s/%s", file_cwd, dir);
176                 arg = fullpath;
177         }
178         return filesystems[current_filesystem].ls(arg);
179 }
180
181 long
182 file_read(const char *filename, void *buffer, unsigned long maxsize)
183 {
184         char fullpath[1024];
185         const char *arg;
186
187         if (current_filesystem == FSTYPE_NONE) {
188                 printf("Can't load file without a filesystem!\n");
189                 return -1;
190         }
191
192         if (ISDIRDELIM(*filename)) {
193                 arg = filename;
194         } else {
195                 sprintf(fullpath, "%s/%s", file_cwd, filename);
196                 arg = fullpath;
197         }
198
199         return filesystems[current_filesystem].read(arg, buffer, maxsize);
200 }