blob: d910c46ddb159d5cf43a009f0d9248b5cd9768b2 [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 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02009 * SPDX-License-Identifier: GPL-2.0+
wdenk7a428cc2003-06-15 22:40:42 +000010 */
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
wdenk7a428cc2003-06-15 22:40:42 +000019/* Supported filesystems */
20static 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 */
26static int current_filesystem = FSTYPE_NONE;
27
28/* The current working directory */
29#define CWD_LEN 511
30char file_cwd[CWD_LEN+1] = "/";
31
32const char *
33file_getfsname(int idx)
34{
Wolfgang Denk927b8ce2010-07-19 11:37:00 +020035 if (idx < 0 || idx >= NUM_FILESYS)
36 return NULL;
wdenk7a428cc2003-06-15 22:40:42 +000037
38 return filesystems[idx].name;
39}
40
wdenk7a428cc2003-06-15 22:40:42 +000041static void
42pathcpy(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;
Wolfgang Denk927b8ce2010-07-19 11:37:00 +020059
60 if (ISDIRDELIM(*src))
wdenk7a428cc2003-06-15 22:40:42 +000061 while (ISDIRDELIM(*src)) src++;
Wolfgang Denk927b8ce2010-07-19 11:37:00 +020062 else
wdenk7a428cc2003-06-15 22:40:42 +000063 src++;
wdenk7a428cc2003-06-15 22:40:42 +000064 } while (1);
65}
66
wdenk7a428cc2003-06-15 22:40:42 +000067int
68file_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
wdenk7a428cc2003-06-15 22:40:42 +0000127int
128file_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
wdenk7a428cc2003-06-15 22:40:42 +0000145int
146file_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
wdenk7a428cc2003-06-15 22:40:42 +0000165long
166file_read(const char *filename, void *buffer, unsigned long maxsize)
167{
168 char fullpath[1024];
169 const char *arg;
170
171 if (current_filesystem == FSTYPE_NONE) {
172 printf("Can't load file without a filesystem!\n");
173 return -1;
174 }
175
176 if (ISDIRDELIM(*filename)) {
177 arg = filename;
178 } else {
179 sprintf(fullpath, "%s/%s", file_cwd, filename);
180 arg = fullpath;
181 }
182
183 return filesystems[current_filesystem].read(arg, buffer, maxsize);
184}