blob: 729f96cbf5e20239f5e6c2dea64eae5d0764cf42 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2009 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <debug.h>
24#include <string.h>
25#include <lib/console.h>
26#include <lib/fs.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <platform.h>
30#include <err.h>
31
32static void test_normalize(const char *in)
33{
34 char path[1024];
35
36 strlcpy(path, in, sizeof(path));
37 fs_normalize_path(path);
38 printf("'%s' -> '%s'\n", in, path);
39}
40
41#if 0
42test_normalize("/");
43test_normalize("/test");
44test_normalize("/test/");
45test_normalize("test/");
46test_normalize("test");
47test_normalize("/test//");
48test_normalize("/test/foo");
49test_normalize("/test/foo/");
50test_normalize("/test/foo/bar");
51test_normalize("/test/foo/bar//");
52test_normalize("/test//foo/bar//");
53test_normalize("/test//./foo/bar//");
54test_normalize("/test//./.foo/bar//");
55test_normalize("/test//./..foo/bar//");
56test_normalize("/test//./../foo/bar//");
57test_normalize("/test/../foo");
58test_normalize("/test/bar/../foo");
59test_normalize("../foo");
60test_normalize("../foo/");
61test_normalize("/../foo");
62test_normalize("/../foo/");
63test_normalize("/../../foo");
64test_normalize("/bleh/../../foo");
65test_normalize("/bleh/bar/../../foo");
66test_normalize("/bleh/bar/../../foo/..");
67test_normalize("/bleh/bar/../../foo/../meh");
68#endif
69
70#if defined(WITH_LIB_CONSOLE)
71
72#if LK_DEBUGLEVEL > 1
73static int cmd_fs(int argc, const cmd_args *argv);
74
75STATIC_COMMAND_START
76STATIC_COMMAND("fs", "fs debug commands", &cmd_fs)
77STATIC_COMMAND_END(fs);
78
79extern int fs_mount_type(const char *path, const char *device, const char *name);
80
81static int cmd_fs_ioctl(int argc, const cmd_args *argv)
82{
83 if (argc < 3) {
84 printf("not enough arguments\n");
85 return ERR_INVALID_ARGS;
86 }
87
88 int request = argv[2].u;
89
90 switch (request) {
91 case FS_IOCTL_GET_FILE_ADDR: {
92 if (argc < 4) {
93 printf("%s %s %lu <path>\n", argv[0].str, argv[1].str,
94 argv[2].u);
95 return ERR_INVALID_ARGS;
96 }
97
98 int err;
99 filehandle *handle;
100 err = fs_open_file(argv[3].str, &handle);
101 if (err != NO_ERROR) {
102 printf("error %d opening file\n", err);
103 return err;
104 }
105
106 void *file_addr;
107 err = fs_file_ioctl(handle, request, &file_addr);
108 if (err != NO_ERROR) {
109 fs_close_file(handle);
110 return err;
111 }
112
113 printf("%s is mapped at %p\n", argv[3].str, file_addr);
114
115 return fs_close_file(handle);
116 break;
117 }
118 default: {
119 printf("error, unsupported ioctl: %d\n", request);
120 }
121 }
122
123 return ERR_NOT_SUPPORTED;
124}
125
126static int cmd_fs(int argc, const cmd_args *argv)
127{
128 int rc = 0;
129
130 if (argc < 2) {
131notenoughargs:
132 printf("not enough arguments:\n");
133usage:
134 printf("%s mount <path> <type> [device]\n", argv[0].str);
135 printf("%s unmount <path>\n", argv[0].str);
136 printf("%s write <path> <string> [<offset>]\n", argv[0].str);
137 printf("%s format <type> [device]\n", argv[0].str);
138 printf("%s stat <path>\n", argv[0].str);
139 printf("%s ioctl <request> [args...]\n", argv[0].str);
140 return -1;
141 }
142
143 if (!strcmp(argv[1].str, "mount")) {
144 int err;
145
146 if (argc < 4)
147 goto notenoughargs;
148
149 err = fs_mount(argv[2].str, argv[3].str,
150 (argc >= 5) ? argv[4].str : NULL);
151
152 if (err < 0) {
153 printf("error %d mounting device\n", err);
154 return err;
155 }
156 } else if (!strcmp(argv[1].str, "unmount")) {
157 int err;
158
159 if (argc < 3)
160 goto notenoughargs;
161
162 err = fs_unmount(argv[2].str);
163 if (err < 0) {
164 printf("error %d unmounting device\n", err);
165 return err;
166 }
167 } else if (!strcmp(argv[1].str, "format")) {
168 int err;
169
170 if (argc < 3) {
171 goto notenoughargs;
172 }
173
174 err = fs_format_device(
175 argv[2].str,
176 (argc >= 4) ? argv[3].str : NULL,
177 NULL
178 );
179
180 if (err != NO_ERROR) {
181 printf("error %d formatting device\n", err);
182 return err;
183 }
184
185 } else if (!strcmp(argv[1].str, "stat")) {
186 int err;
187
188 if (argc < 3) {
189 goto notenoughargs;
190 }
191
192 struct fs_stat stat;
193 err = fs_stat_fs(argv[2].str, &stat);
194
195 if (err != NO_ERROR) {
196 printf("error %d statting filesystem\n", err);
197 return err;
198 }
199
200 printf("\ttotal bytes: %llu\n", stat.total_space);
201 printf("\tfree bytes: %llu\n", stat.free_space);
202 printf("\n");
203 printf("\ttotal inodes: %d\n", stat.total_inodes);
204 printf("\tfree inodes: %d\n", stat.free_inodes);
205
206 } else if (!strcmp(argv[1].str, "ioctl")) {
207 return cmd_fs_ioctl(argc, argv);
208 } else if (!strcmp(argv[1].str, "write")) {
209 int err;
210 off_t off;
211 filehandle *handle;
212 struct file_stat stat;
213
214 if (argc < 3)
215 goto notenoughargs;
216
217 err = fs_open_file(argv[2].str, &handle);
218 if (err < 0) {
219 printf("error %d opening file\n", err);
220 return err;
221 }
222
223 err = fs_stat_file(handle, &stat);
224 if (err < 0) {
225 printf("error %d stat'ing file\n", err);
226 fs_close_file(handle);
227 return err;
228 }
229
230 if (argc < 5)
231 off = stat.size;
232 else
233 off = argv[4].u;
234
235 err = fs_write_file(handle, argv[3].str, off, strlen(argv[3].str));
236 if (err < 0) {
237 printf("error %d writing file\n", err);
238 fs_close_file(handle);
239 return err;
240 }
241
242 fs_close_file(handle);
243 } else {
244 printf("unrecognized subcommand\n");
245 goto usage;
246 }
247
248 return rc;
249}
250
251#endif
252
253#endif
254