]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - fs/fat/file.c
fs: Move conditional compilation to Makefile
[karo-tx-uboot.git] / 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) return NULL;
52
53         return filesystems[idx].name;
54 }
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                 if (ISDIRDELIM(*src)) {
76                         while (ISDIRDELIM(*src)) src++;
77                 } else {
78                         src++;
79                 }
80         } while (1);
81 }
82
83
84 int
85 file_cd(const char *path)
86 {
87         if (ISDIRDELIM(*path)) {
88                 while (ISDIRDELIM(*path)) path++;
89                 strncpy(file_cwd+1, path, CWD_LEN-1);
90         } else {
91                 const char *origpath = path;
92                 char *tmpstr = file_cwd;
93                 int back = 0;
94
95                 while (*tmpstr != '\0') tmpstr++;
96                 do {
97                         tmpstr--;
98                 } while (ISDIRDELIM(*tmpstr));
99
100                 while (*path == '.') {
101                         path++;
102                         while (*path == '.') {
103                                 path++;
104                                 back++;
105                         }
106                         if (*path != '\0' && !ISDIRDELIM(*path)) {
107                                 path = origpath;
108                                 back = 0;
109                                 break;
110                         }
111                         while (ISDIRDELIM(*path)) path++;
112                         origpath = path;
113                 }
114
115                 while (back--) {
116                         /* Strip off path component */
117                         while (!ISDIRDELIM(*tmpstr)) {
118                                 tmpstr--;
119                         }
120                         if (tmpstr == file_cwd) {
121                                 /* Incremented again right after the loop. */
122                                 tmpstr--;
123                                 break;
124                         }
125                         /* Skip delimiters */
126                         while (ISDIRDELIM(*tmpstr)) tmpstr--;
127                 }
128                 tmpstr++;
129                 if (*path == '\0') {
130                         if (tmpstr == file_cwd) {
131                                 *tmpstr = '/';
132                                 tmpstr++;
133                         }
134                         *tmpstr = '\0';
135                         return 0;
136                 }
137                 *tmpstr = '/';
138                 pathcpy(tmpstr+1, path);
139         }
140
141         return 0;
142 }
143
144
145 int
146 file_detectfs(void)
147 {
148         int i;
149
150         current_filesystem = FSTYPE_NONE;
151
152         for (i = 0; i < NUM_FILESYS; i++) {
153                 if (filesystems[i].detect() == 0) {
154                         strcpy(file_cwd, "/");
155                         current_filesystem = i;
156                         break;
157                 }
158         }
159
160         return current_filesystem;
161 }
162
163
164 int
165 file_ls(const char *dir)
166 {
167         char fullpath[1024];
168         const char *arg;
169
170         if (current_filesystem == FSTYPE_NONE) {
171                 printf("Can't list files without a filesystem!\n");
172                 return -1;
173         }
174
175         if (ISDIRDELIM(*dir)) {
176                 arg = dir;
177         } else {
178                 sprintf(fullpath, "%s/%s", file_cwd, dir);
179                 arg = fullpath;
180         }
181         return filesystems[current_filesystem].ls(arg);
182 }
183
184
185 long
186 file_read(const char *filename, void *buffer, unsigned long maxsize)
187 {
188         char fullpath[1024];
189         const char *arg;
190
191         if (current_filesystem == FSTYPE_NONE) {
192                 printf("Can't load file without a filesystem!\n");
193                 return -1;
194         }
195
196         if (ISDIRDELIM(*filename)) {
197                 arg = filename;
198         } else {
199                 sprintf(fullpath, "%s/%s", file_cwd, filename);
200                 arg = fullpath;
201         }
202
203         return filesystems[current_filesystem].read(arg, buffer, maxsize);
204 }