blob: 514dbaecba8129bdb62c318ee7ac281530aacccd [file] [log] [blame]
wdenk57b2d802003-06-27 21:31:46 +00001/*
2 * file.c
wdenk7a428cc2003-06-15 22:40:42 +00003 *
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
Jon Loeliger80eb47c2007-07-09 17:56:50 -050035#if defined(CONFIG_CMD_FAT)
wdenk7a428cc2003-06-15 22:40:42 +000036
37/* Supported filesystems */
38static 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 */
44static int current_filesystem = FSTYPE_NONE;
45
46/* The current working directory */
47#define CWD_LEN 511
48char file_cwd[CWD_LEN+1] = "/";
49
50const char *
51file_getfsname(int idx)
52{
53 if (idx < 0 || idx >= NUM_FILESYS) return NULL;
54
55 return filesystems[idx].name;
56}
57
58
59static void
60pathcpy(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
86int
87file_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
wdenk57b2d802003-06-27 21:31:46 +0000146
wdenk7a428cc2003-06-15 22:40:42 +0000147int
148file_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
166int
167file_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
187long
188file_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
Jon Loeliger80eb47c2007-07-09 17:56:50 -0500208#endif