static int cache_scan(Eet_File *ef, Eina_Inarray *stack, const char *path, const char *base_id, int priority, int recurse, int *changed) { char *file_id = NULL; char id[PATH_MAX]; Eina_Iterator *it; Eina_File_Direct_Info *info; struct stat st; int ret = 1; if (!ecore_file_is_dir(path)) return 1; if (stat(path, &st) == -1) return 1; if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return 1; eina_inarray_push(stack, &st); it = eina_file_stat_ls(path); if (!it) goto end; id[0] = '\0'; EINA_ITERATOR_FOREACH(it, info) { const char *fname = info->path + info->name_start; if (info->path[info->name_start] == '.') continue; if (base_id) { if (*base_id) snprintf(id, sizeof(id), "%s-%s", base_id, fname); else { strncpy(id, fname, PATH_MAX); id[PATH_MAX - 1] = 0; } file_id = id; } if (((info->type == EINA_FILE_LNK) && (ecore_file_is_dir(info->path))) || (info->type == EINA_FILE_DIR)) { if (recurse) { ret = cache_scan(ef, stack, info->path, file_id, priority, recurse, changed); if (!ret) break; } } else { ret = cache_add(ef, info->path, file_id, priority, changed); if (!ret) break; } } eina_iterator_free(it); end: eina_inarray_pop(stack); return ret; }
static int cache_scan(const char *path, const char *base_id, int priority, int recurse, int *changed) { char *file_id = NULL; char id[PATH_MAX]; char buf[PATH_MAX]; Eina_Iterator *it; Eina_File_Direct_Info *info; if (!ecore_file_is_dir(path)) return 1; it = eina_file_direct_ls(path); if (!it) return 1; id[0] = '\0'; EINA_ITERATOR_FOREACH(it, info) { const char *fname; fname = info->path + info->name_start; if (base_id) { if (*base_id) snprintf(id, sizeof(id), "%s-%s", base_id, fname); else strcpy(id, fname); file_id = id; } snprintf(buf, sizeof(buf), "%s/%s", path, fname); if (ecore_file_is_dir(buf)) { if (recurse) cache_scan(buf, file_id, priority, recurse, changed); } else { if (!cache_add(buf, file_id, priority, changed)) { eina_iterator_free(it); return 0; } } } eina_iterator_free(it); return 1; }
EINA_LIST_FOREACH(extra_dirs, l, path) { eina_inarray_flush(stack); if (!cache_scan(stack, path, NULL, priority, 0, &changed)) goto error; }
int main(int argc, char **argv) { /* TODO: * - Add file monitor on files, so that we catch changes on files * during whilst this program runs. * - Maybe linger for a while to reduce number of cache re-creates. */ Efreet_Cache_Hash hash; Efreet_Cache_Version version; Eina_List *dirs = NULL; Eina_List *systemdirs = NULL; Eina_List *extra_dirs = NULL; Eina_List *l = NULL; Eina_Inarray *stack = NULL; int priority = 0; char *dir = NULL; char *path; int lockfd = -1, tmpfd; int changed = 0; int i; char file[PATH_MAX] = { '\0' }; char util_file[PATH_MAX] = { '\0' }; mode_t um; if (!eina_init()) goto eina_error; _efreet_desktop_cache_log_dom = eina_log_domain_register("efreet_desktop_cache", EFREET_DEFAULT_LOG_COLOR); if (_efreet_desktop_cache_log_dom < 0) { EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_desktop_cache."); return -1; } for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-v")) eina_log_domain_level_set("efreet_desktop_cache", EINA_LOG_LEVEL_DBG); else if ((!strcmp(argv[i], "-h")) || (!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--h")) || (!strcmp(argv[i], "--help"))) { printf("Options:\n"); printf(" -v Verbose mode\n"); printf(" -d dir1 dir2 Extra dirs\n"); exit(0); } else if (!strcmp(argv[i], "-d")) { while ((i < (argc - 1)) && (argv[(i + 1)][0] != '-')) extra_dirs = eina_list_append(extra_dirs, argv[++i]); } } extra_dirs = eina_list_sort(extra_dirs, -1, EINA_COMPARE_CB(strcmp)); #ifdef HAVE_SYS_RESOURCE_H setpriority(PRIO_PROCESS, 0, 19); #elif _WIN32 SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); #endif /* init external subsystems */ if (!eet_init()) goto eet_error; if (!ecore_init()) goto ecore_error; efreet_cache_update = 0; /* finish efreet init */ if (!efreet_init()) goto efreet_error; /* create homedir */ snprintf(file, sizeof(file), "%s/efreet", efreet_cache_home_get()); if (!ecore_file_exists(file)) { if (!ecore_file_mkpath(file)) goto efreet_error; efreet_setowner(file); } /* lock process, so that we only run one copy of this program */ lockfd = cache_lock_file(); if (lockfd == -1) goto efreet_error; edd = efreet_desktop_edd(); if (!edd) goto edd_error; /* read user dirs from old cache */ ef = eet_open(efreet_desktop_util_cache_file(), EET_FILE_MODE_READ); if (ef) { old_file_ids = eet_data_read(ef, efreet_hash_string_edd(), "file_id"); eet_close(ef); } /* create cache */ snprintf(file, sizeof(file), "%s.XXXXXX", efreet_desktop_cache_file()); /* set secure umask for temporary files */ um = umask(0077); tmpfd = mkstemp(file); umask(um); if (tmpfd < 0) goto error; close(tmpfd); ef = eet_open(file, EET_FILE_MODE_READ_WRITE); if (!ef) goto error; snprintf(util_file, sizeof(util_file), "%s.XXXXXX", efreet_desktop_util_cache_file()); /* set secure umask for temporary files */ um = umask(0077); tmpfd = mkstemp(util_file); umask(um); if (tmpfd < 0) goto error; close(tmpfd); util_ef = eet_open(util_file, EET_FILE_MODE_READ_WRITE); if (!util_ef) goto error; /* write cache version */ version.major = EFREET_DESKTOP_UTILS_CACHE_MAJOR; version.minor = EFREET_DESKTOP_UTILS_CACHE_MINOR; eet_data_write(util_ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1); version.major = EFREET_DESKTOP_CACHE_MAJOR; version.minor = EFREET_DESKTOP_CACHE_MINOR; eet_data_write(ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1); desktops = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_desktop_free)); file_ids = eina_hash_string_superfast_new(NULL); paths = eina_hash_string_superfast_new(NULL); mime_types = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); categories = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); startup_wm_class = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); name = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); generic_name = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); comment = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); exec = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free)); dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(), "applications"); if (!dirs) goto error; stack = eina_inarray_new(sizeof(struct stat), 16); if (!stack) goto error; EINA_LIST_FREE(dirs, path) { char file_id[PATH_MAX] = { '\0' }; eina_inarray_flush(stack); if (!cache_scan(stack, path, file_id, priority++, 1, &changed)) goto error; systemdirs = eina_list_append(systemdirs, path); }