1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Thomas Martitz
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include <stdio.h> /* snprintf */
27 #include "file.h" /* MAX_PATH */
29 #include "gcc_extensions.h"
30 #include "string-extra.h"
31 #include "filefuncs.h"
41 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
42 #include "dir-target.h"
43 #define opendir opendir_android
44 #define mkdir mkdir_android
45 #define rmdir rmdir_android
46 #elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
48 #define remove sim_remove
49 #define rename sim_rename
50 #define opendir sim_opendir
51 #define mkdir sim_mkdir
52 #define rmdir sim_rmdir
53 extern int sim_open(const char* name
, int o
, ...);
54 extern int sim_remove(const char* name
);
55 extern int sim_rename(const char* old
, const char* new);
56 extern DIR* sim_opendir(const char* name
);
57 extern int sim_mkdir(const char* name
);
58 extern int sim_rmdir(const char* name
);
61 /* flags for get_user_file_path() */
62 /* whether you need write access to that file/dir, especially true
63 * for runtime generated files (config.cfg) */
64 #define NEED_WRITE (1<<0)
65 /* file or directory? */
66 #define IS_FILE (1<<1)
70 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
71 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
72 mkdir("/sdcard/rockbox");
73 mkdir("/sdcard/rockbox/rocks.data");
75 char config_dir
[MAX_PATH
];
77 const char *home
= getenv("HOME");
80 logf("HOME environment var not set. Can't write config");
84 snprintf(config_dir
, sizeof(config_dir
), "%s/.config", home
);
86 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org", home
);
88 /* Plugin data directory */
89 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org/rocks.data", home
);
94 static bool try_path(const char* filename
, unsigned flags
)
98 if (file_exists(filename
))
103 if (dir_exists(filename
))
109 static const char* _get_user_file_path(const char *path
,
112 const size_t bufsize
)
114 const char *ret
= path
;
115 const char *pos
= path
;
116 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
117 pos
+= ROCKBOX_DIR_LEN
;
118 if (*pos
== '/') pos
+= 1;
120 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
121 if (snprintf(buf
, bufsize
, "/sdcard/rockbox/%s", pos
)
123 if (snprintf(buf
, bufsize
, "%s/.config/rockbox.org/%s", getenv("HOME"), pos
)
128 /* always return the replacement buffer (pointing to $HOME) if
129 * write access is needed */
130 if (flags
& NEED_WRITE
)
132 else if (try_path(buf
, flags
))
135 if (ret
!= buf
) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */
137 if (snprintf(buf
, bufsize
, ROCKBOX_SHARE_PATH
"/%s", pos
) >= (int)bufsize
)
140 if (try_path(buf
, flags
))
147 int app_open(const char *name
, int o
, ...)
149 char realpath
[MAX_PATH
];
153 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
156 if (o
& (O_CREAT
|O_RDWR
|O_TRUNC
|O_WRONLY
))
158 name
= _get_user_file_path(name
, flags
, realpath
, sizeof(realpath
));
161 fd
= open(name
, o
, va_arg(ap
, unsigned int));
167 int app_creat(const char* name
, mode_t mode
)
169 return app_open(name
, O_CREAT
|O_WRONLY
|O_TRUNC
, mode
);
172 int app_remove(const char *name
)
174 char realpath
[MAX_PATH
];
175 const char *fname
= name
;
176 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
178 fname
= _get_user_file_path(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
181 return remove(fname
);
184 int app_rename(const char *old
, const char *new)
186 char realpath_old
[MAX_PATH
], realpath_new
[MAX_PATH
];
188 const char *final_old
= old
;
189 if (!strncmp(ROCKBOX_DIR
, old
, ROCKBOX_DIR_LEN
))
191 final_old
= _get_user_file_path(old
, NEED_WRITE
, realpath_old
, sizeof(realpath_old
));
194 const char *final_new
= new;
195 if (!strncmp(ROCKBOX_DIR
, new, ROCKBOX_DIR_LEN
))
197 final_new
= _get_user_file_path(new, NEED_WRITE
, realpath_new
, sizeof(realpath_new
));
200 return rename(final_old
, final_new
);
203 DIR *app_opendir(const char *name
)
205 char realpath
[MAX_PATH
];
206 const char *fname
= name
;
207 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
209 fname
= _get_user_file_path(name
, 0, realpath
, sizeof(realpath
));
211 return opendir(fname
);
214 int app_mkdir(const char* name
)
216 char realpath
[MAX_PATH
];
217 const char *fname
= name
;
218 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
220 fname
= _get_user_file_path(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
225 int app_rmdir(const char* name
)
227 char realpath
[MAX_PATH
];
228 const char *fname
= name
;
229 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
231 fname
= _get_user_file_path(name
, NEED_WRITE
, realpath
, sizeof(realpath
));