/** * path_mkdir_norecurse: * @dir : directory * * Create directory on filesystem. * * Returns: true (1) if directory could be created, otherwise false (0). **/ bool mkdir_norecurse(const char *dir) { int ret; #if defined(_WIN32) ret = _mkdir(dir); #elif defined(IOS) ret = mkdir(dir, 0755); #elif defined(VITA) || defined(PSP) ret = sceIoMkdir(dir, 0777); #else ret = mkdir(dir, 0750); #endif /* Don't treat this as an error. */ #if defined(VITA) if ((ret == SCE_ERROR_ERRNO_EEXIST) && path_is_directory(dir)) ret = 0; #elif defined(PSP) if ((ret == -1) && path_is_directory(dir)) ret = 0; #else if (ret < 0 && errno == EEXIST && path_is_directory(dir)) ret = 0; #endif if (ret < 0) printf("mkdir(%s) error: %s.\n", dir, strerror(errno)); return ret == 0; }
/** * * retro_dirent_is_dir: * @rdir : pointer to the directory entry. * @path : path to the directory entry. * * Is the directory listing entry a directory? * * Returns: true if directory listing entry is * a directory, false if not. */ bool retro_dirent_is_dir(struct RDIR *rdir, const char *path) { #if defined(_WIN32) const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry; return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #elif defined(PSP) || defined(VITA) const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry; #if defined(PSP) return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; #elif defined(VITA) return PSP2_S_ISDIR(entry->d_stat.st_mode); #endif #elif defined(__CELLOS_LV2__) CellFsDirent *entry = (CellFsDirent*)&rdir->entry; return (entry->d_type == CELL_FS_TYPE_DIRECTORY); #elif defined(DT_DIR) const struct dirent *entry = (const struct dirent*)rdir->entry; if (entry->d_type == DT_DIR) return true; /* This can happen on certain file systems. */ if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) return path_is_directory(path); return false; #else /* dirent struct doesn't have d_type, do it the slow way ... */ return path_is_directory(path); #endif }
bool assureDirectoryExists(const Common::String &dir, const char *prefix) { // Check whether the prefix exists if one is supplied. if (prefix) { if (!path_is_valid(prefix)) return false; else if (!path_is_directory(prefix)) return false; } // Obtain absolute path. Common::String path; if (prefix) { path = prefix; path += '/'; path += dir; } else { path = dir; } path = Common::normalizePath(path, '/'); const Common::String::iterator end = path.end(); Common::String::iterator cur = path.begin(); if (*cur == '/') ++cur; do { if (cur + 1 != end) { if (*cur != '/') continue; // It is kind of ugly and against the purpose of Common::String to // insert 0s inside, but this is just for a local string and // simplifies the code a lot. *cur = '\0'; } if (!mkdir_norecurse(path.c_str())) { if (errno == EEXIST) { if (!path_is_valid(path.c_str())) return false; else if (!path_is_directory(path.c_str())) return false; } else return false; } *cur = '/'; } while (cur++ != end); return true; }
bool FileUtilsExtension::delete_folder_tree(const std::string& directory_name) { #ifndef WIN32 DIR* dp; struct dirent* ep; dp = opendir(directory_name.c_str()); while ((ep = readdir(dp)) != NULL) { if (std::string(ep->d_name) == "." || std::string(ep->d_name) == "..") continue; std::string p_buf = directory_name + "/" + ep->d_name; //"%s/%s" if (path_is_directory(p_buf)) delete_folder_tree(p_buf); else unlink(p_buf.c_str()); } closedir(dp); return (0 == rmdir(directory_name.c_str())); #else BOOL ret = RemoveDirectory((LPCWSTR)directory_name.c_str()); if (!ret) { cocos2d::log("FileUtilsExtension::delete_folder_tree failed with error %ld", GetLastError()); } return !!ret; #endif }
static bool dirent_is_directory(const char *path, const struct dirent *entry) { #if defined(PSP) return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; #elif defined(DT_DIR) if (entry->d_type == DT_DIR) return true; else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */ || entry->d_type == DT_LNK) return path_is_directory(path); return false; #else /* dirent struct doesn't have d_type, do it the slow way ... */ return path_is_directory(path); #endif }
void POSIXFilesystemNode::setFlags() { const char *fspath = _path.c_str(); _isValid = path_is_valid(fspath); _isDirectory = path_is_directory(fspath); }
bool CONFIG::get_config_include_path(POOL_MEM &full_path, const char *config_dir) { bool found = false; if (m_config_include_dir) { /* * Set full_path to the initial part of the include path, * so it can be used as result, even on errors. * On success, full_path will be overwritten with the full path. */ full_path.strcpy(config_dir); path_append(full_path, m_config_include_dir); if (path_is_directory(full_path)) { m_config_dir = bstrdup(config_dir); /* * Set full_path to wildcard path. */ if (get_path_of_resource(full_path, NULL, NULL, NULL, true)) { m_use_config_include_dir = true; found = true; } } } return found; }
static bool create_directories_recursivey(const string& path) { if(path_is_directory(path)) { /* Directory already exists, nothing to do. */ return true; } if(path_exists(path)) { /* File exists and it's not a directory. */ return false; } string parent = path_dirname(path); if(parent.size() > 0 && parent != path) { if(!create_directories_recursivey(parent)) { return false; } } #ifdef _WIN32 wstring path_wc = string_to_wstring(path); return _wmkdir(path_wc.c_str()) == 0; #else return mkdir(path.c_str(), 0777) == 0; #endif }
static void delete_folder_tree( const char *directory_name ) { DIR *dp; struct dirent *ep; char p_buf[1024] = {0}; int rc = 0; dp = opendir( directory_name ); rtems_test_assert( dp != NULL ); while ( ( ep = readdir( dp ) ) != NULL && rc == 0 ) { if ( 0 != strcmp( ".", ep->d_name ) && 0 != strcmp( "..", ep->d_name ) ) { snprintf( p_buf, sizeof( p_buf ), "%s/%s", directory_name, ep->d_name ); if ( path_is_directory( p_buf ) ) { delete_folder_tree( p_buf ); rc = rmdir( p_buf ); rtems_test_assert( rc == 0 ); rewinddir( dp ); } else { rc = unlink( p_buf ); rtems_test_assert( rc == 0 ); rewinddir( dp ); } } } rc = closedir( dp ); rtems_test_assert( rc == 0 ); }
bool ZipArchive::Open(const char* path) { if (path_is_directory(path)) return false; zip = zip_open(path, 0, NULL); return (zip != NULL); }
static void check_defaults_dir_create_dir(const char *path) { char new_path[PATH_MAX_LENGTH]; fill_pathname_expand_special(new_path, path, sizeof(new_path)); if (path_is_directory(new_path)) return; path_mkdir(new_path); }
void set_paths_redirect(const char *path) { global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* per-core saves: append the library_name to the save location */ if(global->system.info.library_name && strcmp(global->system.info.library_name,"No Core") && settings->sort_savefiles_enable) { strlcpy(orig_savefile_dir,global->savefile_dir,sizeof(global->savefile_dir)); fill_pathname_dir(global->savefile_dir,global->savefile_dir,global->system.info.library_name,sizeof(global->savefile_dir)); // if path doesn't exist try to create it, if everything fails revert to the original path if(!path_is_directory(global->savefile_dir)) if(!path_mkdir(global->savefile_dir)) strlcpy(global->savefile_dir,orig_savefile_dir,sizeof(global->savefile_dir)); } /* per-core states: append the library_name to the save location */ if (global->system.info.library_name && strcmp(global->system.info.library_name,"No Core") && settings->sort_savestates_enable) { strlcpy(orig_savestate_dir,global->savestate_dir,sizeof(global->savestate_dir)); fill_pathname_dir(global->savestate_dir,global->savestate_dir,global->system.info.library_name,sizeof(global->savestate_dir)); // if path doesn't exist try to create it, if everything fails revert to the original path if(!path_is_directory(global->savestate_dir)) if(!path_mkdir(global->savestate_dir)) strlcpy(global->savestate_dir,orig_savestate_dir,sizeof(global->savestate_dir)); } if(path_is_directory(global->savefile_dir)) strlcpy(global->savefile_name,global->savefile_dir,sizeof(global->savefile_dir)); if(path_is_directory(global->savestate_dir)) strlcpy(global->savestate_name,global->savestate_dir,sizeof(global->savestate_dir)); if (path_is_directory(global->savefile_name)) { fill_pathname_dir(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); RARCH_LOG("Redirecting save file to \"%s\".\n", global->savefile_name); } if (path_is_directory(global->savestate_name)) { fill_pathname_dir(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); RARCH_LOG("Redirecting save state to \"%s\".\n", global->savestate_name); } if (path_is_directory(global->cheatfile_name)) { fill_pathname_dir(global->cheatfile_name, global->basename, ".state", sizeof(global->cheatfile_name)); RARCH_LOG("Redirecting cheat file to \"%s\".\n", global->cheatfile_name); } }
void rarch_make_dir(const char *x, const char *name) { RARCH_LOG("Checking directory name %s [%s]\n", name, x); if (strlen(x) > 0) { if (!path_is_directory(x)) { RARCH_WARN("Directory \"%s\" does not exists, creating\n", x); if (mkdir((x), 0777) != 0) RARCH_ERR("Could not create directory \"%s\"\n", x); } } }
static bool path_mkdir_norecurse(const char *dir) { int ret; #if defined(_WIN32) ret = _mkdir(dir); #elif defined(IOS) ret = mkdir(dir, 0755); #else ret = mkdir(dir, 0750); #endif /* Don't treat this as an error. */ if (ret < 0 && errno == EEXIST && path_is_directory(dir)) ret = 0; if (ret < 0) RARCH_ERR("mkdir(%s) error: %s.\n", dir, strerror(errno)); return ret == 0; }
static void set_special_paths(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* First content file is the significant one. */ set_basename(argv[0]); global->subsystem_fullpaths = string_list_new(); rarch_assert(global->subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(global->subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (!global->has_set.state_path) fill_pathname_noext(global->name.savestate, global->name.base, ".state", sizeof(global->name.savestate)); if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, global->name.base, ".state", sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } /* If this is already set, * do not overwrite it as this was initialized before in * a menu or otherwise. */ if (settings->system_directory[0] == '\0') { RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n",argv[0]); /*fill_pathname_basedir(settings->system_directory, argv[0], sizeof(settings->system_directory));*/ } }
static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir) { if(path_exists(dir)) { directory_iterator it(dir), it_end; for(; it != it_end; ++it) { if(path_is_directory(it->path())) { path_files_md5_hash_recursive(hash, it->path()); } else { string filepath = it->path(); hash.append((const uint8_t*)filepath.c_str(), filepath.size()); hash.append_file(filepath); } } } }
bool CONFIG::get_config_file(POOL_MEM &full_path, const char *config_dir, const char *config_filename) { bool found = false; if (!path_is_directory(config_dir)) { return false; } if (config_filename) { full_path.strcpy(config_dir); if (path_append(full_path, config_filename)) { if (path_exists(full_path)) { m_config_dir = bstrdup(config_dir); found = true; } } } return found; }
static void set_special_paths(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* First content file is the significant one. */ set_basename(argv[0]); global->subsystem_fullpaths = string_list_new(); rarch_assert(global->subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(global->subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (!global->has_set_state_path) fill_pathname_noext(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); if (path_is_directory(global->savestate_name)) { fill_pathname_dir(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); RARCH_LOG("Redirecting save state to \"%s\".\n", global->savestate_name); } /* If this is already set, * do not overwrite it as this was initialized before in * a menu or otherwise. */ if (!*settings->system_directory) fill_pathname_basedir(settings->system_directory, argv[0], sizeof(settings->system_directory)); }
std::vector<std::string> FileUtilsExtension::content_of_folder(const std::string& path, const std::string& extension) { #ifndef WIN32 std::vector<std::string> ret; ret.clear(); if (!path_is_directory(path)) { return ret; } DIR* dp; struct dirent* ep; dp = opendir(path.c_str()); while ((ep = readdir(dp)) != NULL) { if (std::string(ep->d_name) == "." || std::string(ep->d_name) == "..") continue; if (!extension.length() || extension == p.pathExtension.lowercaseString.UTF8String) { ret.push_back(std::string(ep->d_name)); } } closedir(dp); return ret; #else int iRC = 0; std::vector<std::string> vecFiles; // Search 'c:' for '.avi' files including subdirectories iRC = SearchDirectory(vecFiles, path, extension); if (iRC) { vecFiles.clear(); } return vecFiles; #endif }
bool path_mkdir(const char *dir) { const char *target = NULL; /* Use heap. Real chance of stack overflow if we recurse too hard. */ char *basedir = strdup(dir); bool ret = true; if (!basedir) return false; path_parent_dir(basedir); if (!*basedir || !strcmp(basedir, dir)) { ret = false; goto end; } if (path_is_directory(basedir)) { target = dir; ret = path_mkdir_norecurse(dir); } else { target = basedir; ret = path_mkdir(basedir); if (ret) { target = dir; ret = path_mkdir_norecurse(dir); } } end: if (target && !ret) RARCH_ERR("Failed to create directory: \"%s\".\n", target); free(basedir); return ret; }
void path_set_special(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); /* First content file is the significant one. */ path_set_basename(argv[0]); subsystem_fullpaths = string_list_new(); retro_assert(subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (global) { if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL)) fill_pathname_noext(global->name.savestate, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate)); if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } } }
bool nk_wnd_file_picker(nk_menu_handle_t *nk, char* title, char* in, char* out, char* filter) { struct nk_panel layout; struct nk_context *ctx = &nk->ctx; const int id = NK_WND_FILE_PICKER; int i = 0; static file_list_t *drives = NULL; static struct string_list *files = NULL; settings_t *settings = config_get_ptr(); bool ret = false; if (!drives) { drives = (file_list_t*)calloc(1, sizeof(file_list_t)); frontend_driver_parse_drive_list(drives, false); } if (!string_is_empty(in) && string_is_empty(path)) { strlcpy(path, in, sizeof(path)); files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false); } if (!assets_loaded) load_icons(nk); if (nk_begin(ctx, title, nk_rect(10, 10, 500, 400), NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_MOVABLE| NK_WINDOW_BORDER)) { nk_layout_row_dynamic(ctx, 30, 4); if (drives->size == 0) { if(nk_button_image_label(ctx, icons.disk, "/", NK_TEXT_CENTERED)) { fill_pathname_join(path, "/", "", sizeof(path)); files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false); } } else { for (i = 0; i < drives->size; i++) { if(nk_button_image_label(ctx, icons.disk, drives->list[i].path, NK_TEXT_CENTERED)) { fill_pathname_join(path, drives->list[i].path, "", sizeof(path)); files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false); } } } nk_layout_row_dynamic(ctx, 30, 1); if (files) { for (i = 0; i < files->size; i++) { if (nk_button_image_label(ctx, path_is_directory(files->elems[i].data) ? icons.folder : icons.file, path_basename(files->elems[i].data), NK_TEXT_RIGHT)) { strlcpy (path, files->elems[i].data, sizeof(path)); if (path_is_directory (path)) files = dir_list_new(path, filter, true, settings->bools.show_hidden_files, true, false); } } } nk_layout_row_dynamic(ctx, 30, 1); { if (nk_button_text(ctx, "OK", 2)) { ret = true; strlcpy(out, path, sizeof(path)); nk->window[NK_WND_FILE_PICKER].open = false; path[0] = '\0'; } } } /* sort the dir list with directories first */ dir_list_sort(files, true); /* copy the path variable to out*/ /* save position and size to restore after context reset */ nk_wnd_set_state(nk, id, nk_window_get_position(ctx), nk_window_get_size(ctx)); nk_end(ctx); return ret; }
static void check_defaults_dir_create_dir(const char *path) { if (path_is_directory(path)) return; path_mkdir(path); }
static bool load_content_from_compressed_archive( struct string_list *temporary_content, struct retro_game_info *info, unsigned i, struct string_list* additional_path_allocs, bool need_fullpath, const char *path) { union string_list_elem_attr attributes; ssize_t new_path_len; char new_path[PATH_MAX_LENGTH]; char new_basedir[PATH_MAX_LENGTH]; bool ret = false; settings_t *settings = config_get_ptr(); rarch_system_info_t *sys_info= NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sys_info); if (sys_info && sys_info->info.block_extract) return true; if (!need_fullpath || !path_contains_compressed_file(path)) return true; RARCH_LOG("Compressed file in case of need_fullpath." " Now extracting to temporary directory.\n"); strlcpy(new_basedir, settings->cache_directory, sizeof(new_basedir)); if (string_is_empty(new_basedir) || !path_is_directory(new_basedir)) { RARCH_WARN("Tried extracting to cache directory, but " "cache directory was not set or found. " "Setting cache directory to directory " "derived by basename...\n"); fill_pathname_basedir(new_basedir, path, sizeof(new_basedir)); } attributes.i = 0; fill_pathname_join(new_path, new_basedir, path_basename(path), sizeof(new_path)); ret = content_file_compressed_read(path, NULL, new_path, &new_path_len); if (!ret || new_path_len < 0) { RARCH_ERR("%s \"%s\".\n", msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), path); return false; } RARCH_LOG("New path is: [%s]\n", new_path); string_list_append(additional_path_allocs, new_path, attributes); info[i].path = additional_path_allocs->elems[additional_path_allocs->size -1 ].data; if (!string_list_append(temporary_content, new_path, attributes)) return false; return true; }
bool ImageManager::get_image_metadata(const string& filename, void *builtin_data, ImageMetaData& metadata) { memset(&metadata, 0, sizeof(metadata)); if(builtin_data) { if(builtin_image_info_cb) { builtin_image_info_cb(filename, builtin_data, metadata); } else { return false; } if(metadata.is_float) { metadata.is_linear = true; metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; } else { metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; } return true; } /* Perform preliminary checks, with meaningful logging. */ if(!path_exists(filename)) { VLOG(1) << "File '" << filename << "' does not exist."; return false; } if(path_is_directory(filename)) { VLOG(1) << "File '" << filename << "' is a directory, can't use as image."; return false; } ImageInput *in = ImageInput::create(filename); if(!in) { return false; } ImageSpec spec; if(!in->open(filename, spec)) { delete in; return false; } metadata.width = spec.width; metadata.height = spec.height; metadata.depth = spec.depth; /* check the main format, and channel formats; * if any take up more than one byte, we'll need a float texture slot */ if(spec.format.basesize() > 1) { metadata.is_float = true; metadata.is_linear = true; } for(size_t channel = 0; channel < spec.channelformats.size(); channel++) { if(spec.channelformats[channel].basesize() > 1) { metadata.is_float = true; metadata.is_linear = true; } } /* check if it's half float */ if(spec.format == TypeDesc::HALF) metadata.is_half = true; /* basic color space detection, not great but better than nothing * before we do OpenColorIO integration */ if(metadata.is_float) { string colorspace = spec.get_string_attribute("oiio:ColorSpace"); metadata.is_linear = !(colorspace == "sRGB" || colorspace == "GammaCorrected" || (colorspace == "" && (strcmp(in->format_name(), "png") == 0 || strcmp(in->format_name(), "tiff") == 0 || strcmp(in->format_name(), "dpx") == 0 || strcmp(in->format_name(), "jpeg2000") == 0))); } else { metadata.is_linear = false; } /* set type and channels */ metadata.channels = spec.nchannels; if(metadata.is_half) { metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF; } else if(metadata.is_float) { metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; } else { metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; } in->close(); delete in; return true; }
bool ImageManager::file_load_image_generic(Image *img, ImageInput **in, int &width, int &height, int &depth, int &components) { if(img->filename == "") return false; if(!img->builtin_data) { /* NOTE: Error logging is done in meta data acquisition. */ if(!path_exists(img->filename) || path_is_directory(img->filename)) { return false; } /* load image from file through OIIO */ *in = ImageInput::create(img->filename); if(!*in) return false; ImageSpec spec = ImageSpec(); ImageSpec config = ImageSpec(); if(img->use_alpha == false) config.attribute("oiio:UnassociatedAlpha", 1); if(!(*in)->open(img->filename, spec, config)) { delete *in; *in = NULL; return false; } width = spec.width; height = spec.height; depth = spec.depth; components = spec.nchannels; } else { /* load image using builtin images callbacks */ if(!builtin_image_info_cb || !builtin_image_pixels_cb) return false; ImageMetaData metadata; builtin_image_info_cb(img->filename, img->builtin_data, metadata); width = metadata.width; height = metadata.height; depth = metadata.depth; components = metadata.channels; } /* we only handle certain number of components */ if(!(components >= 1 && components <= 4)) { if(*in) { (*in)->close(); delete *in; *in = NULL; } return false; } return true; }
static void rarch_init_savefile_paths(void) { global_t *global = global_get_ptr(); event_command(EVENT_CMD_SAVEFILES_DEINIT); global->savefiles = string_list_new(); rarch_assert(global->savefiles); if (*global->subsystem) { /* For subsystems, we know exactly which RAM types are supported. */ unsigned i, j; const struct retro_subsystem_info *info = libretro_find_subsystem_info( global->system.special, global->system.num_special, global->subsystem); /* We'll handle this error gracefully later. */ unsigned num_content = min(info ? info->num_roms : 0, global->subsystem_fullpaths ? global->subsystem_fullpaths->size : 0); bool use_sram_dir = path_is_directory(global->savefile_dir); for (i = 0; i < num_content; i++) { for (j = 0; j < info->roms[i].num_memory; j++) { union string_list_elem_attr attr; char path[PATH_MAX_LENGTH], ext[32]; const struct retro_subsystem_memory_info *mem = (const struct retro_subsystem_memory_info*) &info->roms[i].memory[j]; snprintf(ext, sizeof(ext), ".%s", mem->extension); if (use_sram_dir) { /* Redirect content fullpath to save directory. */ strlcpy(path, global->savefile_dir, sizeof(path)); fill_pathname_dir(path, global->subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } else { fill_pathname(path, global->subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } attr.i = mem->type; string_list_append(global->savefiles, path, attr); } } /* Let other relevant paths be inferred from the main SRAM location. */ if (!global->has_set_save_path) fill_pathname_noext(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); if (path_is_directory(global->savefile_name)) { fill_pathname_dir(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); RARCH_LOG("Redirecting save file to \"%s\".\n", global->savefile_name); } } else { char savefile_name_rtc[PATH_MAX_LENGTH]; union string_list_elem_attr attr; attr.i = RETRO_MEMORY_SAVE_RAM; string_list_append(global->savefiles, global->savefile_name, attr); /* Infer .rtc save path from save ram path. */ attr.i = RETRO_MEMORY_RTC; fill_pathname(savefile_name_rtc, global->savefile_name, ".rtc", sizeof(savefile_name_rtc)); string_list_append(global->savefiles, savefile_name_rtc, attr); } }
static bool load_content(const struct retro_subsystem_info *special, const struct string_list *content) { unsigned i; bool ret = true; struct string_list* additional_path_allocs = string_list_new(); struct retro_game_info *info = (struct retro_game_info*) calloc(content->size, sizeof(*info)); if (!info) return false; for (i = 0; i < content->size; i++) { const char *path = content->elems[i].data; int attr = content->elems[i].attr.i; bool need_fullpath = attr & 2; bool require_content = attr & 4; if (require_content && !*path) { RARCH_LOG("libretro core requires content, but nothing was provided.\n"); ret = false; goto end; } info[i].path = *path ? path : NULL; if (!need_fullpath && *path) { /* Load the content into memory. */ RARCH_LOG("Loading content file: %s.\n", path); /* First content file is significant, attempt to do patching, * CRC checking, etc. */ long size = i == 0 ? read_content_file(path, (void**)&info[i].data) : read_file(path, (void**)&info[i].data); if (size < 0) { RARCH_ERR("Could not read content file \"%s\".\n", path); ret = false; goto end; } info[i].size = size; } else { RARCH_LOG("Content loading skipped. Implementation will" " load it on its own.\n"); if (need_fullpath && path_contains_compressed_file(path)) { RARCH_LOG("Compressed file in case of need_fullpath." "Now extracting to temporary directory.\n"); if ((!strcmp(g_settings.extraction_directory,"")) || !path_is_directory(g_settings.extraction_directory)) { RARCH_ERR("Tried extracting to extraction directory, but " "extraction directory was not set or found. Exiting.\n"); rarch_assert(false); } char new_path[PATH_MAX]; union string_list_elem_attr attr; attr.i = 0; fill_pathname_join(new_path,g_settings.extraction_directory, path_basename(path),sizeof(new_path)); read_compressed_file(path,NULL,new_path); string_list_append(additional_path_allocs,new_path,attr); info[i].path = additional_path_allocs->elems [additional_path_allocs->size -1 ].data; } } } if (special) ret = pretro_load_game_special(special->id, info, content->size); else ret = pretro_load_game(*content->elems[0].data ? info : NULL); if (!ret) RARCH_ERR("Failed to load game.\n"); end: for (i = 0; i < content->size; i++) free((void*)info[i].data); string_list_free(additional_path_allocs); free(info); return ret; }
static int zarch_zui_render_lay_root_load(zui_t *zui, struct zui_tabbed *tabbed) { char parent_dir[PATH_MAX_LENGTH]; settings_t *settings = config_get_ptr(); core_info_list_t *list = NULL; parent_dir[0] = '\0'; if (zarch_zui_tab(zui, tabbed, "Load", 1)) { unsigned cwd_offset; if (!zui->load_cwd) zui->load_cwd = strdup(settings->directory.menu_content); if (!zui->load_dlist) { core_info_t *core_info = NULL; core_info_get_current_core(&core_info); zui->load_dlist = dir_list_new(zui->load_cwd, core_info->supported_extensions, true, true, false, true); dir_list_sort(zui->load_dlist, true); zui->load_dlist_first = 0; } cwd_offset = MIN(strlen(zui->load_cwd), 60); zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15, tabbed->tabline_size + 5 + 41, &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]); if (zarch_zui_button(zui, zui->width - 290 - 129, tabbed->tabline_size + 5, "Home")) zarch_zui_render_lay_root_load_free(zui); if (zui->load_dlist) { fill_pathname_parent_dir(parent_dir, zui->load_cwd, sizeof(parent_dir)); if (!string_is_empty(parent_dir) && zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73, " ..", 0, NULL, false /* TODO/FIXME */)) { zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir); } else { static int gamepad_index = 0; unsigned size = zui->load_dlist->size; unsigned i, j = 1; unsigned skip = 0; for (i = 0; i < size; ++i) { const char *basename = path_basename(zui->load_dlist->elems[i].data); if (basename[0] != '.') break; skip++; } if (zarch_zui_gamepad_input(zui, &gamepad_index, &zui->load_dlist_first, skip)) zui->load_dlist_first = gamepad_index; for (i = skip + zui->load_dlist_first; i < size; ++i) { char label[PATH_MAX_LENGTH]; const char *path = NULL; const char *basename = NULL; if (j > 10) break; label[0] = '\0'; path = zui->load_dlist->elems[i].data; basename = path_basename(path); *label = 0; strncat(label, " ", sizeof(label)-1); strncat(label, basename, sizeof(label)-1); if (path_is_directory(path)) strncat(label, "/", sizeof(label)-1); if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73 + j * ZUI_ITEM_SIZE_PX, label, i, NULL, gamepad_index == (signed)(i-skip))) { if (path_is_directory(path)) { zarch_zui_render_lay_root_load_set_new_path(zui, path); break; } zui->pick_cores = NULL; zui->pick_supported = 0; strlcpy(zui->pick_content, path, sizeof(zui->pick_content)); core_info_get_list(&list); core_info_list_get_supported_cores(list, path, &zui->pick_cores, &zui->pick_supported); zarch_layout = LAY_PICK_CORE; break; } j++; } } } } else if (zui->load_dlist) { dir_list_free(zui->load_dlist); zui->load_dlist = NULL; } return 0; }
static config_file_t *config_file_new_internal( const char *path, unsigned depth, config_file_cb_t *cb) { RFILE *file = NULL; struct config_file *conf = (struct config_file*)malloc(sizeof(*conf)); if (!conf) return NULL; conf->path = NULL; conf->entries = NULL; conf->tail = NULL; conf->last = NULL; conf->includes = NULL; conf->include_depth = 0; conf->guaranteed_no_duplicates = false ; if (!path || !*path) return conf; if (path_is_directory(path)) goto error; conf->path = strdup(path); if (!conf->path) goto error; conf->include_depth = depth; file = filestream_open(path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { free(conf->path); goto error; } while (!filestream_eof(file)) { char *line = NULL; struct config_entry_list *list = (struct config_entry_list*)malloc(sizeof(*list)); if (!list) { config_file_free(conf); filestream_close(file); return NULL; } list->readonly = false; list->key = NULL; list->value = NULL; list->next = NULL; line = filestream_getline(file); if (!line) { free(list); continue; } if (*line && parse_line(conf, list, line, cb)) { if (conf->entries) conf->tail->next = list; else conf->entries = list; conf->tail = list; if (cb != NULL && list->key != NULL && list->value != NULL) cb->config_file_new_entry_cb(list->key, list->value) ; } free(line); if (list != conf->tail) free(list); } filestream_close(file); return conf; error: free(conf); return NULL; }