diff options
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index ef642b1e3c..1f11f9e49f 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -4272,10 +4272,29 @@ static void __attribute__ ((noinline)) check_ignore(const char *dirname, | |||
4272 | *unignore = file_exists(newpath); | 4272 | *unignore = file_exists(newpath); |
4273 | } | 4273 | } |
4274 | 4274 | ||
4275 | /* max roots on native. on application more can be added via malloc() */ | ||
4276 | #define MAX_STATIC_ROOTS 12 | ||
4277 | |||
4275 | static struct search_roots_ll { | 4278 | static struct search_roots_ll { |
4276 | const char *path; | 4279 | const char *path; |
4277 | struct search_roots_ll * next; | 4280 | struct search_roots_ll * next; |
4278 | } roots_ll; | 4281 | } roots_ll[MAX_STATIC_ROOTS]; |
4282 | |||
4283 | /* check if the path is already included in the search roots, by the | ||
4284 | * means that the path itself or one of its parents folders is in the list */ | ||
4285 | static bool search_root_exists(const char *path) | ||
4286 | { | ||
4287 | struct search_roots_ll *this; | ||
4288 | for(this = &roots_ll[0]; this; this = this->next) | ||
4289 | { | ||
4290 | size_t root_len = strlen(this->path); | ||
4291 | /* check if the link target is inside of an existing search root | ||
4292 | * don't add if target is inside, we'll scan it later */ | ||
4293 | if (!strncmp(this->path, path, root_len)) | ||
4294 | return true; | ||
4295 | } | ||
4296 | return false; | ||
4297 | } | ||
4279 | 4298 | ||
4280 | #ifdef APPLICATION | 4299 | #ifdef APPLICATION |
4281 | /* | 4300 | /* |
@@ -4316,14 +4335,11 @@ static bool add_search_root(const char *name) | |||
4316 | if (realpath(target, abs_target) == NULL) | 4335 | if (realpath(target, abs_target) == NULL) |
4317 | return false; | 4336 | return false; |
4318 | 4337 | ||
4319 | for(this = &roots_ll; this; prev = this, this = this->next) | 4338 | if (search_root_exists(abs_target)) |
4320 | { | 4339 | return false; |
4321 | size_t root_len = strlen(this->path); | 4340 | |
4322 | /* check if the link target is inside of an existing search root | 4341 | /* get the end of the list */ |
4323 | * don't add if target is inside, we'll scan it later */ | 4342 | for(this = &roots_ll[0]; this; prev = this, this = this->next); |
4324 | if (!strncmp(this->path, abs_target, root_len)) | ||
4325 | return false; | ||
4326 | } | ||
4327 | 4343 | ||
4328 | if (prev) | 4344 | if (prev) |
4329 | { | 4345 | { |
@@ -4347,14 +4363,22 @@ static bool add_search_root(const char *name) | |||
4347 | return false; | 4363 | return false; |
4348 | } | 4364 | } |
4349 | 4365 | ||
4366 | static int free_search_root_single(struct search_roots_ll * start) | ||
4367 | { | ||
4368 | if (start < &roots_ll[0] && start >= &roots_ll[MAX_STATIC_ROOTS]) | ||
4369 | { | ||
4370 | free(start->next); | ||
4371 | return sizeof(struct search_roots_ll); | ||
4372 | } | ||
4373 | return 0; | ||
4374 | } | ||
4375 | |||
4350 | static int free_search_roots(struct search_roots_ll * start) | 4376 | static int free_search_roots(struct search_roots_ll * start) |
4351 | { | 4377 | { |
4352 | int ret = 0; | 4378 | int ret = 0; |
4353 | if (start->next) | 4379 | if (start->next) |
4354 | { | 4380 | { |
4355 | ret += free_search_roots(start->next); | 4381 | ret += free_search_root_single(start->next); |
4356 | ret += sizeof(struct search_roots_ll); | ||
4357 | free(start->next); | ||
4358 | } | 4382 | } |
4359 | return ret; | 4383 | return ret; |
4360 | } | 4384 | } |
@@ -4459,7 +4483,8 @@ void tagcache_screensync_enable(bool state) | |||
4459 | tc_stat.syncscreen = state; | 4483 | tc_stat.syncscreen = state; |
4460 | } | 4484 | } |
4461 | 4485 | ||
4462 | void tagcache_build(const char *path) | 4486 | |
4487 | static void do_tagcache_build(const char *path[]) | ||
4463 | { | 4488 | { |
4464 | struct tagcache_header header; | 4489 | struct tagcache_header header; |
4465 | bool ret; | 4490 | bool ret; |
@@ -4501,17 +4526,29 @@ void tagcache_build(const char *path) | |||
4501 | write(cachefd, &header, sizeof(struct tagcache_header)); | 4526 | write(cachefd, &header, sizeof(struct tagcache_header)); |
4502 | 4527 | ||
4503 | ret = true; | 4528 | ret = true; |
4504 | roots_ll.path = path; | 4529 | |
4505 | roots_ll.next = NULL; | 4530 | roots_ll[0].path = path[0]; |
4531 | roots_ll[0].next = NULL; | ||
4532 | /* i is for the path vector, j for the roots_ll array | ||
4533 | * path can be skipped , but root_ll entries can't */ | ||
4534 | for(int i = 1, j = 1; path[i] && j < MAX_STATIC_ROOTS; i++) | ||
4535 | { | ||
4536 | if (search_root_exists(path[i])) /* skip this path */ | ||
4537 | continue; | ||
4538 | |||
4539 | roots_ll[j].path = path[i]; | ||
4540 | roots_ll[j-1].next = &roots_ll[j]; | ||
4541 | j++; | ||
4542 | } | ||
4543 | |||
4506 | struct search_roots_ll * this; | 4544 | struct search_roots_ll * this; |
4507 | /* check_dir might add new roots */ | 4545 | /* check_dir might add new roots */ |
4508 | for(this = &roots_ll; this; this = this->next) | 4546 | for(this = &roots_ll[0]; this; this = this->next) |
4509 | { | 4547 | { |
4510 | strcpy(curpath, this->path); | 4548 | strcpy(curpath, this->path); |
4511 | ret = ret && check_dir(this->path, true); | 4549 | ret = ret && check_dir(this->path, true); |
4512 | } | 4550 | } |
4513 | if (roots_ll.next) | 4551 | free_search_roots(&roots_ll[0]); |
4514 | free_search_roots(roots_ll.next); | ||
4515 | 4552 | ||
4516 | /* Write the header. */ | 4553 | /* Write the header. */ |
4517 | header.magic = TAGCACHE_MAGIC; | 4554 | header.magic = TAGCACHE_MAGIC; |
@@ -4558,6 +4595,18 @@ void tagcache_build(const char *path) | |||
4558 | cpu_boost(false); | 4595 | cpu_boost(false); |
4559 | } | 4596 | } |
4560 | 4597 | ||
4598 | void tagcache_build(void) | ||
4599 | { | ||
4600 | char *vect[MAX_STATIC_ROOTS + 1]; /* +1 to ensure NULL sentinel */ | ||
4601 | char str[sizeof(global_settings.tagcache_scan_paths)]; | ||
4602 | strlcpy(str, global_settings.tagcache_scan_paths, sizeof(str)); | ||
4603 | |||
4604 | int res = split_string(str, ':', vect, MAX_STATIC_ROOTS); | ||
4605 | vect[res] = NULL; | ||
4606 | |||
4607 | do_tagcache_build((const char**)vect); | ||
4608 | } | ||
4609 | |||
4561 | #ifdef HAVE_TC_RAMCACHE | 4610 | #ifdef HAVE_TC_RAMCACHE |
4562 | static void load_ramcache(void) | 4611 | static void load_ramcache(void) |
4563 | { | 4612 | { |
@@ -4643,11 +4692,11 @@ static void tagcache_thread(void) | |||
4643 | case Q_REBUILD: | 4692 | case Q_REBUILD: |
4644 | remove_files(); | 4693 | remove_files(); |
4645 | remove(TAGCACHE_FILE_TEMP); | 4694 | remove(TAGCACHE_FILE_TEMP); |
4646 | tagcache_build("/"); | 4695 | tagcache_build(); |
4647 | break; | 4696 | break; |
4648 | 4697 | ||
4649 | case Q_UPDATE: | 4698 | case Q_UPDATE: |
4650 | tagcache_build("/"); | 4699 | tagcache_build(); |
4651 | #ifdef HAVE_TC_RAMCACHE | 4700 | #ifdef HAVE_TC_RAMCACHE |
4652 | load_ramcache(); | 4701 | load_ramcache(); |
4653 | #endif | 4702 | #endif |
@@ -4665,13 +4714,13 @@ static void tagcache_thread(void) | |||
4665 | { | 4714 | { |
4666 | load_ramcache(); | 4715 | load_ramcache(); |
4667 | if (tc_stat.ramcache && global_settings.tagcache_autoupdate) | 4716 | if (tc_stat.ramcache && global_settings.tagcache_autoupdate) |
4668 | tagcache_build("/"); | 4717 | tagcache_build(); |
4669 | } | 4718 | } |
4670 | else | 4719 | else |
4671 | #endif | 4720 | #endif |
4672 | if (global_settings.tagcache_autoupdate) | 4721 | if (global_settings.tagcache_autoupdate) |
4673 | { | 4722 | { |
4674 | tagcache_build("/"); | 4723 | tagcache_build(); |
4675 | 4724 | ||
4676 | /* This will be very slow unless dircache is enabled | 4725 | /* This will be very slow unless dircache is enabled |
4677 | or target is flash based, but do it anyway for | 4726 | or target is flash based, but do it anyway for |