RaaA: Add initial Pandora support
[maemo-rb.git] / firmware / common / rbpaths.c
blobcb56ab4845668d7c5fe10da0b5c4f9467a9ebd47
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 #else
74 char config_dir[MAX_PATH];
76 const char *home = getenv("HOME");
77 if (!home)
79 logf("HOME environment var not set. Can't write config");
80 return;
83 snprintf(config_dir, sizeof(config_dir), "%s/.config", home);
84 mkdir(config_dir);
85 snprintf(config_dir, sizeof(config_dir), "%s/.config/rockbox.org", home);
86 mkdir(config_dir);
87 #endif
90 static bool try_path(const char* filename, unsigned flags)
92 if (flags & IS_FILE)
94 if (file_exists(filename))
95 return true;
97 else
99 if (dir_exists(filename))
100 return true;
102 return false;
105 static const char* _get_user_file_path(const char *path,
106 unsigned flags,
107 char* buf,
108 const size_t bufsize)
110 const char *ret = path;
111 const char *pos = path;
112 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
113 pos += ROCKBOX_DIR_LEN;
114 if (*pos == '/') pos += 1;
116 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
117 if (snprintf(buf, bufsize, "/sdcard/rockbox/%s", pos)
118 #else
119 if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos)
120 #endif
121 >= (int)bufsize)
122 return NULL;
124 /* always return the replacement buffer (pointing to $HOME) if
125 * write access is needed */
126 if (flags & NEED_WRITE)
127 ret = buf;
128 else if (try_path(buf, flags))
129 ret = buf;
131 if (ret != buf) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */
133 if (snprintf(buf, bufsize, ROCKBOX_SHARE_PATH "/%s", pos) >= (int)bufsize)
134 return NULL;
136 if (try_path(buf, flags))
137 ret = buf;
140 return ret;
143 int app_open(const char *name, int o, ...)
145 char realpath[MAX_PATH];
146 va_list ap;
147 int fd;
149 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
151 int flags = IS_FILE;
152 if (o & (O_CREAT|O_RDWR|O_TRUNC|O_WRONLY))
153 flags |= NEED_WRITE;
154 name = _get_user_file_path(name, flags, realpath, sizeof(realpath));
156 va_start(ap, o);
157 fd = open(name, o, va_arg(ap, unsigned int));
158 va_end(ap);
160 return fd;
163 int app_creat(const char* name, mode_t mode)
165 return app_open(name, O_CREAT|O_WRONLY|O_TRUNC, mode);
168 int app_remove(const char *name)
170 char realpath[MAX_PATH];
171 const char *fname = name;
172 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
174 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
177 return remove(fname);
180 int app_rename(const char *old, const char *new)
182 char realpath_old[MAX_PATH], realpath_new[MAX_PATH];
184 const char *final_old = old;
185 if (!strncmp(ROCKBOX_DIR, old, ROCKBOX_DIR_LEN))
187 final_old = _get_user_file_path(old, NEED_WRITE, realpath_old, sizeof(realpath_old));
190 const char *final_new = new;
191 if (!strncmp(ROCKBOX_DIR, new, ROCKBOX_DIR_LEN))
193 final_new = _get_user_file_path(new, NEED_WRITE, realpath_new, sizeof(realpath_new));
196 return rename(final_old, final_new);
199 DIR *app_opendir(const char *name)
201 char realpath[MAX_PATH];
202 const char *fname = name;
203 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
205 fname = _get_user_file_path(name, 0, realpath, sizeof(realpath));
207 return opendir(fname);
210 int app_mkdir(const char* name)
212 char realpath[MAX_PATH];
213 const char *fname = name;
214 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
216 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
218 return mkdir(fname);
221 int app_rmdir(const char* name)
223 char realpath[MAX_PATH];
224 const char *fname = name;
225 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
227 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
229 return rmdir(fname);