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 */
28 #include "file.h" /* MAX_PATH */
30 #include "gcc_extensions.h"
31 #include "string-extra.h"
32 #include "filefuncs.h"
43 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
44 #include "dir-target.h"
45 #define opendir opendir_android
46 #define mkdir mkdir_android
47 #define rmdir rmdir_android
48 static const char rbhome
[] = "/sdcard";
49 #elif defined(SAMSUNG_YPR0)
50 #include "dir-target.h"
51 #define opendir opendir_ypr0
52 #define mkdir mkdir_ypr0
53 #define rmdir rmdir_ypr0
54 #elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
56 #define remove sim_remove
57 #define rename sim_rename
58 #define opendir sim_opendir
59 #define mkdir sim_mkdir
60 #define rmdir sim_rmdir
61 extern int sim_open(const char* name
, int o
, ...);
62 extern int sim_remove(const char* name
);
63 extern int sim_rename(const char* old
, const char* new);
64 extern DIR* sim_opendir(const char* name
);
65 extern int sim_mkdir(const char* name
);
66 extern int sim_rmdir(const char* name
);
70 #if !defined(SAMSUNG_YPR0)
72 /* flags for get_user_file_path() */
73 /* whether you need write access to that file/dir, especially true
74 * for runtime generated files (config.cfg) */
75 #define NEED_WRITE (1<<0)
76 /* file or directory? */
77 #define IS_FILE (1<<1)
81 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
82 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
83 mkdir("/sdcard/rockbox");
84 mkdir("/sdcard/rockbox/rocks.data");
86 char config_dir
[MAX_PATH
];
88 const char *home
= getenv("RBROOT");
91 home
= getenv("HOME");
95 logf("HOME environment var not set. Can't write config");
100 snprintf(config_dir
, sizeof(config_dir
), "%s/.config", home
);
102 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org", home
);
104 /* Plugin data directory */
105 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org/rocks.data", home
);
110 static bool try_path(const char* filename
, unsigned flags
)
114 if (file_exists(filename
))
119 if (dir_exists(filename
))
125 static const char* _get_user_file_path(const char *path
,
128 const size_t bufsize
)
130 const char *ret
= path
;
131 const char *pos
= path
;
132 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
133 pos
+= ROCKBOX_DIR_LEN
;
134 if (*pos
== '/') pos
+= 1;
136 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
137 if (snprintf(buf
, bufsize
, "/sdcard/rockbox/%s", pos
)
139 if (snprintf(buf
, bufsize
, "%s/.config/rockbox.org/%s", rbhome
, pos
)
144 /* always return the replacement buffer (pointing to $HOME) if
145 * write access is needed */
146 if (flags
& NEED_WRITE
)
148 else if (try_path(buf
, flags
))
151 if (ret
!= buf
) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */
153 if (snprintf(buf
, bufsize
, ROCKBOX_SHARE_PATH
"/%s", pos
) >= (int)bufsize
)
156 if (try_path(buf
, flags
))
164 static const char* handle_special_dirs(const char* dir
, unsigned flags
,
165 char *buf
, const size_t bufsize
)
167 if (!strncmp(HOME_DIR
, dir
, HOME_DIR_LEN
))
169 const char *p
= dir
+ HOME_DIR_LEN
;
170 while (*p
== '/') p
++;
171 snprintf(buf
, bufsize
, "%s/%s", rbhome
, p
);
174 else if (!strncmp(ROCKBOX_DIR
, dir
, ROCKBOX_DIR_LEN
))
175 return _get_user_file_path(dir
, flags
, buf
, bufsize
);
180 int app_open(const char *name
, int o
, ...)
182 char realpath
[MAX_PATH
];
186 if (o
& (O_CREAT
|O_RDWR
|O_TRUNC
|O_WRONLY
))
189 name
= handle_special_dirs(name
, flags
, realpath
, sizeof(realpath
));
192 fd
= open(name
, o
, va_arg(ap
, unsigned int));
198 int app_creat(const char* name
, mode_t mode
)
200 return app_open(name
, O_CREAT
|O_WRONLY
|O_TRUNC
, mode
);
203 int app_remove(const char *name
)
205 char realpath
[MAX_PATH
];
206 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
208 return remove(fname
);
211 int app_rename(const char *old
, const char *new)
213 char realpath_old
[MAX_PATH
], realpath_new
[MAX_PATH
];
214 const char *final_old
, *final_new
;
216 final_old
= handle_special_dirs(old
, NEED_WRITE
, realpath_old
, sizeof(realpath_old
));
217 final_new
= handle_special_dirs(new, NEED_WRITE
, realpath_new
, sizeof(realpath_new
));
219 return rename(final_old
, final_new
);
222 DIR *app_opendir(const char *name
)
224 char realpath
[MAX_PATH
];
225 const char *fname
= handle_special_dirs(name
, 0, realpath
, sizeof(realpath
));
226 return opendir(fname
);
229 int app_mkdir(const char* name
)
231 char realpath
[MAX_PATH
];
232 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
236 int app_rmdir(const char* name
)
238 char realpath
[MAX_PATH
];
239 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
245 int app_open(const char *name
, int o
, ...)
252 ret
= open(name
, o
, va_arg(ap
, mode_t
));
256 return open(name
, o
);
259 int app_creat(const char* name
, mode_t mode
) { return creat(name
, mode
); }
260 int app_remove(const char *name
) { return remove(name
); }
261 int app_rename(const char *old
, const char *new) { return rename(old
,new); }
262 DIR *app_opendir(const char *name
) { return opendir(name
); }
263 int app_mkdir(const char* name
) { return mkdir(name
); }
264 int app_rmdir(const char* name
) { return rmdir(name
); }