]>
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 | * | |
1a459660 | 9 | * SPDX-License-Identifier: GPL-2.0+ |
71f95118 WD |
10 | */ |
11 | ||
12 | #include <common.h> | |
13 | #include <config.h> | |
14 | #include <malloc.h> | |
15 | #include <fat.h> | |
16 | #include <linux/stat.h> | |
17 | #include <linux/time.h> | |
18 | ||
71f95118 WD |
19 | /* Supported filesystems */ |
20 | static const struct filesystem filesystems[] = { | |
21 | { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, | |
22 | }; | |
23 | #define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) | |
24 | ||
25 | /* The filesystem which was last detected */ | |
26 | static int current_filesystem = FSTYPE_NONE; | |
27 | ||
28 | /* The current working directory */ | |
29 | #define CWD_LEN 511 | |
30 | char file_cwd[CWD_LEN+1] = "/"; | |
31 | ||
32 | const char * | |
33 | file_getfsname(int idx) | |
34 | { | |
7385c28e WD |
35 | if (idx < 0 || idx >= NUM_FILESYS) |
36 | return NULL; | |
71f95118 WD |
37 | |
38 | return filesystems[idx].name; | |
39 | } | |
40 | ||
71f95118 WD |
41 | static void |
42 | pathcpy(char *dest, const char *src) | |
43 | { | |
44 | char *origdest = dest; | |
45 | ||
46 | do { | |
47 | if (dest-file_cwd >= CWD_LEN) { | |
48 | *dest = '\0'; | |
49 | return; | |
50 | } | |
51 | *(dest) = *(src); | |
52 | if (*src == '\0') { | |
53 | if (dest-- != origdest && ISDIRDELIM(*dest)) { | |
54 | *dest = '\0'; | |
55 | } | |
56 | return; | |
57 | } | |
58 | ++dest; | |
7385c28e WD |
59 | |
60 | if (ISDIRDELIM(*src)) | |
71f95118 | 61 | while (ISDIRDELIM(*src)) src++; |
7385c28e | 62 | else |
71f95118 | 63 | src++; |
71f95118 WD |
64 | } while (1); |
65 | } | |
66 | ||
71f95118 WD |
67 | int |
68 | file_cd(const char *path) | |
69 | { | |
70 | if (ISDIRDELIM(*path)) { | |
71 | while (ISDIRDELIM(*path)) path++; | |
72 | strncpy(file_cwd+1, path, CWD_LEN-1); | |
73 | } else { | |
74 | const char *origpath = path; | |
75 | char *tmpstr = file_cwd; | |
76 | int back = 0; | |
77 | ||
78 | while (*tmpstr != '\0') tmpstr++; | |
79 | do { | |
80 | tmpstr--; | |
81 | } while (ISDIRDELIM(*tmpstr)); | |
82 | ||
83 | while (*path == '.') { | |
84 | path++; | |
85 | while (*path == '.') { | |
86 | path++; | |
87 | back++; | |
88 | } | |
89 | if (*path != '\0' && !ISDIRDELIM(*path)) { | |
90 | path = origpath; | |
91 | back = 0; | |
92 | break; | |
93 | } | |
94 | while (ISDIRDELIM(*path)) path++; | |
95 | origpath = path; | |
96 | } | |
97 | ||
98 | while (back--) { | |
99 | /* Strip off path component */ | |
100 | while (!ISDIRDELIM(*tmpstr)) { | |
101 | tmpstr--; | |
102 | } | |
103 | if (tmpstr == file_cwd) { | |
104 | /* Incremented again right after the loop. */ | |
105 | tmpstr--; | |
106 | break; | |
107 | } | |
108 | /* Skip delimiters */ | |
109 | while (ISDIRDELIM(*tmpstr)) tmpstr--; | |
110 | } | |
111 | tmpstr++; | |
112 | if (*path == '\0') { | |
113 | if (tmpstr == file_cwd) { | |
114 | *tmpstr = '/'; | |
115 | tmpstr++; | |
116 | } | |
117 | *tmpstr = '\0'; | |
118 | return 0; | |
119 | } | |
120 | *tmpstr = '/'; | |
121 | pathcpy(tmpstr+1, path); | |
122 | } | |
123 | ||
124 | return 0; | |
125 | } | |
126 | ||
71f95118 WD |
127 | int |
128 | file_detectfs(void) | |
129 | { | |
130 | int i; | |
131 | ||
132 | current_filesystem = FSTYPE_NONE; | |
133 | ||
134 | for (i = 0; i < NUM_FILESYS; i++) { | |
135 | if (filesystems[i].detect() == 0) { | |
136 | strcpy(file_cwd, "/"); | |
137 | current_filesystem = i; | |
138 | break; | |
139 | } | |
140 | } | |
141 | ||
142 | return current_filesystem; | |
143 | } | |
144 | ||
71f95118 WD |
145 | int |
146 | file_ls(const char *dir) | |
147 | { | |
148 | char fullpath[1024]; | |
149 | const char *arg; | |
150 | ||
151 | if (current_filesystem == FSTYPE_NONE) { | |
152 | printf("Can't list files without a filesystem!\n"); | |
153 | return -1; | |
154 | } | |
155 | ||
156 | if (ISDIRDELIM(*dir)) { | |
157 | arg = dir; | |
158 | } else { | |
159 | sprintf(fullpath, "%s/%s", file_cwd, dir); | |
160 | arg = fullpath; | |
161 | } | |
162 | return filesystems[current_filesystem].ls(arg); | |
163 | } | |
164 | ||
1ad0b98a | 165 | int file_read(const char *filename, void *buffer, int maxsize) |
71f95118 WD |
166 | { |
167 | char fullpath[1024]; | |
168 | const char *arg; | |
169 | ||
170 | if (current_filesystem == FSTYPE_NONE) { | |
171 | printf("Can't load file without a filesystem!\n"); | |
172 | return -1; | |
173 | } | |
174 | ||
175 | if (ISDIRDELIM(*filename)) { | |
176 | arg = filename; | |
177 | } else { | |
178 | sprintf(fullpath, "%s/%s", file_cwd, filename); | |
179 | arg = fullpath; | |
180 | } | |
181 | ||
182 | return filesystems[current_filesystem].read(arg, buffer, maxsize); | |
183 | } |