]>
Commit | Line | Data |
---|---|---|
8bde7f77 WD |
1 | /* |
2 | * file.c | |
71f95118 WD |
3 | * |
4 | * Mini "VFS" by Marcus Sundberg | |
5 | * | |
6 | * 2002-07-28 - [email protected] - ported to ppcboot v1.1.6 | |
7 | * 2003-03-10 - [email protected] - 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 | #if (CONFIG_COMMANDS & CFG_CMD_FAT) | |
36 | ||
37 | /* Supported filesystems */ | |
38 | static const struct filesystem filesystems[] = { | |
39 | { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, | |
40 | }; | |
41 | #define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) | |
42 | ||
43 | /* The filesystem which was last detected */ | |
44 | static int current_filesystem = FSTYPE_NONE; | |
45 | ||
46 | /* The current working directory */ | |
47 | #define CWD_LEN 511 | |
48 | char file_cwd[CWD_LEN+1] = "/"; | |
49 | ||
50 | const char * | |
51 | file_getfsname(int idx) | |
52 | { | |
53 | if (idx < 0 || idx >= NUM_FILESYS) return NULL; | |
54 | ||
55 | return filesystems[idx].name; | |
56 | } | |
57 | ||
58 | ||
59 | static void | |
60 | pathcpy(char *dest, const char *src) | |
61 | { | |
62 | char *origdest = dest; | |
63 | ||
64 | do { | |
65 | if (dest-file_cwd >= CWD_LEN) { | |
66 | *dest = '\0'; | |
67 | return; | |
68 | } | |
69 | *(dest) = *(src); | |
70 | if (*src == '\0') { | |
71 | if (dest-- != origdest && ISDIRDELIM(*dest)) { | |
72 | *dest = '\0'; | |
73 | } | |
74 | return; | |
75 | } | |
76 | ++dest; | |
77 | if (ISDIRDELIM(*src)) { | |
78 | while (ISDIRDELIM(*src)) src++; | |
79 | } else { | |
80 | src++; | |
81 | } | |
82 | } while (1); | |
83 | } | |
84 | ||
85 | ||
86 | int | |
87 | file_cd(const char *path) | |
88 | { | |
89 | if (ISDIRDELIM(*path)) { | |
90 | while (ISDIRDELIM(*path)) path++; | |
91 | strncpy(file_cwd+1, path, CWD_LEN-1); | |
92 | } else { | |
93 | const char *origpath = path; | |
94 | char *tmpstr = file_cwd; | |
95 | int back = 0; | |
96 | ||
97 | while (*tmpstr != '\0') tmpstr++; | |
98 | do { | |
99 | tmpstr--; | |
100 | } while (ISDIRDELIM(*tmpstr)); | |
101 | ||
102 | while (*path == '.') { | |
103 | path++; | |
104 | while (*path == '.') { | |
105 | path++; | |
106 | back++; | |
107 | } | |
108 | if (*path != '\0' && !ISDIRDELIM(*path)) { | |
109 | path = origpath; | |
110 | back = 0; | |
111 | break; | |
112 | } | |
113 | while (ISDIRDELIM(*path)) path++; | |
114 | origpath = path; | |
115 | } | |
116 | ||
117 | while (back--) { | |
118 | /* Strip off path component */ | |
119 | while (!ISDIRDELIM(*tmpstr)) { | |
120 | tmpstr--; | |
121 | } | |
122 | if (tmpstr == file_cwd) { | |
123 | /* Incremented again right after the loop. */ | |
124 | tmpstr--; | |
125 | break; | |
126 | } | |
127 | /* Skip delimiters */ | |
128 | while (ISDIRDELIM(*tmpstr)) tmpstr--; | |
129 | } | |
130 | tmpstr++; | |
131 | if (*path == '\0') { | |
132 | if (tmpstr == file_cwd) { | |
133 | *tmpstr = '/'; | |
134 | tmpstr++; | |
135 | } | |
136 | *tmpstr = '\0'; | |
137 | return 0; | |
138 | } | |
139 | *tmpstr = '/'; | |
140 | pathcpy(tmpstr+1, path); | |
141 | } | |
142 | ||
143 | return 0; | |
144 | } | |
145 | ||
8bde7f77 | 146 | |
71f95118 WD |
147 | int |
148 | file_detectfs(void) | |
149 | { | |
150 | int i; | |
151 | ||
152 | current_filesystem = FSTYPE_NONE; | |
153 | ||
154 | for (i = 0; i < NUM_FILESYS; i++) { | |
155 | if (filesystems[i].detect() == 0) { | |
156 | strcpy(file_cwd, "/"); | |
157 | current_filesystem = i; | |
158 | break; | |
159 | } | |
160 | } | |
161 | ||
162 | return current_filesystem; | |
163 | } | |
164 | ||
165 | ||
166 | int | |
167 | file_ls(const char *dir) | |
168 | { | |
169 | char fullpath[1024]; | |
170 | const char *arg; | |
171 | ||
172 | if (current_filesystem == FSTYPE_NONE) { | |
173 | printf("Can't list files without a filesystem!\n"); | |
174 | return -1; | |
175 | } | |
176 | ||
177 | if (ISDIRDELIM(*dir)) { | |
178 | arg = dir; | |
179 | } else { | |
180 | sprintf(fullpath, "%s/%s", file_cwd, dir); | |
181 | arg = fullpath; | |
182 | } | |
183 | return filesystems[current_filesystem].ls(arg); | |
184 | } | |
185 | ||
186 | ||
187 | long | |
188 | file_read(const char *filename, void *buffer, unsigned long maxsize) | |
189 | { | |
190 | char fullpath[1024]; | |
191 | const char *arg; | |
192 | ||
193 | if (current_filesystem == FSTYPE_NONE) { | |
194 | printf("Can't load file without a filesystem!\n"); | |
195 | return -1; | |
196 | } | |
197 | ||
198 | if (ISDIRDELIM(*filename)) { | |
199 | arg = filename; | |
200 | } else { | |
201 | sprintf(fullpath, "%s/%s", file_cwd, filename); | |
202 | arg = fullpath; | |
203 | } | |
204 | ||
205 | return filesystems[current_filesystem].read(arg, buffer, maxsize); | |
206 | } | |
207 | ||
208 | #endif /* #if (CONFIG_COMMANDS & CFG_CMD_FAT) */ |