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) || defined(SAMSUNG_YPR0) && !defined(__PCTOOL__)
44 #include "dir-target.h"
45 #define opendir _opendir
47 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
48 static const char rbhome
[] = "/sdcard";
50 #elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA)) && !defined(__PCTOOL__)
52 #define remove sim_remove
53 #define rename sim_rename
54 #define opendir sim_opendir
55 #define mkdir sim_mkdir
56 #define rmdir sim_rmdir
57 extern int sim_open(const char* name
, int o
, ...);
58 extern int sim_remove(const char* name
);
59 extern int sim_rename(const char* old
, const char* new);
60 extern DIR* sim_opendir(const char* name
);
61 extern int sim_mkdir(const char* name
);
62 extern int sim_rmdir(const char* name
);
66 #if !defined(SAMSUNG_YPR0) && !defined(__PCTOOL__)
68 /* flags for get_user_file_path() */
69 /* whether you need write access to that file/dir, especially true
70 * for runtime generated files (config.cfg) */
71 #define NEED_WRITE (1<<0)
72 /* file or directory? */
73 #define IS_FILE (1<<1)
77 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
78 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
79 mkdir("/sdcard/rockbox");
80 mkdir("/sdcard/rockbox/rocks.data");
82 char config_dir
[MAX_PATH
];
84 const char *home
= getenv("RBROOT");
87 home
= getenv("HOME");
91 logf("HOME environment var not set. Can't write config");
96 snprintf(config_dir
, sizeof(config_dir
), "%s/.config", home
);
98 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org", home
);
100 /* Plugin data directory */
101 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org/rocks.data", home
);
106 static bool try_path(const char* filename
, unsigned flags
)
110 if (file_exists(filename
))
115 if (dir_exists(filename
))
121 static const char* _get_user_file_path(const char *path
,
124 const size_t bufsize
)
126 const char *ret
= path
;
127 const char *pos
= path
;
128 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
129 pos
+= ROCKBOX_DIR_LEN
;
130 if (*pos
== '/') pos
+= 1;
132 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
133 if (snprintf(buf
, bufsize
, "/sdcard/rockbox/%s", pos
)
135 if (snprintf(buf
, bufsize
, "%s/.config/rockbox.org/%s", rbhome
, pos
)
140 /* always return the replacement buffer (pointing to $HOME) if
141 * write access is needed */
142 if (flags
& NEED_WRITE
)
144 else if (try_path(buf
, flags
))
147 if (ret
!= buf
) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */
149 if (snprintf(buf
, bufsize
, ROCKBOX_SHARE_PATH
"/%s", pos
) >= (int)bufsize
)
152 if (try_path(buf
, flags
))
160 static const char* handle_special_dirs(const char* dir
, unsigned flags
,
161 char *buf
, const size_t bufsize
)
163 if (!strncmp(HOME_DIR
, dir
, HOME_DIR_LEN
))
165 const char *p
= dir
+ HOME_DIR_LEN
;
166 while (*p
== '/') p
++;
167 snprintf(buf
, bufsize
, "%s/%s", rbhome
, p
);
170 else if (!strncmp(ROCKBOX_DIR
, dir
, ROCKBOX_DIR_LEN
))
171 return _get_user_file_path(dir
, flags
, buf
, bufsize
);
176 int app_open(const char *name
, int o
, ...)
178 char realpath
[MAX_PATH
];
182 if (o
& (O_CREAT
|O_RDWR
|O_TRUNC
|O_WRONLY
))
185 name
= handle_special_dirs(name
, flags
, realpath
, sizeof(realpath
));
188 fd
= open(name
, o
, va_arg(ap
, unsigned int));
194 int app_creat(const char* name
, mode_t mode
)
196 return app_open(name
, O_CREAT
|O_WRONLY
|O_TRUNC
, mode
);
199 int app_remove(const char *name
)
201 char realpath
[MAX_PATH
];
202 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
204 return remove(fname
);
207 int app_rename(const char *old
, const char *new)
209 char realpath_old
[MAX_PATH
], realpath_new
[MAX_PATH
];
210 const char *final_old
, *final_new
;
212 final_old
= handle_special_dirs(old
, NEED_WRITE
, realpath_old
, sizeof(realpath_old
));
213 final_new
= handle_special_dirs(new, NEED_WRITE
, realpath_new
, sizeof(realpath_new
));
215 return rename(final_old
, final_new
);
218 DIR *app_opendir(const char *name
)
220 char realpath
[MAX_PATH
];
221 const char *fname
= handle_special_dirs(name
, 0, realpath
, sizeof(realpath
));
222 return opendir(fname
);
225 int app_mkdir(const char* name
)
227 char realpath
[MAX_PATH
];
228 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
232 int app_rmdir(const char* name
)
234 char realpath
[MAX_PATH
];
235 const char *fname
= handle_special_dirs(name
, NEED_WRITE
, realpath
, sizeof(realpath
));
241 int app_open(const char *name
, int o
, ...)
248 ret
= open(name
, o
, va_arg(ap
, mode_t
));
252 return open(name
, o
);
255 int app_creat(const char* name
, mode_t mode
) { return creat(name
, mode
); }
256 int app_remove(const char *name
) { return remove(name
); }
257 int app_rename(const char *old
, const char *new) { return rename(old
,new); }
258 DIR *app_opendir(const char *name
) { return (DIR*)opendir(name
); } /* cast to remove warning in checkwps */
259 int app_mkdir(const char* name
) { return mkdir(name
); }
260 int app_rmdir(const char* name
) { return rmdir(name
); }