diff options
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/dircache.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 7ff497790e..66189c48a8 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -71,7 +71,7 @@ static unsigned long entry_count = 0; | |||
71 | static unsigned long reserve_used = 0; | 71 | static unsigned long reserve_used = 0; |
72 | static unsigned int cache_build_ticks = 0; | 72 | static unsigned int cache_build_ticks = 0; |
73 | static unsigned long appflags = 0; | 73 | static unsigned long appflags = 0; |
74 | static char dircache_cur_path[MAX_PATH*2]; | 74 | static char dircache_cur_path[MAX_PATH]; |
75 | 75 | ||
76 | static struct event_queue dircache_queue; | 76 | static struct event_queue dircache_queue; |
77 | static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)]; | 77 | static long dircache_stack[(DEFAULT_STACK_SIZE + 0x900)/sizeof(long)]; |
@@ -393,7 +393,8 @@ static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dirca | |||
393 | * path: Absolute path to a file or directory (see comment) | 393 | * path: Absolute path to a file or directory (see comment) |
394 | * go_down: Returns the first entry of the directory given by the path (see comment) | 394 | * go_down: Returns the first entry of the directory given by the path (see comment) |
395 | * | 395 | * |
396 | * As a a special case to handle buggy code, accept path="" as an alias for "/" | 396 | * As a a special case, accept path="" as an alias for "/". |
397 | * Also if the path omits the first '/', it will be accepted. | ||
397 | * | 398 | * |
398 | * * If get_down=true: | 399 | * * If get_down=true: |
399 | * If path="/", the returned entry is the first of root directory (ie dircache_root) | 400 | * If path="/", the returned entry is the first of root directory (ie dircache_root) |
@@ -420,16 +421,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, bool go_down) | |||
420 | bool at_root = true; | 421 | bool at_root = true; |
421 | struct dircache_entry *cache_entry = dircache_root; | 422 | struct dircache_entry *cache_entry = dircache_root; |
422 | 423 | ||
423 | /* check that the path is absolute (accept empty path also) */ | 424 | strlcpy(namecopy, path, sizeof(namecopy)); |
424 | if(path[0] != '/' && path[0] != 0) | ||
425 | return NULL; | ||
426 | |||
427 | /* make a copy of the path because strok_r modifies the path */ | ||
428 | /* also handle the weird "" alias for "/" */ | ||
429 | if(path[0] != 0) | ||
430 | strlcpy(namecopy, path, sizeof(namecopy)); | ||
431 | else | ||
432 | strlcpy(namecopy, "/", sizeof(namecopy)); | ||
433 | 425 | ||
434 | for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) | 426 | for(part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) |
435 | { | 427 | { |
@@ -913,31 +905,39 @@ const struct dircache_entry *dircache_get_entry_ptr(const char *filename) | |||
913 | */ | 905 | */ |
914 | void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) | 906 | void dircache_copy_path(const struct dircache_entry *entry, char *buf, int size) |
915 | { | 907 | { |
916 | const struct dircache_entry *down[MAX_SCAN_DEPTH]; | 908 | int path_size = 0; |
917 | int depth = 0; | 909 | int idx; |
910 | const struct dircache_entry *temp = entry; | ||
918 | 911 | ||
919 | if (size <= 0) | 912 | if (size <= 0) |
920 | return ; | 913 | return ; |
914 | |||
915 | /* first compute the necessary size */ | ||
916 | while(temp != NULL) | ||
917 | { | ||
918 | path_size += temp->name_len; /* '/' + d_name */ | ||
919 | temp = temp->up; | ||
920 | } | ||
921 | 921 | ||
922 | buf[0] = '\0'; | 922 | /* now copy the path */ |
923 | 923 | /* doesn't matter with trailing 0 because it's added later */ | |
924 | if (entry == NULL) | 924 | idx = path_size; |
925 | return ; | 925 | while(entry != NULL) |
926 | |||
927 | do { | ||
928 | down[depth] = entry; | ||
929 | entry = entry->up; | ||
930 | depth++; | ||
931 | } while (entry != NULL && depth < MAX_SCAN_DEPTH); | ||
932 | |||
933 | while (--depth >= 0) | ||
934 | { | 926 | { |
935 | snprintf(buf, size, "/%s", down[depth]->d_name); | 927 | idx -= entry->name_len; |
936 | buf += down[depth]->name_len; /* '/' + d_name */ | 928 | /* available size */ |
937 | size -= down[depth]->name_len; | 929 | int rem = size - idx; |
938 | if (size <= 0) | 930 | |
939 | break ; | 931 | if(rem >= 1) |
932 | { | ||
933 | buf[idx] = '/'; | ||
934 | memcpy(buf + idx + 1, entry->d_name, MIN((size_t)(rem - 1), (size_t)(entry->name_len - 1))); | ||
935 | } | ||
936 | entry = entry->up; | ||
940 | } | 937 | } |
938 | |||
939 | /* add trailing 0 */ | ||
940 | buf[MIN(path_size, size-1)] = 0; | ||
941 | } | 941 | } |
942 | 942 | ||
943 | /* --- Directory cache live updating functions --- */ | 943 | /* --- Directory cache live updating functions --- */ |
@@ -1060,7 +1060,7 @@ void dircache_update_filesize(int fd, long newsize, long startcluster) | |||
1060 | 1060 | ||
1061 | if (fd_bindings[fd] == NULL) | 1061 | if (fd_bindings[fd] == NULL) |
1062 | { | 1062 | { |
1063 | logf("dircache fd access error"); | 1063 | logf("dircache fd(%d) access error", fd); |
1064 | dircache_initialized = false; | 1064 | dircache_initialized = false; |
1065 | return ; | 1065 | return ; |
1066 | } | 1066 | } |