summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-02-28 11:41:35 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-02-28 11:41:35 +0000
commit871575f0f03b697a602b3cb7ee6fe0b5d29a9607 (patch)
treeb7deff5e606ef18e982ce81ede35245fb0b8551c
parent3b6141c7c6b71944aaa35a92f118f26a1eb7078c (diff)
downloadrockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.zip
rockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.tar.gz
rockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.tar.bz2
rockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.tar.xz
Implement . and .. path in dircache to properly support moving files
to other directories without absolute destination path provided. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8866 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/dircache.c55
-rw-r--r--firmware/include/dircache.h3
2 files changed, 53 insertions, 5 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index fbd7fab..df68022 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -155,7 +155,7 @@ static int dircache_scan(struct travel_data *td)
{
continue;
}
-
+
td->ce->attribute = td->entry.attr;
td->ce->name_len = MIN(254, strlen(td->entry.name)) + 1;
td->ce->d_name = ((char *)dircache_root+dircache_size);
@@ -211,15 +211,41 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
memset(ce, 0, sizeof(struct dircache_entry));
dir_recursion[0].dir = dir;
dir_recursion[0].ce = ce;
+ dir_recursion[0].first = ce;
do {
//logf("=> %s", dircache_cur_path);
result = dircache_scan(&dir_recursion[depth]);
switch (result) {
case 0: /* Leaving the current directory. */
+ /* Add the standard . and .. entries. */
+ ce = dir_recursion[depth].ce;
+ ce->attribute = FAT_ATTR_DIRECTORY;
+ ce->d_name = ".";
+ ce->name_len = 2;
+ ce->startcluster = dir_recursion[depth].dir->file.firstcluster;
+ ce->size = 0;
+ ce->down = dir_recursion[depth].first;
+
depth--;
- if (depth >= 0)
- dircache_cur_path[dir_recursion[depth].pathpos] = '\0';
+ if (depth < 0)
+ break ;
+
+ dircache_cur_path[dir_recursion[depth].pathpos] = '\0';
+
+ ce = dircache_gen_next(ce);
+ if (ce == NULL)
+ {
+ logf("memory allocation error");
+ return -3;
+ }
+ ce->attribute = FAT_ATTR_DIRECTORY;
+ ce->d_name = "..";
+ ce->name_len = 3;
+ ce->startcluster = dir_recursion[depth].dir->file.firstcluster;
+ ce->size = 0;
+ ce->down = dir_recursion[depth].first;
+
break ;
case 1: /* Going down in the directory tree. */
@@ -231,6 +257,7 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
}
dir_recursion[depth].dir = &dir_recursion[depth-1].newdir;
+ dir_recursion[depth].first = dir_recursion[depth-1].down_entry;
dir_recursion[depth].ce = dir_recursion[depth-1].down_entry;
break ;
@@ -685,6 +712,7 @@ static struct dircache_entry* dircache_new_entry(const char *path, int attribute
if (entry == NULL)
{
logf("basedir not found!");
+ logf(basedir);
dircache_initialized = false;
return NULL;
}
@@ -812,11 +840,14 @@ 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 *p;
if (!dircache_initialized)
return ;
logf("rename: %s->%s", oldpath, newpath);
+
entry = dircache_get_entry(oldpath, true, false);
if (entry == NULL)
{
@@ -832,6 +863,23 @@ void dircache_rename(const char *oldpath, const char *newpath)
* save the data, because the entry will be re-used. */
oldentry = *entry;
+ /* Generate the absolute path for destination if necessary. */
+ if (newpath[0] != '/')
+ {
+ strncpy(absolute_path, oldpath, sizeof(absolute_path)-1);
+ p = strrchr(absolute_path, '/');
+ if (!p)
+ {
+ logf("Invalid path");
+ dircache_initialized = false;
+ return ;
+ }
+
+ *p = '\0';
+ strncpy(p, absolute_path, sizeof(absolute_path)-1-strlen(p));
+ newpath = absolute_path;
+ }
+
newentry = dircache_new_entry(newpath, entry->attribute);
if (newentry == NULL)
{
@@ -840,7 +888,6 @@ void dircache_rename(const char *oldpath, const char *newpath)
}
newentry->down = oldentry.down;
- newentry->up = oldentry.up;
newentry->size = oldentry.size;
newentry->startcluster = oldentry.startcluster;
newentry->wrttime = oldentry.wrttime;
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 6e75e1b..93bc413 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -24,11 +24,12 @@
#ifdef HAVE_DIRCACHE
#define DIRCACHE_RESERVE (1024*64)
-#define DIRCACHE_LIMIT (1024*1024*3)
+#define DIRCACHE_LIMIT (1024*1024*6)
#define DIRCACHE_FILE ROCKBOX_DIR "/dircache.dat"
/* Internal structures. */
struct travel_data {
+ struct dircache_entry *first;
struct dircache_entry *ce;
struct dircache_entry *down_entry;
struct fat_dir *dir;