summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-01 16:15:27 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-01 16:15:27 +0000
commit9c0b2479f7025a84444adf08e3be8ced60dad013 (patch)
treef3d328dd73f46d599f0432cc43ae206798cbe4f6 /firmware
parent2e7d92fef707a2cd30820fd0053c539c3ac8e2b3 (diff)
downloadrockbox-9c0b2479f7025a84444adf08e3be8ced60dad013.tar.gz
rockbox-9c0b2479f7025a84444adf08e3be8ced60dad013.tar.bz2
rockbox-9c0b2479f7025a84444adf08e3be8ced60dad013.zip
Rockbox as an application: add get_user_file_path().
For RaaA it evaluates user paths at runtime. For everything but codecs/plugins it will give the path under $HOME/.config/rockbox.org if write access is needed or if the file/folder in question exists there (otherwise it gives /usr/local/share/rockbox). This allows for installing themes under $HOME as well as having config.cfg and other important files there while installing the application (and default themes) under /usr/local. On the DAPs it's a no-op, returing /.rockbox directly. Not converted to use get_user_file_path() are plugins themselves, because RaaA doesn't build plugins yet. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27656 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/common/dircache.c11
-rw-r--r--firmware/common/filefuncs.c37
-rw-r--r--firmware/common/rbpaths.c84
-rw-r--r--firmware/common/unicode.c4
-rw-r--r--firmware/export/filefuncs.h5
-rw-r--r--firmware/export/rbpaths.h132
-rw-r--r--firmware/font.c20
-rw-r--r--firmware/include/dircache.h1
-rw-r--r--firmware/include/file.h5
10 files changed, 284 insertions, 18 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b4f5301a84..d8cfadef11 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -105,6 +105,9 @@ common/dircache.c
#endif /* HAVE_DIRCACHE */
common/filefuncs.c
common/format.c
+#ifdef APPLICATION
+common/rbpaths.c
+#endif
common/strcasecmp.c
common/strcasestr.c
common/strnatcmp.c
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 906527f8f2..7b2cdd1d75 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -88,10 +88,13 @@ static int fdbind_idx = 0;
*/
static int open_dircache_file(unsigned flags, int permissions)
{
+ char path[MAX_PATH];
+ const char *file = get_user_file_path(DIRCACHE_FILE, IS_FILE|NEED_WRITE,
+ path, sizeof(path));
if (permissions != 0)
- return open(DIRCACHE_FILE, flags, permissions);
+ return open(file, flags, permissions);
- return open(DIRCACHE_FILE, flags);
+ return open(file, flags);
}
/**
@@ -99,7 +102,9 @@ static int open_dircache_file(unsigned flags, int permissions)
*/
static int remove_dircache_file(void)
{
- return remove(DIRCACHE_FILE);
+ char path[MAX_PATH];
+ return remove(get_user_file_path(DIRCACHE_FILE, IS_FILE|NEED_WRITE,
+ path, sizeof(path)));
}
#endif
/**
diff --git a/firmware/common/filefuncs.c b/firmware/common/filefuncs.c
index ca9113250a..c058267094 100644
--- a/firmware/common/filefuncs.c
+++ b/firmware/common/filefuncs.c
@@ -22,6 +22,7 @@
#include "dir.h"
#include "stdlib.h"
#include "string.h"
+#include "debug.h"
#ifdef HAVE_MULTIVOLUME
/* returns on which volume this is, and copies the reduced name
@@ -50,3 +51,39 @@ int strip_volume(const char* name, char* namecopy)
return volume;
}
#endif /* #ifdef HAVE_MULTIVOLUME */
+
+#ifndef __PCTOOL__
+/* Test file existence, using dircache of possible */
+bool file_exists(const char *file)
+{
+ int fd;
+
+#ifdef DEBUG
+ if (!file || strlen(file) <= 0)
+ {
+ DEBUGF("%s(): Invalid parameter!\n");
+ return false;
+ }
+#endif
+
+#ifdef HAVE_DIRCACHE
+ if (dircache_is_enabled())
+ return (dircache_get_entry_ptr(file) != NULL);
+#endif
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ return false;
+ close(fd);
+ return true;
+}
+
+bool dir_exists(const char *path)
+{
+ DIR* d = opendir(path);
+ if (!d)
+ return false;
+ closedir(d);
+ return true;
+}
+#endif /* __PCTOOL__ */
diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c
new file mode 100644
index 0000000000..69bc1387ef
--- /dev/null
+++ b/firmware/common/rbpaths.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+
+#include <stdio.h> /* snprintf */
+#include <stdlib.h>
+#include "rbpaths.h"
+#include "file.h" /* MAX_PATH */
+#include "dir.h"
+#include "gcc_extensions.h"
+#include "string-extra.h"
+#include "filefuncs.h"
+
+
+void paths_init(void)
+{
+ /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
+ char home_path[MAX_PATH];
+ snprintf(home_path, sizeof(home_path), "%s/.config/rockbox.org", getenv("HOME"));
+ mkdir(home_path);
+}
+
+const char* get_user_file_path(const char *path,
+ unsigned flags,
+ char* buf,
+ const size_t bufsize)
+{
+ const char *ret = path;
+ const char *pos = path;
+ printf("%s(): looking for %s\n", __func__, path);
+ /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
+ pos += ROCKBOX_DIR_LEN;
+ if (*pos == '/') pos += 1;
+
+ if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos)
+ >= (int)bufsize)
+ return NULL;
+
+ /* always return the replacement buffer (pointing to $HOME) if
+ * write access is needed */
+ if (flags & NEED_WRITE)
+ ret = buf;
+ else
+ {
+ if (flags & IS_FILE)
+ {
+ if (file_exists(buf))
+ ret = buf;
+ }
+ else
+ {
+ if (dir_exists(buf))
+ ret = buf;
+ }
+ }
+
+ /* make a copy if we're about to return the path*/
+ if (UNLIKELY((flags & FORCE_BUFFER_COPY) && (ret != buf)))
+ {
+ strlcpy(buf, ret, bufsize);
+ ret = buf;
+ }
+
+ printf("%s(): %s\n", __func__, ret);
+ return ret;
+}
diff --git a/firmware/common/unicode.c b/firmware/common/unicode.c
index 4ef6eaae2b..25d4a9129e 100644
--- a/firmware/common/unicode.c
+++ b/firmware/common/unicode.c
@@ -27,16 +27,16 @@
*/
#include <stdio.h>
+#include "config.h"
#include "file.h"
#include "debug.h"
#include "rbunicode.h"
-#include "config.h"
+#include "rbpaths.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
-#define CODEPAGE_DIR ROCKBOX_DIR"/codepages"
static int default_codepage = 0;
static int loaded_cp_table = 0;
diff --git a/firmware/export/filefuncs.h b/firmware/export/filefuncs.h
index 130c5ff4be..3745c6bee3 100644
--- a/firmware/export/filefuncs.h
+++ b/firmware/export/filefuncs.h
@@ -28,4 +28,9 @@
int strip_volume(const char* name, char* namecopy);
#endif
+#ifndef __PCTOOL__
+bool file_exists(const char *file);
+bool dir_exists(const char *path);
+#endif
+
#endif /* __INCLUDE_FILEFUNCS_H_ */
diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h
new file mode 100644
index 0000000000..cd87888cef
--- /dev/null
+++ b/firmware/export/rbpaths.h
@@ -0,0 +1,132 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef __PATHS_H__
+#define __PATHS_H__
+
+#include <stdbool.h>
+#include "autoconf.h"
+#include "string-extra.h"
+
+/* flags for get_user_file_path() */
+/* whether you need write access to that file/dir, especially true
+ * for runtime generated files (config.cfg) */
+#define NEED_WRITE (1<<0)
+/* file or directory? */
+#define IS_FILE (1<<1)
+/* make sure the path is copied into the passed buffer (it may return
+ * the passed path directly otherwise, e.g. always on target builds) */
+#define FORCE_BUFFER_COPY (1<<2)
+
+
+
+/* name of directory where configuration, fonts and other data
+ * files are stored */
+#ifdef __PCTOOL__
+#undef ROCKBOX_DIR
+#undef ROCKBOX_DIR_LEN
+#undef WPS_DIR
+#define ROCKBOX_DIR "."
+#define ROCKBOX_DIR_LEN 1
+#else
+
+/* ROCKBOX_DIR is now defined in autoconf.h for flexible build types */
+#ifndef ROCKBOX_DIR
+#error ROCKBOX_DIR not defined (should be in autoconf.h)
+#endif
+#define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1)
+#endif /* def __PCTOOL__ */
+
+#ifndef APPLICATION
+
+/* make sure both are the same for native builds */
+#undef ROCKBOX_LIBRARY_PATH
+#define ROCKBOX_LIBRARY_PATH ROCKBOX_DIR
+
+#define PLUGIN_DIR ROCKBOX_DIR "/rocks"
+#define CODECS_DIR ROCKBOX_DIR "/codecs"
+
+#define REC_BASE_DIR "/"
+#define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists"
+
+#ifndef PLUGIN
+static inline __attribute__((always_inline)) const char* get_user_file_path(const char *path,
+ unsigned flags,
+ char* buf,
+ const size_t bufsize)
+{
+ if (flags & FORCE_BUFFER_COPY)
+ {
+ strlcpy(buf, path, bufsize);
+ return buf;
+ }
+ return path;
+}
+#endif
+
+#define paths_init()
+#else /* application */
+
+#define PLUGIN_DIR ROCKBOX_LIBRARY_PATH "/rockbox/rocks"
+#define CODECS_DIR ROCKBOX_LIBRARY_PATH "/rockbox/codecs"
+
+#define REC_BASE_DIR ROCKBOX_DIR "/"
+#define PLAYLIST_CATALOG_DEFAULT_DIR ROCKBOX_DIR "/Playlists"
+
+extern void paths_init(void);
+extern const char* get_user_file_path(const char *path,
+ unsigned flags,
+ char* buf,
+ const size_t bufsize);
+#endif /* APPLICATION */
+
+#define LANG_DIR ROCKBOX_DIR "/langs"
+
+#define PLUGIN_GAMES_DIR PLUGIN_DIR "/games"
+#define PLUGIN_APPS_DIR PLUGIN_DIR "/apps"
+#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos"
+#define VIEWERS_DIR PLUGIN_DIR "/viewers"
+
+
+#define WPS_DIR ROCKBOX_DIR "/wps"
+#define SBS_DIR WPS_DIR
+#define THEME_DIR ROCKBOX_DIR "/themes"
+#define FONT_DIR ROCKBOX_DIR "/fonts"
+#define ICON_DIR ROCKBOX_DIR "/icons"
+
+#define BACKDROP_DIR ROCKBOX_DIR "/backdrops"
+#define EQS_DIR ROCKBOX_DIR "/eqs"
+
+/* need to fix this once the application gets record/radio abilities */
+#define RECPRESETS_DIR ROCKBOX_DIR "/recpresets"
+#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
+
+#define DIRCACHE_FILE ROCKBOX_DIR "/dircache.dat"
+#define CODEPAGE_DIR ROCKBOX_DIR "/codepages"
+
+#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
+#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
+#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
+
+#define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control"
+#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
+#define GLYPH_CACHE_FILE ROCKBOX_DIR "/.glyphcache"
+#endif /* __PATHS_H__ */
diff --git a/firmware/font.c b/firmware/font.c
index f1584713ed..b8ad76ec3a 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -36,6 +36,7 @@
#include "panic.h"
#include "rbunicode.h"
#include "diacritic.h"
+#include "rbpaths.h"
#define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB
@@ -56,7 +57,6 @@
#define FONT_HEADER_SIZE 36
#endif
-#define GLYPH_CACHE_FILE ROCKBOX_DIR"/.glyphcache"
#ifndef BOOTLOADER
/* Font cache includes */
@@ -606,12 +606,13 @@ void glyph_cache_save(struct font* pf)
pf = &font_ui;
if (pf->fd >= 0 && pf == &font_ui)
{
-#ifdef WPSEDITOR
- cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
-#else
- cache_fd = creat(GLYPH_CACHE_FILE, 0666);
-#endif
- if (cache_fd < 0) return;
+ char path[MAX_PATH];
+ const char *file = get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE,
+ path, sizeof(path));
+
+ cache_fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (cache_fd < 0)
+ return;
lru_traverse(&pf->cache._lru, glyph_file_write);
@@ -630,9 +631,10 @@ static void glyph_cache_load(struct font* pf)
int fd;
unsigned char tmp[2];
unsigned short ch;
+ char path[MAX_PATH];
- fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
-
+ fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE,
+ path, sizeof(path)), O_RDONLY|O_BINARY);
if (fd >= 0) {
while (read(fd, tmp, 2) == 2) {
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 4472d5fbe0..650b92632d 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -27,7 +27,6 @@
#define DIRCACHE_RESERVE (1024*64)
#define DIRCACHE_LIMIT (1024*1024*6)
-#define DIRCACHE_FILE ROCKBOX_DIR"/dircache.dat"
#define DIRCACHE_APPFLAG_TAGCACHE 0x0001
diff --git a/firmware/include/file.h b/firmware/include/file.h
index 91b701d6d2..a9d1d05a11 100644
--- a/firmware/include/file.h
+++ b/firmware/include/file.h
@@ -22,13 +22,12 @@
#ifndef _FILE_H_
#define _FILE_H_
-#undef MAX_PATH /* this avoids problems when building simulator */
-#define MAX_PATH 260
-
#include <sys/types.h>
#include "config.h"
#include "gcc_extensions.h"
+#undef MAX_PATH /* this avoids problems when building simulator */
+#define MAX_PATH 260
#define MAX_OPEN_FILES 11
#ifndef SEEK_SET