diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-02-28 11:41:35 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-02-28 11:41:35 +0000 |
commit | 871575f0f03b697a602b3cb7ee6fe0b5d29a9607 (patch) | |
tree | b7deff5e606ef18e982ce81ede35245fb0b8551c /firmware | |
parent | 3b6141c7c6b71944aaa35a92f118f26a1eb7078c (diff) | |
download | rockbox-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.c | 55 | ||||
-rw-r--r-- | firmware/include/dircache.h | 3 |
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. */ |
31 | struct travel_data { | 31 | struct 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; |