diff options
Diffstat (limited to 'firmware/common/rbpaths.c')
-rw-r--r-- | firmware/common/rbpaths.c | 166 |
1 files changed, 143 insertions, 23 deletions
diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c index b63586c9f4..50d6ccf6ec 100644 --- a/firmware/common/rbpaths.c +++ b/firmware/common/rbpaths.c | |||
@@ -22,13 +22,47 @@ | |||
22 | 22 | ||
23 | #include <stdio.h> /* snprintf */ | 23 | #include <stdio.h> /* snprintf */ |
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | #include <stdarg.h> | ||
25 | #include "rbpaths.h" | 26 | #include "rbpaths.h" |
26 | #include "file.h" /* MAX_PATH */ | 27 | #include "file.h" /* MAX_PATH */ |
27 | #include "dir.h" | ||
28 | #include "gcc_extensions.h" | 28 | #include "gcc_extensions.h" |
29 | #include "string-extra.h" | 29 | #include "string-extra.h" |
30 | #include "filefuncs.h" | 30 | #include "filefuncs.h" |
31 | 31 | ||
32 | #undef open | ||
33 | #undef creat | ||
34 | #undef remove | ||
35 | #undef rename | ||
36 | #undef opendir | ||
37 | #undef mkdir | ||
38 | #undef rmdir | ||
39 | |||
40 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) | ||
41 | #include "dir-target.h" | ||
42 | #define opendir opendir_android | ||
43 | #define mkdir mkdir_android | ||
44 | #define rmdir rmdir_android | ||
45 | #elif (CONFIG_PLATFORM & PLATFORM_SDL) | ||
46 | #define open sim_open | ||
47 | #define remove sim_remove | ||
48 | #define rename sim_rename | ||
49 | #define opendir sim_opendir | ||
50 | #define mkdir sim_mkdir | ||
51 | #define rmdir sim_rmdir | ||
52 | extern int sim_open(const char* name, int o, ...); | ||
53 | extern int sim_remove(const char* name); | ||
54 | extern int sim_rename(const char* old, const char* new); | ||
55 | extern DIR* sim_opendir(const char* name); | ||
56 | extern int sim_mkdir(const char* name); | ||
57 | extern int sim_rmdir(const char* name); | ||
58 | #endif | ||
59 | |||
60 | /* flags for get_user_file_path() */ | ||
61 | /* whether you need write access to that file/dir, especially true | ||
62 | * for runtime generated files (config.cfg) */ | ||
63 | #define NEED_WRITE (1<<0) | ||
64 | /* file or directory? */ | ||
65 | #define IS_FILE (1<<1) | ||
32 | 66 | ||
33 | void paths_init(void) | 67 | void paths_init(void) |
34 | { | 68 | { |
@@ -42,14 +76,28 @@ void paths_init(void) | |||
42 | #endif | 76 | #endif |
43 | } | 77 | } |
44 | 78 | ||
45 | const char* get_user_file_path(const char *path, | 79 | static bool try_path(const char* filename, unsigned flags) |
46 | unsigned flags, | 80 | { |
47 | char* buf, | 81 | if (flags & IS_FILE) |
48 | const size_t bufsize) | 82 | { |
83 | if (file_exists(filename)) | ||
84 | return true; | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | if (dir_exists(filename)) | ||
89 | return true; | ||
90 | } | ||
91 | return false; | ||
92 | } | ||
93 | |||
94 | static const char* _get_user_file_path(const char *path, | ||
95 | unsigned flags, | ||
96 | char* buf, | ||
97 | const size_t bufsize) | ||
49 | { | 98 | { |
50 | const char *ret = path; | 99 | const char *ret = path; |
51 | const char *pos = path; | 100 | const char *pos = path; |
52 | printf("%s(): looking for %s\n", __func__, path); | ||
53 | /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */ | 101 | /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */ |
54 | pos += ROCKBOX_DIR_LEN; | 102 | pos += ROCKBOX_DIR_LEN; |
55 | if (*pos == '/') pos += 1; | 103 | if (*pos == '/') pos += 1; |
@@ -66,27 +114,99 @@ const char* get_user_file_path(const char *path, | |||
66 | * write access is needed */ | 114 | * write access is needed */ |
67 | if (flags & NEED_WRITE) | 115 | if (flags & NEED_WRITE) |
68 | ret = buf; | 116 | ret = buf; |
69 | else | 117 | else if (try_path(buf, flags)) |
118 | ret = buf; | ||
119 | |||
120 | if (ret != buf) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */ | ||
70 | { | 121 | { |
71 | if (flags & IS_FILE) | 122 | if (snprintf(buf, bufsize, ROCKBOX_SHARE_PATH "/%s", pos) >= (int)bufsize) |
72 | { | 123 | return NULL; |
73 | if (file_exists(buf)) | 124 | |
74 | ret = buf; | 125 | if (try_path(buf, flags)) |
75 | } | 126 | ret = buf; |
76 | else | ||
77 | { | ||
78 | if (dir_exists(buf)) | ||
79 | ret = buf; | ||
80 | } | ||
81 | } | 127 | } |
82 | 128 | ||
83 | /* make a copy if we're about to return the path*/ | 129 | return ret; |
84 | if (UNLIKELY((flags & FORCE_BUFFER_COPY) && (ret != buf))) | 130 | } |
131 | |||
132 | int app_open(const char *name, int o, ...) | ||
133 | { | ||
134 | char realpath[MAX_PATH]; | ||
135 | va_list ap; | ||
136 | int fd; | ||
137 | |||
138 | if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN)) | ||
85 | { | 139 | { |
86 | strlcpy(buf, ret, bufsize); | 140 | int flags = IS_FILE; |
87 | ret = buf; | 141 | if (o & (O_CREAT|O_RDWR|O_TRUNC|O_WRONLY)) |
142 | flags |= NEED_WRITE; | ||
143 | name = _get_user_file_path(name, flags, realpath, sizeof(realpath)); | ||
88 | } | 144 | } |
145 | va_start(ap, o); | ||
146 | fd = open(name, o, ap); | ||
147 | va_end(ap); | ||
148 | |||
149 | return fd; | ||
150 | |||
151 | } | ||
89 | 152 | ||
90 | printf("%s(): %s\n", __func__, ret); | 153 | int app_creat(const char* name, mode_t mode) |
91 | return ret; | 154 | { |
155 | return app_open(name, O_CREAT|O_WRONLY|O_TRUNC, mode); | ||
92 | } | 156 | } |
157 | |||
158 | int app_remove(const char *name) | ||
159 | { | ||
160 | char realpath[MAX_PATH]; | ||
161 | const char *fname = name; | ||
162 | if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN)) | ||
163 | { | ||
164 | fname = _get_user_file_path(name, 0, realpath, sizeof(realpath)); | ||
165 | } | ||
166 | return remove(fname); | ||
167 | } | ||
168 | |||
169 | int app_rename(const char *old, const char *new) | ||
170 | { | ||
171 | char realpath[MAX_PATH]; | ||
172 | const char *fname = old; | ||
173 | if (!strncmp(ROCKBOX_DIR, old, ROCKBOX_DIR_LEN)) | ||
174 | { | ||
175 | fname = _get_user_file_path(old, 0, realpath, sizeof(realpath)); | ||
176 | } | ||
177 | return rename(fname, new); | ||
178 | } | ||
179 | |||
180 | DIR *app_opendir(const char *name) | ||
181 | { | ||
182 | char realpath[MAX_PATH]; | ||
183 | const char *fname = name; | ||
184 | if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN)) | ||
185 | { | ||
186 | fname = _get_user_file_path(name, 0, realpath, sizeof(realpath)); | ||
187 | } | ||
188 | return opendir(fname); | ||
189 | } | ||
190 | |||
191 | int app_mkdir(const char* name) | ||
192 | { | ||
193 | char realpath[MAX_PATH]; | ||
194 | const char *fname = name; | ||
195 | if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN)) | ||
196 | { | ||
197 | fname = _get_user_file_path(name, 0, realpath, sizeof(realpath)); | ||
198 | } | ||
199 | return mkdir(fname); | ||
200 | } | ||
201 | |||
202 | int app_rmdir(const char* name) | ||
203 | { | ||
204 | char realpath[MAX_PATH]; | ||
205 | const char *fname = name; | ||
206 | if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN)) | ||
207 | { | ||
208 | fname = _get_user_file_path(name, 0, realpath, sizeof(realpath)); | ||
209 | } | ||
210 | return rmdir(fname); | ||
211 | } | ||
212 | |||