summaryrefslogtreecommitdiff
path: root/firmware
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 /firmware
parent3b6141c7c6b71944aaa35a92f118f26a1eb7078c (diff)
downloadrockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.tar.gz
rockbox-871575f0f03b697a602b3cb7ee6fe0b5d29a9607.zip
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
Diffstat (limited to 'firmware')
-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 fbd7fab188..df68022fcd 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -155,7 +155,7 @@ static int dircache_scan(struct travel_data *td)
155 { 155 {
156 continue; 156 continue;
157 } 157 }
158 158
159 td->ce->attribute = td->entry.attr; 159 td->ce->attribute = td->entry.attr;
160 td->ce->name_len = MIN(254, strlen(td->entry.name)) + 1; 160 td->ce->name_len = MIN(254, strlen(td->entry.name)) + 1;
161 td->ce->d_name = ((char *)dircache_root+dircache_size); 161 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)
211 memset(ce, 0, sizeof(struct dircache_entry)); 211 memset(ce, 0, sizeof(struct dircache_entry));
212 dir_recursion[0].dir = dir; 212 dir_recursion[0].dir = dir;
213 dir_recursion[0].ce = ce; 213 dir_recursion[0].ce = ce;
214 dir_recursion[0].first = ce;
214 215
215 do { 216 do {
216 //logf("=> %s", dircache_cur_path); 217 //logf("=> %s", dircache_cur_path);
217 result = dircache_scan(&dir_recursion[depth]); 218 result = dircache_scan(&dir_recursion[depth]);
218 switch (result) { 219 switch (result) {
219 case 0: /* Leaving the current directory. */ 220 case 0: /* Leaving the current directory. */
221 /* Add the standard . and .. entries. */
222 ce = dir_recursion[depth].ce;
223 ce->attribute = FAT_ATTR_DIRECTORY;
224 ce->d_name = ".";
225 ce->name_len = 2;
226 ce->startcluster = dir_recursion[depth].dir->file.firstcluster;
227 ce->size = 0;
228 ce->down = dir_recursion[depth].first;
229
220 depth--; 230 depth--;
221 if (depth >= 0) 231 if (depth < 0)
222 dircache_cur_path[dir_recursion[depth].pathpos] = '\0'; 232 break ;
233
234 dircache_cur_path[dir_recursion[depth].pathpos] = '\0';
235
236 ce = dircache_gen_next(ce);
237 if (ce == NULL)
238 {
239 logf("memory allocation error");
240 return -3;
241 }
242 ce->attribute = FAT_ATTR_DIRECTORY;
243 ce->d_name = "..";
244 ce->name_len = 3;
245 ce->startcluster = dir_recursion[depth].dir->file.firstcluster;
246 ce->size = 0;
247 ce->down = dir_recursion[depth].first;
248
223 break ; 249 break ;
224 250
225 case 1: /* Going down in the directory tree. */ 251 case 1: /* Going down in the directory tree. */
@@ -231,6 +257,7 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
231 } 257 }
232 258
233 dir_recursion[depth].dir = &dir_recursion[depth-1].newdir; 259 dir_recursion[depth].dir = &dir_recursion[depth-1].newdir;
260 dir_recursion[depth].first = dir_recursion[depth-1].down_entry;
234 dir_recursion[depth].ce = dir_recursion[depth-1].down_entry; 261 dir_recursion[depth].ce = dir_recursion[depth-1].down_entry;
235 break ; 262 break ;
236 263
@@ -685,6 +712,7 @@ static struct dircache_entry* dircache_new_entry(const char *path, int attribute
685 if (entry == NULL) 712 if (entry == NULL)
686 { 713 {
687 logf("basedir not found!"); 714 logf("basedir not found!");
715 logf(basedir);
688 dircache_initialized = false; 716 dircache_initialized = false;
689 return NULL; 717 return NULL;
690 } 718 }
@@ -812,11 +840,14 @@ void dircache_rename(const char *oldpath, const char *newpath)
812{ /* Test ok. */ 840{ /* Test ok. */
813 struct dircache_entry *entry, *newentry; 841 struct dircache_entry *entry, *newentry;
814 struct dircache_entry oldentry; 842 struct dircache_entry oldentry;
843 char absolute_path[MAX_PATH];
844 char *p;
815 845
816 if (!dircache_initialized) 846 if (!dircache_initialized)
817 return ; 847 return ;
818 848
819 logf("rename: %s->%s", oldpath, newpath); 849 logf("rename: %s->%s", oldpath, newpath);
850
820 entry = dircache_get_entry(oldpath, true, false); 851 entry = dircache_get_entry(oldpath, true, false);
821 if (entry == NULL) 852 if (entry == NULL)
822 { 853 {
@@ -832,6 +863,23 @@ void dircache_rename(const char *oldpath, const char *newpath)
832 * save the data, because the entry will be re-used. */ 863 * save the data, because the entry will be re-used. */
833 oldentry = *entry; 864 oldentry = *entry;
834 865
866 /* Generate the absolute path for destination if necessary. */
867 if (newpath[0] != '/')
868 {
869 strncpy(absolute_path, oldpath, sizeof(absolute_path)-1);
870 p = strrchr(absolute_path, '/');
871 if (!p)
872 {
873 logf("Invalid path");
874 dircache_initialized = false;
875 return ;
876 }
877
878 *p = '\0';
879 strncpy(p, absolute_path, sizeof(absolute_path)-1-strlen(p));
880 newpath = absolute_path;
881 }
882
835 newentry = dircache_new_entry(newpath, entry->attribute); 883 newentry = dircache_new_entry(newpath, entry->attribute);
836 if (newentry == NULL) 884 if (newentry == NULL)
837 { 885 {
@@ -840,7 +888,6 @@ void dircache_rename(const char *oldpath, const char *newpath)
840 } 888 }
841 889
842 newentry->down = oldentry.down; 890 newentry->down = oldentry.down;
843 newentry->up = oldentry.up;
844 newentry->size = oldentry.size; 891 newentry->size = oldentry.size;
845 newentry->startcluster = oldentry.startcluster; 892 newentry->startcluster = oldentry.startcluster;
846 newentry->wrttime = oldentry.wrttime; 893 newentry->wrttime = oldentry.wrttime;
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 6e75e1bfeb..93bc413dc9 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -24,11 +24,12 @@
24#ifdef HAVE_DIRCACHE 24#ifdef HAVE_DIRCACHE
25 25
26#define DIRCACHE_RESERVE (1024*64) 26#define DIRCACHE_RESERVE (1024*64)
27#define DIRCACHE_LIMIT (1024*1024*3) 27#define DIRCACHE_LIMIT (1024*1024*6)
28#define DIRCACHE_FILE ROCKBOX_DIR "/dircache.dat" 28#define DIRCACHE_FILE ROCKBOX_DIR "/dircache.dat"
29 29
30/* Internal structures. */ 30/* Internal structures. */
31struct travel_data { 31struct travel_data {
32 struct dircache_entry *first;
32 struct dircache_entry *ce; 33 struct dircache_entry *ce;
33 struct dircache_entry *down_entry; 34 struct dircache_entry *down_entry;
34 struct fat_dir *dir; 35 struct fat_dir *dir;