void dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort, const dir_sort_options_t * sort_op, const char *fltr) { DIR *dirp; struct dirent *dp; int link_to_dir, stale_link; struct stat st; file_entry_t *fentry; /* ".." (if any) must be the first entry in the list */ if (!dir_list_init (list)) return; fentry = &list->list[0]; if (dir_get_dotdot_stat (vpath, &st)) fentry->st = st; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); return; } tree_store_start_check (vpath); { const char *vpath_str; vpath_str = vfs_path_as_str (vpath); /* Do not add a ".." entry to the root directory */ if ((vpath_str[0] == PATH_SEP) && (vpath_str[1] == '\0')) list->len--; } while ((dp = mc_readdir (dirp)) != NULL) { if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link)) continue; if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0)) goto ret; if ((list->len & 31) == 0) rotate_dash (TRUE); } dir_list_sort (list, sort, sort_op); ret: mc_closedir (dirp); tree_store_end_check (); rotate_dash (FALSE); }
/* Return the nth directory, or NULL of n is out of range. */ const char * dir_list_nth (int n) { /* The default value of the list consists of the single directory ".". */ if (directory == NULL) dir_list_append ("."); if (n < 0 || n >= directory->nitems) return NULL; return directory->item[n]; }
void dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort, const dir_sort_options_t * sort_op, const char *fltr) { DIR *dirp; struct dirent *dp; int i, link_to_dir, stale_link; struct stat st; int marked_cnt; GHashTable *marked_files; const char *tmp_path; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); dir_list_clean (list); dir_list_init (list); return; } tree_store_start_check (vpath); marked_files = g_hash_table_new (g_str_hash, g_str_equal); alloc_dir_copy (list->len); for (marked_cnt = i = 0; i < list->len; i++) { file_entry_t *fentry, *dfentry; fentry = &list->list[i]; dfentry = &dir_copy.list[i]; dfentry->fnamelen = fentry->fnamelen; dfentry->fname = g_strndup (fentry->fname, fentry->fnamelen); dfentry->f.marked = fentry->f.marked; dfentry->f.dir_size_computed = fentry->f.dir_size_computed; dfentry->f.link_to_dir = fentry->f.link_to_dir; dfentry->f.stale_link = fentry->f.stale_link; dfentry->sort_key = NULL; dfentry->second_sort_key = NULL; if (fentry->f.marked) { g_hash_table_insert (marked_files, dfentry->fname, dfentry); marked_cnt++; } } /* save len for later dir_list_clean() */ dir_copy.len = list->len; /* Add ".." except to the root directory. The ".." entry (if any) must be the first in the list. */ tmp_path = vfs_path_get_by_index (vpath, 0)->path; if (vfs_path_elements_count (vpath) == 1 && IS_PATH_SEP (tmp_path[0]) && tmp_path[1] == '\0') { /* root directory */ dir_list_clean (list); } else { dir_list_clean (list); if (!dir_list_init (list)) { dir_list_clean (&dir_copy); return; } if (dir_get_dotdot_stat (vpath, &st)) { file_entry_t *fentry; fentry = &list->list[0]; fentry->st = st; } } while ((dp = mc_readdir (dirp)) != NULL) { file_entry_t *fentry; if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link)) continue; if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0)) { mc_closedir (dirp); /* Norbert (Feb 12, 1997): Just in case someone finds this memory leak: -1 means big trouble (at the moment no memory left), I don't bother with further cleanup because if one gets to this point he will have more problems than a few memory leaks and because one 'dir_list_clean' would not be enough (and because I don't want to spent the time to make it working, IMHO it's not worthwhile). dir_list_clean (&dir_copy); */ tree_store_end_check (); g_hash_table_destroy (marked_files); return; } fentry = &list->list[list->len - 1]; fentry->f.marked = 0; /* * If we have marked files in the copy, scan through the copy * to find matching file. Decrease number of remaining marks if * we copied one. */ if (marked_cnt > 0 && g_hash_table_lookup (marked_files, dp->d_name) != NULL) { fentry->f.marked = 1; marked_cnt--; } if ((list->len & 15) == 0) rotate_dash (TRUE); } mc_closedir (dirp); tree_store_end_check (); g_hash_table_destroy (marked_files); dir_list_sort (list, sort, sort_op); dir_list_clean (&dir_copy); rotate_dash (FALSE); }
static core_info_list_t *core_info_list_new(const char *path, const char *libretro_info_dir, const char *exts, bool dir_show_hidden_files) { size_t i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; const char *path_basedir = libretro_info_dir; struct string_list *contents = string_list_new(); bool ok = dir_list_append(contents, path, exts, false, dir_show_hidden_files, false, false); #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP /* UWP: browse the optional packages for additional cores */ struct string_list *core_packages = string_list_new(); uwp_fill_installed_core_packages(core_packages); for (i = 0; i < core_packages->size; i++) { dir_list_append(contents, core_packages->elems[i].data, exts, false, dir_show_hidden_files, false, false); } string_list_free(core_packages); #else /* Keep the old 'directory not found' behavior */ if (!ok) { string_list_free(contents); contents = NULL; } #endif if (!contents) return NULL; core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); if (!core_info) goto error; core_info_list->list = core_info; core_info_list->count = contents->size; for (i = 0; i < contents->size; i++) { size_t info_path_size = PATH_MAX_LENGTH * sizeof(char); char *info_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); info_path[0] = '\0'; if ( core_info_list_iterate(info_path, info_path_size, path_basedir, contents, i) && path_is_valid(info_path)) { char *tmp = NULL; bool tmp_bool = false; unsigned count = 0; config_file_t *conf = config_file_new(info_path); free(info_path); if (!conf) continue; if (config_get_string(conf, "display_name", &tmp) && !string_is_empty(tmp)) { core_info[i].display_name = strdup(tmp); free(tmp); tmp = NULL; } if (config_get_string(conf, "display_version", &tmp) && !string_is_empty(tmp)) { core_info[i].display_version = strdup(tmp); free(tmp); tmp = NULL; } if (config_get_string(conf, "corename", &tmp) && !string_is_empty(tmp)) { core_info[i].core_name = strdup(tmp); free(tmp); tmp = NULL; } if (config_get_string(conf, "systemname", &tmp) && !string_is_empty(tmp)) { core_info[i].systemname = strdup(tmp); free(tmp); tmp = NULL; } if (config_get_string(conf, "systemid", &tmp) && !string_is_empty(tmp)) { core_info[i].system_id = strdup(tmp); free(tmp); tmp = NULL; } if (config_get_string(conf, "manufacturer", &tmp) && !string_is_empty(tmp)) { core_info[i].system_manufacturer = strdup(tmp); free(tmp); tmp = NULL; } config_get_uint(conf, "firmware_count", &count); core_info[i].firmware_count = count; if (config_get_string(conf, "supported_extensions", &tmp) && !string_is_empty(tmp)) { core_info[i].supported_extensions = strdup(tmp); core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "authors", &tmp) && !string_is_empty(tmp)) { core_info[i].authors = strdup(tmp); core_info[i].authors_list = string_split(core_info[i].authors, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "permissions", &tmp) && !string_is_empty(tmp)) { core_info[i].permissions = strdup(tmp); core_info[i].permissions_list = string_split(core_info[i].permissions, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "license", &tmp) && !string_is_empty(tmp)) { core_info[i].licenses = strdup(tmp); core_info[i].licenses_list = string_split(core_info[i].licenses, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "categories", &tmp) && !string_is_empty(tmp)) { core_info[i].categories = strdup(tmp); core_info[i].categories_list = string_split(core_info[i].categories, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "database", &tmp) && !string_is_empty(tmp)) { core_info[i].databases = strdup(tmp); core_info[i].databases_list = string_split(core_info[i].databases, "|"); free(tmp); tmp = NULL; } if (config_get_string(conf, "notes", &tmp) && !string_is_empty(tmp)) { core_info[i].notes = strdup(tmp); core_info[i].note_list = string_split(core_info[i].notes, "|"); free(tmp); tmp = NULL; } if (tmp) free(tmp); tmp = NULL; if (config_get_bool(conf, "supports_no_game", &tmp_bool)) core_info[i].supports_no_game = tmp_bool; if (config_get_bool(conf, "database_match_archive_member", &tmp_bool)) core_info[i].database_match_archive_member = tmp_bool; core_info[i].config_data = conf; } else free(info_path); if (!string_is_empty(contents->elems[i].data)) core_info[i].path = strdup(contents->elems[i].data); if (!core_info[i].display_name) core_info[i].display_name = strdup(path_basename(core_info[i].path)); } if (core_info_list) { core_info_list_resolve_all_extensions(core_info_list); core_info_list_resolve_all_firmware(core_info_list); } string_list_free(contents); return core_info_list; error: if (contents) string_list_free(contents); core_info_list_free(core_info_list); return NULL; }