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 */
27 #include "file.h" /* MAX_PATH */
29 #include "gcc_extensions.h"
30 #include "string-extra.h"
31 #include "filefuncs.h"
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))
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
);
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)
70 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
71 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
72 mkdir("/sdcard/rockbox");
74 char config_dir
[MAX_PATH
];
76 const char *home
= getenv("HOME");
79 logf("HOME environment var not set. Can't write config");
83 snprintf(config_dir
, sizeof(config_dir
), "%s/.config", home
);
85 snprintf(config_dir
, sizeof(config_dir
), "%s/.config/rockbox.org", home
);
90 static bool try_path(const char* filename
, unsigned flags
)
94 if (file_exists(filename
))
99 if (dir_exists(filename
))
105 static const char* _get_user_file_path(const char *path
,
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
)
119 if (snprintf(buf
, bufsize
, "%s/.config/rockbox.org/%s", getenv("HOME"), pos
)
124 /* always return the replacement buffer (pointing to $HOME) if
125 * write access is needed */
126 if (flags
& NEED_WRITE
)
128 else if (try_path(buf
, flags
))
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
)
136 if (try_path(buf
, flags
))
143 int app_open(const char *name
, int o
, ...)
145 char realpath
[MAX_PATH
];
149 if (!strncmp(ROCKBOX_DIR
, name
, ROCKBOX_DIR_LEN
))
152 if (o
& (O_CREAT
|O_RDWR
|O_TRUNC
|O_WRONLY
))
154 name
= _get_user_file_path(name
, flags
, realpath
, sizeof(realpath
));
157 fd
= open(name
, o
, va_arg(ap
, unsigned int));
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
));
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
));