summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/settings.h6
-rw-r--r--apps/tagcache.c270
-rw-r--r--apps/tagcache.h9
-rw-r--r--firmware/common/dircache.c23
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/export/debug.h2
-rw-r--r--firmware/export/logf.h10
-rw-r--r--firmware/id3.c12
-rw-r--r--firmware/include/dir.h2
-rw-r--r--firmware/include/dircache.h2
-rw-r--r--firmware/logf.c17
-rw-r--r--firmware/mp3data.c5
-rw-r--r--tools/Makefile9
-rw-r--r--tools/database.c13
-rw-r--r--uisimulator/common/io.c53
15 files changed, 298 insertions, 137 deletions
diff --git a/apps/settings.h b/apps/settings.h
index 079fd29649..7b70ab748c 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -37,8 +37,14 @@
#include "backlight.h" /* for [MIN|MAX]_BRIGHTNESS_SETTING */
#endif
+#ifdef __PCTOOL__
+#define ROCKBOX_DIR "."
+#define ROCKBOX_DIR_LEN 1
+#else
#define ROCKBOX_DIR "/.rockbox"
#define ROCKBOX_DIR_LEN 9
+#endif
+
#define FONT_DIR ROCKBOX_DIR "/fonts"
#define LANG_DIR ROCKBOX_DIR "/langs"
#define WPS_DIR ROCKBOX_DIR "/wps"
diff --git a/apps/tagcache.c b/apps/tagcache.c
index d8684bd989..4739291aa8 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -61,26 +61,37 @@
#include "logf.h"
#include "string.h"
#include "usb.h"
-#include "dircache.h"
#include "metadata.h"
#include "id3.h"
-#include "settings.h"
-#include "splash.h"
-#include "lang.h"
#include "tagcache.h"
#include "buffer.h"
-#include "atoi.h"
#include "crc32.h"
-#include "eeprom_settings.h"
#include "misc.h"
+#include "settings.h"
+#include "dircache.h"
+#ifndef __PCTOOL__
+#include "atoi.h"
+#include "splash.h"
+#include "lang.h"
+#include "eeprom_settings.h"
+#endif
+#ifdef __PCTOOL__
+#include <ctype.h>
+#define yield() do { } while(0)
+#define sim_sleep(timeout) do { } while(0)
+#endif
+
+
+#ifndef __PCTOOL__
/* Tag Cache thread. */
static struct event_queue tagcache_queue;
static long tagcache_stack[(DEFAULT_STACK_SIZE + 0x4000)/sizeof(long)];
static const char tagcache_thread_name[] = "tagcache";
+#endif
/* Previous path when scanning directory tree recursively. */
-static char curpath[MAX_PATH*2];
+static char curpath[TAG_MAXLEN+32];
static long curpath_size = sizeof(curpath);
/* Used when removing duplicates. */
@@ -105,7 +116,7 @@ static const char *tags_str[] = { "artist", "album", "genre", "title",
"playcount", "playtime", "lastplayed" };
/* Status information of the tagcache. */
-static struct tagcache_stat stat;
+static struct tagcache_stat tc_stat;
/* Queue commands. */
enum tagcache_queue {
@@ -158,7 +169,7 @@ struct ramcache_header {
# ifdef HAVE_EEPROM_SETTINGS
struct statefile_header {
struct ramcache_header *hdr;
- struct tagcache_stat stat;
+ struct tagcache_stat tc_stat;
};
# endif
@@ -275,8 +286,8 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
fd = open(buf, write ? O_RDWR : O_RDONLY);
if (fd < 0)
{
- logf("tag file open failed: %d", tag);
- stat.ready = false;
+ logf("tag file open failed: tag=%d write=%d file=%s", tag, write, buf);
+ tc_stat.ready = false;
return fd;
}
@@ -285,7 +296,7 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
if (hdr->magic != TAGCACHE_MAGIC || rc != sizeof(struct tagcache_header))
{
logf("header error");
- stat.ready = false;
+ tc_stat.ready = false;
close(fd);
return -2;
}
@@ -302,7 +313,7 @@ static long find_entry_ram(const char *filename,
int i;
/* Check if we tagcache is loaded into ram. */
- if (!stat.ramcache)
+ if (!tc_stat.ramcache)
return -1;
if (dc == NULL)
@@ -355,11 +366,11 @@ static long find_entry_disk(const char *filename)
bool found = false;
struct tagfile_entry tfe;
int fd;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
int i;
int pos = -1;
- if (!stat.ready)
+ if (!tc_stat.ready)
return -2;
fd = filenametag_fd;
@@ -443,7 +454,7 @@ static int find_index(const char *filename)
long idx_id = -1;
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (stat.ramcache && dircache_is_enabled())
+ if (tc_stat.ramcache && dircache_is_enabled())
idx_id = find_entry_ram(filename, NULL);
#endif
@@ -457,7 +468,7 @@ bool tagcache_find_index(struct tagcache_search *tcs, const char *filename)
{
int idx_id;
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
idx_id = find_index(filename);
@@ -483,7 +494,7 @@ static bool get_index(int masterfd, int idxid,
}
#ifdef HAVE_TC_RAMCACHE
- if (stat.ramcache && use_ram)
+ if (tc_stat.ramcache && use_ram)
{
if (hdr->indices[idxid].flag & FLAG_DELETED)
return false;
@@ -520,7 +531,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx)
}
#ifdef HAVE_TC_RAMCACHE
- if (stat.ramcache)
+ if (tc_stat.ramcache)
{
memcpy(&hdr->indices[idxid], idx, sizeof(struct index_entry));
}
@@ -660,7 +671,7 @@ long tagcache_get_numeric(const struct tagcache_search *tcs, int tag)
{
struct index_entry idx;
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
if (!tagcache_is_numeric_tag(tag))
@@ -852,7 +863,7 @@ bool tagcache_check_clauses(struct tagcache_search *tcs,
return check_clauses(tcs, &idx, clause, count);
}
-static bool add_uniqbuf(struct tagcache_search *tcs, long id)
+static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id)
{
int i;
@@ -984,8 +995,8 @@ static void remove_files(void)
int i;
char buf[MAX_PATH];
- stat.ready = false;
- stat.ramcache = false;
+ tc_stat.ready = false;
+ tc_stat.ramcache = false;
remove(TAGCACHE_FILE_MASTER);
for (i = 0; i < TAG_COUNT; i++)
{
@@ -1007,7 +1018,7 @@ static int open_master_fd(struct master_header *hdr, bool write)
if (fd < 0)
{
logf("master file open failed for R/W");
- stat.ready = false;
+ tc_stat.ready = false;
return fd;
}
@@ -1016,7 +1027,7 @@ static int open_master_fd(struct master_header *hdr, bool write)
if (hdr->tch.magic != TAGCACHE_MAGIC || rc != sizeof(struct master_header))
{
logf("header error");
- stat.ready = false;
+ tc_stat.ready = false;
close(fd);
return -2;
}
@@ -1037,7 +1048,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
sleep(1);
memset(tcs, 0, sizeof(struct tagcache_search));
- if (stat.commit_step > 0 || !stat.ready)
+ if (tc_stat.commit_step > 0 || !tc_stat.ready)
return false;
tcs->position = sizeof(struct tagcache_header);
@@ -1053,7 +1064,7 @@ bool tagcache_search(struct tagcache_search *tcs, int tag)
#ifndef HAVE_TC_RAMCACHE
tcs->ramsearch = false;
#else
- tcs->ramsearch = stat.ramcache;
+ tcs->ramsearch = tc_stat.ramcache;
if (tcs->ramsearch)
{
tcs->entry_count = hdr->entry_count[tcs->type];
@@ -1146,11 +1157,11 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
static bool get_next(struct tagcache_search *tcs)
{
- static char buf[MAX_PATH];
+ static char buf[TAG_MAXLEN+32];
struct tagfile_entry entry;
long flag = 0;
- if (!tcs->valid || !stat.ready)
+ if (!tcs->valid || !tc_stat.ready)
return false;
if (tcs->idxfd[tcs->type] < 0 && !tagcache_is_numeric_tag(tcs->type)
@@ -1367,12 +1378,12 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
struct index_entry *entry;
int idx_id;
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
/* Find the corresponding entry in tagcache. */
idx_id = find_entry_ram(filename, NULL);
- if (idx_id < 0 || !stat.ramcache)
+ if (idx_id < 0 || !tc_stat.ramcache)
return false;
entry = &hdr->indices[idx_id];
@@ -1411,11 +1422,11 @@ static int check_if_empty(char **tag)
}
length = strlen(*tag);
- if (length >= MAX_PATH-32)
+ if (length > TAG_MAXLEN)
{
logf("over length tag: %s", *tag);
- *tag[MAX_PATH-32] = '\0';
- length = MAX_PATH-32;
+ length = TAG_MAXLEN;
+ *tag[length] = '\0';
}
return length + 1;
@@ -1440,17 +1451,26 @@ static void add_tagcache(char *path)
char tracknumfix[3];
char *genrestr;
int offset = 0;
+ int path_length = strlen(path);
if (cachefd < 0)
return ;
+ /* Check for overlength file path. */
+ if (path_length > TAG_MAXLEN)
+ {
+ /* Path can't be shortened. */
+ logf("Too long path: %s");
+ return ;
+ }
+
/* Check if the file is supported. */
if (probe_file_format(path) == AFMT_UNKNOWN)
return ;
/* Check if the file is already cached. */
#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (stat.ramcache && dircache_is_enabled())
+ if (tc_stat.ramcache && dircache_is_enabled())
{
if (find_entry_ram(path, dc) >= 0)
return ;
@@ -1552,7 +1572,7 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique)
int i;
unsigned crc32;
unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4];
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
for (i = 0; str[i] != '\0' && i < (int)sizeof(buf)-1; i++)
buf[i] = tolower(str[i]);
@@ -1628,7 +1648,7 @@ static int compare(const void *p1, const void *p2)
e2 = &e2[4];
*/
- return strncasecmp(e1->str, e2->str, MAX_PATH);
+ return strncasecmp(e1->str, e2->str, TAG_MAXLEN);
}
static int tempbuf_sort(int fd)
@@ -1853,7 +1873,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
struct master_header tcmh;
struct index_entry idxbuf[IDX_BUF_DEPTH];
int idxbuf_pos;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
int fd = -1, masterfd;
bool error = false;
int init;
@@ -2031,7 +2051,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
if (masterfd < 0)
{
- logf("Failure to create index file");
+ logf("Failure to create index file (%s)", TAGCACHE_FILE_MASTER);
close(fd);
return -2;
}
@@ -2349,6 +2369,7 @@ static bool commit(void)
return true;
}
+
/* Load the header. */
len = sizeof(struct tagcache_header);
rc = read(tmpfd, &tch, len);
@@ -2375,7 +2396,7 @@ static bool commit(void)
/* At first be sure to unload the ramcache! */
#ifdef HAVE_TC_RAMCACHE
- stat.ramcache = false;
+ tc_stat.ramcache = false;
#endif
read_lock++;
@@ -2399,10 +2420,10 @@ static bool commit(void)
#endif
#ifdef HAVE_TC_RAMCACHE
- if (tempbuf_size == 0 && stat.ramcache_allocated > 0)
+ if (tempbuf_size == 0 && tc_stat.ramcache_allocated > 0)
{
tempbuf = (char *)(hdr + 1);
- tempbuf_size = stat.ramcache_allocated - sizeof(struct ramcache_header) - 128;
+ tempbuf_size = tc_stat.ramcache_allocated - sizeof(struct ramcache_header) - 128;
tempbuf_size &= ~0x03;
}
#endif
@@ -2411,7 +2432,7 @@ static bool commit(void)
if (tempbuf_size == 0)
{
logf("delaying commit until next boot");
- stat.commit_delayed = true;
+ tc_stat.commit_delayed = true;
close(tmpfd);
read_lock--;
return false;
@@ -2420,9 +2441,9 @@ static bool commit(void)
logf("commit %d entries...", tch.entry_count);
/* Now create the index files. */
- stat.commit_step = 0;
+ tc_stat.commit_step = 0;
tch.datasize = 0;
- stat.commit_delayed = false;
+ tc_stat.commit_delayed = false;
for (i = 0; i < TAG_COUNT; i++)
{
@@ -2431,7 +2452,7 @@ static bool commit(void)
if (tagcache_is_numeric_tag(i))
continue;
- stat.commit_step++;
+ tc_stat.commit_step++;
ret = build_index(i, &tch, tmpfd);
if (ret <= 0)
{
@@ -2440,8 +2461,8 @@ static bool commit(void)
if (ret < 0)
remove_files();
else
- stat.commit_delayed = true;
- stat.commit_step = 0;
+ tc_stat.commit_delayed = true;
+ tc_stat.commit_step = 0;
read_lock--;
return false;
}
@@ -2449,7 +2470,7 @@ static bool commit(void)
build_numeric_indices(&tch, tmpfd);
close(tmpfd);
- stat.commit_step = 0;
+ tc_stat.commit_step = 0;
/* Update the master index headers. */
if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
@@ -2469,7 +2490,7 @@ static bool commit(void)
logf("tagcache committed");
remove(TAGCACHE_FILE_TEMP);
- stat.ready = true;
+ tc_stat.ready = true;
if (local_allocation)
{
@@ -2485,7 +2506,7 @@ static bool commit(void)
#ifdef HAVE_TC_RAMCACHE
/* Reload tagcache. */
- if (stat.ramcache_allocated > 0)
+ if (tc_stat.ramcache_allocated > 0)
tagcache_start_scan();
#endif
@@ -2497,9 +2518,14 @@ static bool commit(void)
static void allocate_tempbuf(void)
{
/* Yeah, malloc would be really nice now :) */
+#ifdef __PCTOOL__
+ tempbuf_size = 32*1024*1024;
+ tempbuf = malloc(tempbuf_size);
+#else
tempbuf = (char *)(((long)audiobuf & ~0x03) + 0x04);
tempbuf_size = (long)audiobufend - (long)audiobuf - 4;
audiobuf += tempbuf_size;
+#endif
}
static void free_tempbuf(void)
@@ -2507,7 +2533,11 @@ static void free_tempbuf(void)
if (tempbuf_size == 0)
return ;
+#ifdef __PCTOOL__
+ free(tempbuf);
+#else
audiobuf -= tempbuf_size;
+#endif
tempbuf = NULL;
tempbuf_size = 0;
}
@@ -2538,7 +2568,7 @@ static bool update_current_serial(long serial)
long tagcache_increase_serial(void)
{
- if (!stat.ready)
+ if (!tc_stat.ready)
return -2;
while (read_lock)
@@ -2559,7 +2589,7 @@ static bool modify_numeric_entry(int masterfd, int idx_id, int tag, long data)
{
struct index_entry idx;
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
if (!tagcache_is_numeric_tag(tag))
@@ -2691,7 +2721,7 @@ static bool read_tag(char *dest, long size,
static int parse_changelog_line(int line_n, const char *buf, void *parameters)
{
struct index_entry idx;
- char tag_data[MAX_PATH];
+ char tag_data[TAG_MAXLEN+32];
int idx_id;
long masterfd = (long)parameters;
const int import_tags[] = { tag_playcount, tag_playtime, tag_lastplayed };
@@ -2752,6 +2782,7 @@ static int parse_changelog_line(int line_n, const char *buf, void *parameters)
return write_index(masterfd, idx_id, &idx) ? 0 : -5;
}
+#ifndef __PCTOOL__
bool tagcache_import_changelog(void)
{
struct master_header myhdr;
@@ -2760,7 +2791,7 @@ bool tagcache_import_changelog(void)
long masterfd;
char buf[2048];
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
while (read_lock)
@@ -2798,17 +2829,18 @@ bool tagcache_import_changelog(void)
return true;
}
+#endif
bool tagcache_create_changelog(struct tagcache_search *tcs)
{
struct master_header myhdr;
struct index_entry idx;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
char temp[32];
int clfd;
int i, j;
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
if (!tagcache_search(tcs, tag_filename))
@@ -2882,7 +2914,7 @@ static bool delete_entry(long idx_id)
int tag, i;
struct index_entry idx, myidx;
struct master_header myhdr;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
int in_use[TAG_COUNT];
logf("delete_entry(): %d", idx_id);
@@ -2987,6 +3019,7 @@ static bool delete_entry(long idx_id)
return true;
}
+#ifndef __PCTOOL__
/**
* Returns true if there is an event waiting in the queue
* that requires the current operation to be aborted.
@@ -3008,6 +3041,7 @@ static bool check_event_queue(void)
return false;
}
+#endif
#ifdef HAVE_TC_RAMCACHE
static bool allocate_tagcache(void)
@@ -3028,13 +3062,13 @@ static bool allocate_tagcache(void)
* Now calculate the required cache size plus
* some extra space for alignment fixes.
*/
- stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE +
+ tc_stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE +
sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *);
- hdr = buffer_alloc(stat.ramcache_allocated + 128);
+ hdr = buffer_alloc(tc_stat.ramcache_allocated + 128);
memset(hdr, 0, sizeof(struct ramcache_header));
memcpy(&hdr->h, &tcmh, sizeof(struct master_header));
hdr->indices = (struct index_entry *)(hdr + 1);
- logf("tagcache: %d bytes allocated.", stat.ramcache_allocated);
+ logf("tagcache: %d bytes allocated.", tc_stat.ramcache_allocated);
return true;
}
@@ -3069,18 +3103,18 @@ static bool tagcache_dumpload(void)
offpos = (long)hdr - (long)shdr.hdr;
/* Lets allocate real memory and load it */
- hdr = buffer_alloc(shdr.stat.ramcache_allocated);
- rc = read(fd, hdr, shdr.stat.ramcache_allocated);
+ hdr = buffer_alloc(shdr.tc_stat.ramcache_allocated);
+ rc = read(fd, hdr, shdr.tc_stat.ramcache_allocated);
close(fd);
- if (rc != shdr.stat.ramcache_allocated)
+ if (rc != shdr.tc_stat.ramcache_allocated)
{
logf("read failure!");
hdr = NULL;
return false;
}
- memcpy(&stat, &shdr.stat, sizeof(struct tagcache_stat));
+ memcpy(&tc_stat, &shdr.tc_stat, sizeof(struct tagcache_stat));
/* Now fix the pointers */
hdr->indices = (struct index_entry *)((long)hdr->indices + offpos);
@@ -3095,7 +3129,7 @@ static bool tagcache_dumpsave(void)
struct statefile_header shdr;
int fd;
- if (!stat.ramcache)
+ if (!tc_stat.ramcache)
return false;
fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC);
@@ -3107,11 +3141,11 @@ static bool tagcache_dumpsave(void)
/* Create the header */
shdr.hdr = hdr;
- memcpy(&shdr.stat, &stat, sizeof(struct tagcache_stat));
+ memcpy(&shdr.tc_stat, &tc_stat, sizeof(struct tagcache_stat));
write(fd, &shdr, sizeof(struct statefile_header));
/* And dump the data too */
- write(fd, hdr, stat.ramcache_allocated);
+ write(fd, hdr, tc_stat.ramcache_allocated);
close(fd);
return true;
@@ -3121,7 +3155,7 @@ static bool tagcache_dumpsave(void)
static bool load_tagcache(void)
{
struct tagcache_header *tch;
- long bytesleft = stat.ramcache_allocated;
+ long bytesleft = tc_stat.ramcache_allocated;
struct index_entry *idx;
int rc, fd;
char *p;
@@ -3164,7 +3198,7 @@ static bool load_tagcache(void)
}
bytesleft -= sizeof(struct index_entry);
- if (bytesleft < 0 || ((long)idx - (long)hdr->indices) >= stat.ramcache_allocated)
+ if (bytesleft < 0 || ((long)idx - (long)hdr->indices) >= tc_stat.ramcache_allocated)
{
logf("too big tagcache.");
close(fd);
@@ -3181,7 +3215,7 @@ static bool load_tagcache(void)
for (tag = 0; tag < TAG_COUNT; tag++)
{
struct tagfile_entry *fe;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
if (tagcache_is_numeric_tag(tag))
continue ;
@@ -3341,7 +3375,7 @@ static bool load_tagcache(void)
close(fd);
}
- stat.ramcache_used = stat.ramcache_allocated - bytesleft;
+ tc_stat.ramcache_used = tc_stat.ramcache_allocated - bytesleft;
logf("tagcache loaded into ram!");
return true;
@@ -3351,7 +3385,7 @@ static bool load_tagcache(void)
static bool check_deleted_files(void)
{
int fd, testfd;
- char buf[MAX_PATH];
+ char buf[TAG_MAXLEN+32];
struct tagfile_entry tfe;
logf("reverse scan...");
@@ -3366,7 +3400,11 @@ static bool check_deleted_files(void)
lseek(fd, sizeof(struct tagcache_header), SEEK_SET);
while (read(fd, &tfe, sizeof(struct tagfile_entry))
- == sizeof(struct tagfile_entry) && !check_event_queue())
+ == sizeof(struct tagfile_entry)
+#ifndef __PCTOOL__
+ && !check_event_queue()
+#endif
+ )
{
if (tfe.tag_length >= (long)sizeof(buf)-1)
{
@@ -3414,7 +3452,11 @@ static bool check_dir(const char *dirname)
}
/* Recursively scan the dir. */
+#ifdef __PCTOOL__
+ while (1)
+#else
while (!check_event_queue())
+#endif
{
struct dircache_entry *entry;
@@ -3426,8 +3468,8 @@ static bool check_dir(const char *dirname)
break ;
}
- if (!strcmp(entry->d_name, ".") ||
- !strcmp(entry->d_name, ".."))
+ if (!strcmp((char *)entry->d_name, ".") ||
+ !strcmp((char *)entry->d_name, ".."))
continue;
yield();
@@ -3454,7 +3496,7 @@ static bool check_dir(const char *dirname)
return success;
}
-static void build_tagcache(void)
+void build_tagcache(const char *path)
{
struct tagcache_header header;
bool ret;
@@ -3482,7 +3524,7 @@ static void build_tagcache(void)
cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC);
if (cachefd < 0)
{
- logf("master file open failed");
+ logf("master file open failed: %s", TAGCACHE_FILE_TEMP);
return ;
}
@@ -3490,12 +3532,13 @@ static void build_tagcache(void)
cpu_boost_id(true, CPUBOOSTID_TAGCACHE);
+ logf("Scanning files...");
/* Scan for new files. */
memset(&header, 0, sizeof(struct tagcache_header));
write(cachefd, &header, sizeof(struct tagcache_header));
- //strcpy(curpath, "/Best");
- ret = check_dir("/");
+ strcpy(curpath, path);
+ ret = check_dir(path);
/* Write the header. */
header.magic = TAGCACHE_MAGIC;
@@ -3519,11 +3562,17 @@ static void build_tagcache(void)
}
/* Commit changes to the database. */
+#ifdef __PCTOOL__
+ allocate_tempbuf();
+#endif
if (commit())
{
remove(TAGCACHE_FILE_TEMP);
logf("tagcache built!");
}
+#ifdef __PCTOOL__
+ free_tempbuf();
+#endif
#ifdef HAVE_TC_RAMCACHE
if (hdr)
@@ -3546,13 +3595,13 @@ static void load_ramcache(void)
cpu_boost_id(true, CPUBOOSTID_TAGCACHE);
/* At first we should load the cache (if exists). */
- stat.ramcache = load_tagcache();
+ tc_stat.ramcache = load_tagcache();
- if (!stat.ramcache)
+ if (!tc_stat.ramcache)
{
/* If loading failed, it must indicate some problem with the db
* so disable it entirely to prevent further issues. */
- stat.ready = false;
+ tc_stat.ready = false;
hdr = NULL;
}
@@ -3561,7 +3610,7 @@ static void load_ramcache(void)
void tagcache_unload_ramcache(void)
{
- stat.ramcache = false;
+ tc_stat.ramcache = false;
/* Just to make sure there is no statefile present. */
// remove(TAGCACHE_STATEFILE);
}
@@ -3594,6 +3643,7 @@ static bool check_all_headers(void)
return true;
}
+#ifndef __PCTOOL__
static void tagcache_thread(void)
{
struct event ev;
@@ -3615,16 +3665,16 @@ static void tagcache_thread(void)
# endif
/* Allocate space for the tagcache if found on disk. */
- if (global_settings.tagcache_ram && !stat.ramcache)
+ if (global_settings.tagcache_ram && !tc_stat.ramcache)
allocate_tagcache();
#endif
cpu_boost_id(false, CPUBOOSTID_TAGCACHE);
- stat.initialized = true;
+ tc_stat.initialized = true;
/* Don't delay bootup with the header check but do it on background. */
sleep(HZ);
- stat.ready = check_all_headers();
+ tc_stat.ready = check_all_headers();
while (1)
{
@@ -3638,11 +3688,11 @@ static void tagcache_thread(void)
case Q_REBUILD:
remove_files();
- build_tagcache();
+ build_tagcache("/");
break;
case Q_UPDATE:
- build_tagcache();
+ build_tagcache("/");
#ifdef HAVE_TC_RAMCACHE
load_ramcache();
#endif
@@ -3652,21 +3702,21 @@ static void tagcache_thread(void)
case Q_START_SCAN:
check_done = false;
case SYS_TIMEOUT:
- if (check_done || !stat.ready)
+ if (check_done || !tc_stat.ready)
break ;
#ifdef HAVE_TC_RAMCACHE
- if (!stat.ramcache && global_settings.tagcache_ram)
+ if (!tc_stat.ramcache && global_settings.tagcache_ram)
{
load_ramcache();
- if (stat.ramcache && global_settings.tagcache_autoupdate)
- build_tagcache();
+ if (tc_stat.ramcache && global_settings.tagcache_autoupdate)
+ build_tagcache("/");
}
else
#endif
if (global_settings.tagcache_autoupdate)
{
- build_tagcache();
+ build_tagcache("/");
/* Don't do auto removal without dircache (very slow). */
#ifdef HAVE_DIRCACHE
if (dircache_is_enabled())
@@ -3711,7 +3761,7 @@ bool tagcache_prepare_shutdown(void)
void tagcache_shutdown(void)
{
#ifdef HAVE_EEPROM_SETTINGS
- if (stat.ramcache)
+ if (tc_stat.ramcache)
tagcache_dumpsave();
#endif
}
@@ -3729,7 +3779,7 @@ static int get_progress(void)
#endif
#ifdef HAVE_TC_RAMCACHE
{
- if (hdr && stat.ramcache)
+ if (hdr && tc_stat.ramcache)
total_count = hdr->h.tch.entry_count;
}
#endif
@@ -3742,12 +3792,12 @@ static int get_progress(void)
struct tagcache_stat* tagcache_get_stat(void)
{
- stat.progress = get_progress();
- stat.processed_entries = processed_dir_count;
+ tc_stat.progress = get_progress();
+ tc_stat.processed_entries = processed_dir_count;
- return &stat;
+ return &tc_stat;
}
-
+
void tagcache_start_scan(void)
{
queue_post(&tagcache_queue, Q_START_SCAN, 0);
@@ -3755,7 +3805,7 @@ void tagcache_start_scan(void)
bool tagcache_update(void)
{
- if (!stat.ready)
+ if (!tc_stat.ready)
return false;
queue_post(&tagcache_queue, Q_UPDATE, 0);
@@ -3780,31 +3830,41 @@ void tagcache_stop_scan(void)
#ifdef HAVE_TC_RAMCACHE
bool tagcache_is_ramcache(void)
{
- return stat.ramcache;
+ return tc_stat.ramcache;
}
#endif
+#endif /* !__PCTOOL__ */
+
void tagcache_init(void)
{
- memset(&stat, 0, sizeof(struct tagcache_stat));
+ memset(&tc_stat, 0, sizeof(struct tagcache_stat));
filenametag_fd = -1;
current_serial = 0;
write_lock = read_lock = 0;
+#ifndef __PCTOOL__
queue_init(&tagcache_queue, true);
create_thread(tagcache_thread, tagcache_stack,
sizeof(tagcache_stack), tagcache_thread_name
IF_PRIO(, PRIORITY_BACKGROUND));
+#else
+ tc_stat.initialized = true;
+ allocate_tempbuf();
+ commit();
+ free_tempbuf();
+ tc_stat.ready = check_all_headers();
+#endif
}
bool tagcache_is_initialized(void)
{
- return stat.initialized;
+ return tc_stat.initialized;
}
int tagcache_get_commit_step(void)
{
- return stat.commit_step;
+ return tc_stat.commit_step;
}
diff --git a/apps/tagcache.h b/apps/tagcache.h
index f1819855db..ea4d255630 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -30,6 +30,9 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
#define TAG_COUNT 13
+/* Maximum length of a single tag. */
+#define TAG_MAXLEN (MAX_PATH*2)
+
/* Allow a little drift to the filename ordering (should not be too high/low). */
#define POS_HISTORY_COUNT 4
@@ -119,7 +122,7 @@ struct tagcache_search {
int entry_count;
bool valid;
bool initialized;
- long *unique_list;
+ unsigned long *unique_list;
int unique_list_capacity;
int unique_list_count;
@@ -133,6 +136,10 @@ struct tagcache_search {
int idx_id;
};
+#ifdef __PCTOOL__
+void build_tagcache(const char *path);
+#endif
+
int tagcache_str_to_tag(const char *str);
const char* tagcache_tag_to_str(int tag);
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 7222a41221..7227704ffc 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -57,7 +57,7 @@ static unsigned long dircache_size = 0;
static unsigned long entry_count = 0;
static unsigned long reserve_used = 0;
static unsigned int cache_build_ticks = 0;
-static char dircache_cur_path[MAX_PATH];
+static char dircache_cur_path[MAX_PATH*2];
static struct event_queue dircache_queue;
static long dircache_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
@@ -178,7 +178,7 @@ static int dircache_scan(struct travel_data *td)
}
td->ce->attribute = td->entry->attribute;
- td->ce->name_len = MIN(254, strlen(td->entry->d_name)) + 1;
+ td->ce->name_len = strlen(td->entry->d_name);
td->ce->d_name = ((char *)dircache_root+dircache_size);
td->ce->size = td->entry->size;
td->ce->wrtdate = td->entry->wrtdate;
@@ -192,7 +192,7 @@ static int dircache_scan(struct travel_data *td)
}
td->ce->attribute = td->entry.attr;
- td->ce->name_len = MIN(254, strlen(td->entry.name)) + 1;
+ td->ce->name_len = strlen(td->entry.name) + 1;
td->ce->d_name = ((char *)dircache_root+dircache_size);
td->ce->startcluster = td->entry.firstcluster;
td->ce->size = td->entry.filesize;
@@ -215,9 +215,11 @@ static int dircache_scan(struct travel_data *td)
return -2;
td->pathpos = strlen(dircache_cur_path);
- strncpy(&dircache_cur_path[td->pathpos], "/", MAX_PATH - td->pathpos - 1);
+ strncpy(&dircache_cur_path[td->pathpos], "/",
+ sizeof(dircache_cur_path) - td->pathpos - 1);
#ifdef SIMULATOR
- strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, MAX_PATH - td->pathpos - 2);
+ strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name,
+ sizeof(dircache_cur_path) - td->pathpos - 2);
td->newdir = opendir(dircache_cur_path);
if (td->newdir == NULL)
@@ -226,7 +228,8 @@ static int dircache_scan(struct travel_data *td)
return -3;
}
#else
- strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, MAX_PATH - td->pathpos - 2);
+ strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name,
+ sizeof(dircache_cur_path) - td->pathpos - 2);
td->newdir = *td->dir;
if (fat_opendir(IF_MV2(volume,) &td->newdir,
@@ -360,7 +363,7 @@ static struct dircache_entry* dircache_get_entry(const char *path,
bool get_before, bool only_directories)
{
struct dircache_entry *cache_entry, *before;
- char namecopy[MAX_PATH];
+ char namecopy[MAX_PATH*2];
char* part;
char* end;
@@ -543,7 +546,7 @@ static int dircache_do_rebuild(void)
pdir = &dir;
#endif
- memset(dircache_cur_path, 0, MAX_PATH);
+ memset(dircache_cur_path, 0, sizeof(dircache_cur_path));
dircache_size = sizeof(struct dircache_entry);
cpu_boost_id(true, CPUBOOSTID_DIRCACHE);
@@ -837,7 +840,7 @@ static int block_until_ready(void)
static struct dircache_entry* dircache_new_entry(const char *path, int attribute)
{
struct dircache_entry *entry;
- char basedir[MAX_PATH];
+ char basedir[MAX_PATH*2];
char *new;
long last_cache_size = dircache_size;
@@ -1005,7 +1008,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
{ /* Test ok. */
struct dircache_entry *entry, *newentry;
struct dircache_entry oldentry;
- char absolute_path[MAX_PATH];
+ char absolute_path[MAX_PATH*2];
char *p;
if (block_until_ready())
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 18c0ef7d17..45d974a96f 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -20,7 +20,9 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
+#ifndef __PCTOOL__
#include "autoconf.h"
+#endif
/* symbolic names for multiple choice configurations: */
diff --git a/firmware/export/debug.h b/firmware/export/debug.h
index 52b6687c6b..ce556d6418 100644
--- a/firmware/export/debug.h
+++ b/firmware/export/debug.h
@@ -26,7 +26,7 @@ extern void ldebugf(const char* file, int line, const char *fmt, ...);
#ifdef __GNUC__
/* */
-#if defined(SIMULATOR)
+#if defined(SIMULATOR) && !defined(__PCTOOL__)
#define DEBUGF debugf
#define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__)
#else
diff --git a/firmware/export/logf.h b/firmware/export/logf.h
index 4206173596..35cb7127e4 100644
--- a/firmware/export/logf.h
+++ b/firmware/export/logf.h
@@ -23,6 +23,7 @@
#ifdef ROCKBOX_HAS_LOGF
+#ifndef __PCTOOL__
#define MAX_LOGF_LINES 1000
#define MAX_LOGF_ENTRY 30
#define MAX_LOGF_DATASIZE (MAX_LOGF_ENTRY*MAX_LOGF_LINES)
@@ -30,11 +31,14 @@
extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY];
extern int logfindex;
extern bool logfwrap;
+#endif /* __PCTOOL__ */
-void logf(const char *format, ...);
-#else
+#define logf _logf
+void _logf(const char *format, ...);
+
+#else /* !ROCKBOX_HAS_LOGF */
/* built without logf() support enabled */
#define logf(...)
-#endif
+#endif /* !ROCKBOX_HAS_LOGF */
#endif /* LOGF_H */
diff --git a/firmware/id3.c b/firmware/id3.c
index 470f4dc352..90b5b3bdee 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -457,9 +457,9 @@ static int unicode_munge(char* string, char* utf8buf, int *len) {
long tmp;
bool le = false;
int i = 0;
- char *str = string;
+ unsigned char *str = (unsigned char *)string;
int templen = 0;
- char* utf8 = utf8buf;
+ unsigned char* utf8 = (unsigned char *)utf8buf;
switch (str[0]) {
case 0x00: /* Type 0x00 is ordinary ISO 8859-1 */
@@ -467,7 +467,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) {
(*len)--;
utf8 = iso_decode(str, utf8, -1, *len);
*utf8 = 0;
- *len = utf8 - utf8buf;
+ *len = (unsigned long)utf8 - (unsigned long)utf8buf;
break;
case 0x01: /* Unicode with or without BOM */
@@ -524,7 +524,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) {
default: /* Plain old string */
utf8 = iso_decode(str, utf8, -1, *len);
*utf8 = 0;
- *len = utf8 - utf8buf;
+ *len = (unsigned long)utf8 - (unsigned long)utf8buf;
break;
}
return 0;
@@ -571,7 +571,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
case 1:
case 2:
/* convert string to utf8 */
- utf8 = entry->id3v1buf[i];
+ utf8 = (unsigned char *)entry->id3v1buf[i];
utf8 = iso_decode(ptr, utf8, -1, 30);
/* make sure string is terminated */
*utf8 = 0;
@@ -579,7 +579,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
case 3:
ptr[4] = 0;
- entry->year = atoi(ptr);
+ entry->year = atoi((char *)ptr);
break;
case 4:
diff --git a/firmware/include/dir.h b/firmware/include/dir.h
index 948b30ffe2..c10640199f 100644
--- a/firmware/include/dir.h
+++ b/firmware/include/dir.h
@@ -20,7 +20,7 @@
#define _DIR_H_
#include <stdbool.h>
-#include <file.h>
+#include "file.h"
#define ATTR_READ_ONLY 0x01
#define ATTR_HIDDEN 0x02
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index f6bc153faf..9c3bc68ddc 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -67,7 +67,7 @@ struct dircache_entry {
long startcluster;
unsigned short wrtdate;
unsigned short wrttime;
- unsigned char name_len;
+ unsigned long name_len;
char *d_name;
};
diff --git a/firmware/logf.c b/firmware/logf.c
index fc57bd85bf..2056db5cc4 100644
--- a/firmware/logf.c
+++ b/firmware/logf.c
@@ -27,7 +27,6 @@
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
-#include <sprintf.h>
#include "config.h"
#include "lcd-remote.h"
#include "logf.h"
@@ -36,9 +35,11 @@
/* Only provide all this if asked to */
#ifdef ROCKBOX_HAS_LOGF
+#ifndef __PCTOOL__
unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY];
int logfindex;
bool logfwrap;
+#endif
#ifdef HAVE_REMOTE_LCD
static void displayremote(void)
@@ -77,7 +78,18 @@ static void displayremote(void)
#define displayremote()
#endif
-void logf(const char *format, ...)
+#ifdef __PCTOOL__
+void _logf(const char *format, ...)
+{
+ char buf[1024];
+ va_list ap;
+ va_start(ap, format);
+
+ vsnprintf(buf, sizeof buf, format, ap);
+ printf("DEBUG: %s\n", buf);
+}
+#else
+void _logf(const char *format, ...)
{
int len;
unsigned char *ptr;
@@ -104,5 +116,6 @@ void logf(const char *format, ...)
displayremote();
}
+#endif
#endif
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index 0710090b37..49b95f2d9e 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -242,6 +242,7 @@ unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned lo
return __find_next_frame(fd, offset, max_offset, last_header, fileread);
}
+#ifndef __PCTOOL__
static int fnf_read_index;
static int fnf_buf_len;
@@ -335,6 +336,7 @@ unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset,
return __find_next_frame(0, offset, max_offset, last_header, mem_getbyte);
}
+#endif
int get_mp3file_info(int fd, struct mp3info *info)
{
@@ -543,6 +545,7 @@ static void long2bytes(unsigned char *buf, long val)
buf[3] = val & 0xff;
}
+#ifndef __PCTOOL__
int count_mp3_frames(int fd, int startpos, int filesize,
void (*progressfunc)(int))
{
@@ -762,3 +765,5 @@ int create_xing_header(int fd, long startpos, long filesize,
return info.frame_size;
}
+
+#endif
diff --git a/tools/Makefile b/tools/Makefile
index 1f8be87370..d6c885d85b 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -10,7 +10,7 @@ CFLAGS := -O -ansi -g
LDFLAGS := -g
CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \
- generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat
+ generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database
all:
@echo "Run make in your build directory!"
@@ -38,6 +38,13 @@ mkboot: mkboot.c
ipod_fw: ipod_fw.c
$(SILENT)$(CC) -g $+ -o $@
+database: database.c ../apps/tagcache.c ../apps/metadata.c \
+../firmware/id3.c ../firmware/common/unicode.c \
+../firmware/common/crc32.c ../uisimulator/common/io.c \
+../firmware/mp3data.c ../firmware/logf.c
+ $(SILENT)$(CC) -g -I../firmware/export -iquote ../firmware/include \
+-D__PCTOOL__ -DHAVE_TAGCACHE -DROCKBOX_HAS_LOGF -DSIMULATOR -ldl -I../apps $+ -o $@
+
convbdf: convbdf.c
$(SILENT)$(CC) -g $+ -o $@
diff --git a/tools/database.c b/tools/database.c
new file mode 100644
index 0000000000..780586ea90
--- /dev/null
+++ b/tools/database.c
@@ -0,0 +1,13 @@
+/* A _very_ skeleton file to demonstrate building tagcache db on host. */
+
+#include <stdio.h>
+#include "tagcache.h"
+
+int main(int argc, char **argv)
+{
+ tagcache_init();
+ build_tagcache("/export/stuff/mp3");
+
+ return 0;
+}
+
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index c4f8840cc5..ca64affa8c 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -106,11 +106,14 @@ MYDIR *sim_opendir(const char *name)
char buffer[256]; /* sufficiently big */
DIR *dir;
- if(name[0] == '/') {
+#ifndef __PCTOOL__
+ if(name[0] == '/')
+ {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
dir=(DIR *)opendir(buffer);
}
else
+#endif
dir=(DIR *)opendir(name);
if(dir) {
@@ -137,8 +140,12 @@ struct sim_dirent *sim_readdir(MYDIR *dir)
strcpy((char *)secret.d_name, x11->d_name);
/* build file name */
+#ifdef __PCTOOL__
+ sprintf(buffer, "%s/%s", dir->name, x11->d_name);
+#else
sprintf(buffer, SIMULATOR_ARCHOS_ROOT "%s/%s",
dir->name, x11->d_name);
+#endif
stat(buffer, &s); /* get info */
#define ATTR_DIRECTORY 0x10
@@ -164,22 +171,32 @@ int sim_open(const char *name, int o)
char buffer[256]; /* sufficiently big */
int opts = rockbox2sim(o);
- if(name[0] == '/') {
+#ifndef __PCTOOL__
+ if(name[0] == '/')
+ {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
debugf("We open the real file '%s'\n", buffer);
return open(buffer, opts, 0666);
}
+
fprintf(stderr, "WARNING, bad file name lacks slash: %s\n",
name);
return -1;
+#else
+ return open(name, opts, 0666);
+#endif
+
}
int sim_creat(const char *name, mode_t mode)
{
- char buffer[256]; /* sufficiently big */
int opts = rockbox2sim(mode);
- if(name[0] == '/') {
+
+#ifndef __PCTOOL__
+ char buffer[256]; /* sufficiently big */
+ if(name[0] == '/')
+ {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
debugf("We create the real file '%s'\n", buffer);
@@ -188,12 +205,22 @@ int sim_creat(const char *name, mode_t mode)
fprintf(stderr, "WARNING, bad file name lacks slash: %s\n",
name);
return -1;
+#else
+ return open(name, opts | O_CREAT | O_TRUNC, 0666);
+#endif
}
int sim_mkdir(const char *name, mode_t mode)
{
- char buffer[256]; /* sufficiently big */
(void)mode;
+#ifdef __PCTOOL__
+# ifdef WIN32
+ return mkdir(name);
+# else
+ return mkdir(name, 0777);
+# endif
+#else
+ char buffer[256]; /* sufficiently big */
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
@@ -204,22 +231,31 @@ int sim_mkdir(const char *name, mode_t mode)
#else
return mkdir(buffer, 0777);
#endif
+#endif
}
int sim_rmdir(const char *name)
{
+#ifdef __PCTOOL__
+ return rmdir(name);
+#else
char buffer[256]; /* sufficiently big */
- if(name[0] == '/') {
+ if(name[0] == '/')
+ {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
debugf("We remove the real directory '%s'\n", buffer);
return rmdir(buffer);
}
return rmdir(name);
+#endif
}
int sim_remove(const char *name)
{
+#ifdef __PCTOOL__
+ return remove(name);
+#else
char buffer[256]; /* sufficiently big */
#ifdef HAVE_DIRCACHE
@@ -233,10 +269,14 @@ int sim_remove(const char *name)
return remove(buffer);
}
return remove(name);
+#endif
}
int sim_rename(const char *oldpath, const char* newpath)
{
+#ifdef __PCTOOL__
+ return rename(oldpath, newpath);
+#else
char buffer1[256];
char buffer2[256];
@@ -252,6 +292,7 @@ int sim_rename(const char *oldpath, const char* newpath)
return rename(buffer1, buffer2);
}
return -1;
+#endif
}
/* rockbox off_t may be different from system off_t */