summaryrefslogtreecommitdiff
path: root/firmware/common/rbpaths.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/rbpaths.c')
-rw-r--r--firmware/common/rbpaths.c166
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
52extern int sim_open(const char* name, int o, ...);
53extern int sim_remove(const char* name);
54extern int sim_rename(const char* old, const char* new);
55extern DIR* sim_opendir(const char* name);
56extern int sim_mkdir(const char* name);
57extern 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
33void paths_init(void) 67void paths_init(void)
34{ 68{
@@ -42,14 +76,28 @@ void paths_init(void)
42#endif 76#endif
43} 77}
44 78
45const char* get_user_file_path(const char *path, 79static 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
94static 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
132int 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); 153int 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
158int 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
169int 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
180DIR *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
191int 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
202int 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