RaaA: Fix write locations of plugins
[maemo-rb.git] / firmware / common / rbpaths.c
blob1bbed97d21095a48a997753d86b1c5c790ee6f00
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 */
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include "rbpaths.h"
27 #include "file.h" /* MAX_PATH */
28 #include "logf.h"
29 #include "gcc_extensions.h"
30 #include "string-extra.h"
31 #include "filefuncs.h"
33 #undef open
34 #undef creat
35 #undef remove
36 #undef rename
37 #undef opendir
38 #undef mkdir
39 #undef rmdir
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))
47 #define open sim_open
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);
59 #endif
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)
68 void paths_init(void)
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");
74 #else
75 char config_dir[MAX_PATH];
77 const char *home = getenv("HOME");
78 if (!home)
80 logf("HOME environment var not set. Can't write config");
81 return;
84 snprintf(config_dir, sizeof(config_dir), "%s/.config", home);
85 mkdir(config_dir);
86 snprintf(config_dir, sizeof(config_dir), "%s/.config/rockbox.org", home);
87 mkdir(config_dir);
88 /* Plugin data directory */
89 snprintf(config_dir, sizeof(config_dir), "%s/.config/rockbox.org/rocks.data", home);
90 mkdir(config_dir);
91 #endif
94 static bool try_path(const char* filename, unsigned flags)
96 if (flags & IS_FILE)
98 if (file_exists(filename))
99 return true;
101 else
103 if (dir_exists(filename))
104 return true;
106 return false;
109 static const char* _get_user_file_path(const char *path,
110 unsigned flags,
111 char* buf,
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)
122 #else
123 if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos)
124 #endif
125 >= (int)bufsize)
126 return NULL;
128 /* always return the replacement buffer (pointing to $HOME) if
129 * write access is needed */
130 if (flags & NEED_WRITE)
131 ret = buf;
132 else if (try_path(buf, flags))
133 ret = buf;
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)
138 return NULL;
140 if (try_path(buf, flags))
141 ret = buf;
144 return ret;
147 int app_open(const char *name, int o, ...)
149 char realpath[MAX_PATH];
150 va_list ap;
151 int fd;
153 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
155 int flags = IS_FILE;
156 if (o & (O_CREAT|O_RDWR|O_TRUNC|O_WRONLY))
157 flags |= NEED_WRITE;
158 name = _get_user_file_path(name, flags, realpath, sizeof(realpath));
160 va_start(ap, o);
161 fd = open(name, o, va_arg(ap, unsigned int));
162 va_end(ap);
164 return fd;
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));
222 return mkdir(fname);
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));
233 return rmdir(fname);