RaaA: Fix database duplication issue on every start
[kugel-rb.git] / firmware / common / rbpaths.c
blob2d3c1e6603ac5bc6d13d1ce419b8044f252abdcd
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 "gcc_extensions.h"
29 #include "string-extra.h"
30 #include "filefuncs.h"
32 #undef open
33 #undef creat
34 #undef remove
35 #undef rename
36 #undef opendir
37 #undef mkdir
38 #undef rmdir
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
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)
67 void paths_init(void)
69 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
70 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
71 mkdir("/sdcard/rockbox");
72 #else
73 char home_path[MAX_PATH];
74 snprintf(home_path, sizeof(home_path), "%s/.config/rockbox.org", getenv("HOME"));
75 mkdir(home_path);
76 #endif
79 static bool try_path(const char* filename, unsigned flags)
81 if (flags & IS_FILE)
83 if (file_exists(filename))
84 return true;
86 else
88 if (dir_exists(filename))
89 return true;
91 return false;
94 static const char* _get_user_file_path(const char *path,
95 unsigned flags,
96 char* buf,
97 const size_t bufsize)
99 const char *ret = path;
100 const char *pos = path;
101 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
102 pos += ROCKBOX_DIR_LEN;
103 if (*pos == '/') pos += 1;
105 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
106 if (snprintf(buf, bufsize, "/sdcard/rockbox/%s", pos)
107 #else
108 if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos)
109 #endif
110 >= (int)bufsize)
111 return NULL;
113 /* always return the replacement buffer (pointing to $HOME) if
114 * write access is needed */
115 if (flags & NEED_WRITE)
116 ret = buf;
117 else if (try_path(buf, flags))
118 ret = buf;
120 if (ret != buf) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */
122 if (snprintf(buf, bufsize, ROCKBOX_SHARE_PATH "/%s", pos) >= (int)bufsize)
123 return NULL;
125 if (try_path(buf, flags))
126 ret = buf;
129 return ret;
132 int app_open(const char *name, int o, ...)
134 char realpath[MAX_PATH];
135 va_list ap;
136 int fd;
138 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
140 int flags = IS_FILE;
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));
145 va_start(ap, o);
146 fd = open(name, o, va_arg(ap, unsigned int));
147 va_end(ap);
149 return fd;
152 int app_creat(const char* name, mode_t mode)
154 return app_open(name, O_CREAT|O_WRONLY|O_TRUNC, mode);
157 int app_remove(const char *name)
159 char realpath[MAX_PATH];
160 const char *fname = name;
161 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
163 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
166 return remove(fname);
169 int app_rename(const char *old, const char *new)
171 char realpath[MAX_PATH];
172 const char *fname = old;
173 if (!strncmp(ROCKBOX_DIR, old, ROCKBOX_DIR_LEN))
175 fname = _get_user_file_path(old, NEED_WRITE, realpath, sizeof(realpath));
177 return rename(fname, new);
180 DIR *app_opendir(const char *name)
182 char realpath[MAX_PATH];
183 const char *fname = name;
184 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
186 fname = _get_user_file_path(name, 0, realpath, sizeof(realpath));
188 return opendir(fname);
191 int app_mkdir(const char* name)
193 char realpath[MAX_PATH];
194 const char *fname = name;
195 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
197 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
199 return mkdir(fname);
202 int app_rmdir(const char* name)
204 char realpath[MAX_PATH];
205 const char *fname = name;
206 if (!strncmp(ROCKBOX_DIR, name, ROCKBOX_DIR_LEN))
208 fname = _get_user_file_path(name, NEED_WRITE, realpath, sizeof(realpath));
210 return rmdir(fname);