]> git.ipfire.org Git - people/ms/u-boot.git/blob - fs/fat/file.c
89706117b9410c1be7363f268881e75640b36b2a
[people/ms/u-boot.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 * SPDX-License-Identifier: GPL-2.0+
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
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 {
35 if (idx < 0 || idx >= NUM_FILESYS)
36 return NULL;
37
38 return filesystems[idx].name;
39 }
40
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;
59
60 if (ISDIRDELIM(*src))
61 while (ISDIRDELIM(*src)) src++;
62 else
63 src++;
64 } while (1);
65 }
66
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
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
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
165 int file_read(const char *filename, void *buffer, int maxsize)
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 }