Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.
My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
diff --git a/apps/tagcache.c b/apps/tagcache.c index 679d7cb..81e574a 100644 #include <stdio.h> #include <stdlib.h> #include <ctype.h> +#ifdef APPLICATION +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> /* lstat() */ +#endif #include "config.h" #include "ata_idle_notify.h" #include "thread.h" #include "settings.h" #include "dir.h" #include "structec.h" +#include "debug.h" #ifndef __PCTOOL__ #include "lang.h" static void __attribute__ ((noinline)) check_ignore(const char *dirname, *unignore = file_exists(newpath); } +static struct search_roots_ll { + const char * path; + struct search_roots_ll * next; +} roots_ll; + +#ifdef APPLICATION +static bool add_search_root(const char *name) +{ + struct search_roots_ll * this; + char target[MAX_PATH]; + ssize_t len; + len = readlink(name, target, sizeof(target)); + if (len < 0) + return false; + target[len] = '\0'; + + for(this = &roots_ll; this && this->next; this = this->next) + { + /* check if the link target is inside of an existing search root + * don't add if target is inside, we'll scan it later */ + if (strstr(this->path, target)) + return false; + } + + this->next = malloc(sizeof(struct search_roots_ll)); + this = this->next; + this->path = strdup(target); + this->next = NULL; + return true; +} + +static void free_search_roots(struct search_roots_ll * start) +{ + if (start->next) + { + free_search_roots(start->next); + free(start->next); + } + free((void*)start->path); +} +#endif static bool check_dir(const char *dirname, int add_files) { static bool check_dir(const char *dirname, int add_files) logf("tagcache: opendir(%s) failed", dirname); return false; } - + printf("scanning %s\n", dirname); /* check for a database.ignore and database.unignore */ check_ignore(dirname, &ignore, &unignore); static bool check_dir(const char *dirname, int add_files) #endif { struct dirent *entry; +#ifdef APPLICATION + /* save some stack, it's safe because we don't use it after recursive calls */ + static struct stat st; + if (lstat(dirname, &st)) + { + success = false; + break; + } + if (S_ISLNK(st.st_mode)) + { /* don't follow symlinks. + * we already went through the target or we will do later so + * pretent success */ + add_search_root(dirname); + success = true; + break; + } +#endif entry = readdir(dir); if (entry == NULL) void tagcache_build(const char *path) /* Scan for new files. */ memset(&header, 0, sizeof(struct tagcache_header)); write(cachefd, &header, sizeof(struct tagcache_header)); + path = "/home/kugel/rbdev/rockbox-git/build-sdlapp"; - if (strcmp("/", path) != 0) - strcpy(curpath, path); - ret = check_dir(path, true); - + ret = true; + roots_ll.path = path; + roots_ll.next = NULL; + struct search_roots_ll * this; + /* check_dir might add new roots */ + for(this = &roots_ll; this; this = this->next) + { + strcpy(curpath, this->path); + ret = ret && check_dir(this->path, true); + } +#ifdef APPLICATION + if (roots_ll.next) + free_search_roots(roots_ll.next); +#endif /* Write the header. */ header.magic = TAGCACHE_MAGIC; header.datasize = data_size; |