void path_parent_dir(char *path) { size_t len = strlen(path); if (len && path_char_is_slash(path[len - 1])) path[len - 1] = '\0'; path_basedir(path); }
static void set_basename(const char *path) { char *dst = NULL; global_t *global = global_get_ptr(); strlcpy(global->fullpath, path, sizeof(global->fullpath)); strlcpy(global->basename, path, sizeof(global->basename)); #ifdef HAVE_COMPRESSION /* Removing extension is a bit tricky for compressed files. * Basename means: * /file/to/path/game.extension should be: * /file/to/path/game * * Two things to consider here are: /file/to/path/ is expected * to be a directory and "game" is a single file. This is used for * states and srm default paths. * * For compressed files we have: * * /file/to/path/comp.7z#game.extension and * /file/to/path/comp.7z#folder/game.extension * * The choice I take here is: * /file/to/path/game as basename. We might end up in a writable * directory then and the name of srm and states are meaningful. * */ path_basedir(global->basename); fill_pathname_dir(global->basename, path, "", sizeof(global->basename)); #endif if ((dst = strrchr(global->basename, '.'))) *dst = '\0'; }
int find_first_data_track(const char *cue_path, int32_t *offset, char *track_path, size_t max_len) { int rv, m, s, f; char tmp_token[MAX_TOKEN_LEN]; char cue_dir[PATH_MAX_LENGTH]; RFILE *fd; strlcpy(cue_dir, cue_path, PATH_MAX_LENGTH); path_basedir(cue_dir); fd = retro_fopen(cue_path, RFILE_MODE_READ, -1); if (!fd) { RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path, strerror(errno)); return -errno; } RARCH_LOG("Parsing CUE file '%s'...\n", cue_path); while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0) { if (strcmp(tmp_token, "FILE") == 0) { get_token(fd, tmp_token, MAX_TOKEN_LEN); fill_pathname_join(track_path, cue_dir, tmp_token, max_len); } else if (strcasecmp(tmp_token, "TRACK") == 0) { get_token(fd, tmp_token, MAX_TOKEN_LEN); get_token(fd, tmp_token, MAX_TOKEN_LEN); if (strcasecmp(tmp_token, "AUDIO") == 0) continue; find_token(fd, "INDEX"); get_token(fd, tmp_token, MAX_TOKEN_LEN); get_token(fd, tmp_token, MAX_TOKEN_LEN); if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3) { RARCH_LOG("Error parsing time stamp '%s'\n", tmp_token); return -errno; } *offset = ((m * 60) * (s * 75) * f) * 25; RARCH_LOG("Found 1st data track on file '%s+%d'\n", track_path, *offset); rv = 0; goto clean; } } rv = -EINVAL; clean: retro_fclose(fd); return rv; }
/** * fill_pathname_basedir: * @out_dir : output directory * @in_path : input path * @size : size of output directory * * Copies base directory of @in_path into @out_path. * If in_path is a path without any slashes (relative current directory), * @out_path will get path "./". **/ void fill_pathname_basedir(char *out_dir, const char *in_path, size_t size) { if (out_dir != in_path) retro_assert(strlcpy(out_dir, in_path, size) < size); path_basedir(out_dir); }
static int file_decompressed(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t crc32, void *userdata) { char path[PATH_MAX_LENGTH]; decompress_state_t *dec = (decompress_state_t*)userdata; /* Ignore directories. */ if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\') goto next_file; /* Make directory */ fill_pathname_join(path, dec->target_dir, name, sizeof(path)); path_basedir(path); if (!path_mkdir(path)) goto error; fill_pathname_join(path, dec->target_dir, name, sizeof(path)); if (!zlib_perform_mode(path, valid_exts, cdata, cmode, csize, size, crc32, userdata)) goto error; RARCH_LOG("[deflate] Path: %s, CRC32: 0x%x\n", name, crc32); next_file: return 1; error: dec->callback_error = (char*)malloc(PATH_MAX_LENGTH); snprintf(dec->callback_error, PATH_MAX_LENGTH, "Failed to deflate %s.\n", path); return 0; }
void fill_pathname_abbreviate_special(char *out_path, const char *in_path, size_t size) { #if !defined(RARCH_CONSOLE) unsigned i; const char *candidates[3]; const char *notations[3]; char application_dir[PATH_MAX_LENGTH]; const char *home = getenv("HOME"); application_dir[0] = '\0'; /* application_dir could be zero-string. Safeguard against this. * * Keep application dir in front of home, moving app dir to a * new location inside home would break otherwise. */ /* ugly hack - use application_dir pointer before filling it in. C89 reasons */ candidates[0] = application_dir; candidates[1] = home; candidates[2] = NULL; notations [0] = ":"; notations [1] = "~"; notations [2] = NULL; fill_pathname_application_path(application_dir, sizeof(application_dir)); path_basedir(application_dir); for (i = 0; candidates[i]; i++) { if (!string_is_empty(candidates[i]) && strstr(in_path, candidates[i]) == in_path) { size_t src_size = strlcpy(out_path, notations[i], size); retro_assert(src_size < size); out_path += src_size; size -= src_size; in_path += strlen(candidates[i]); if (!path_char_is_slash(*in_path)) { retro_assert(strlcpy(out_path, path_default_slash(), size) < size); out_path++; size--; } break; /* Don't allow more abbrevs to take place. */ } } #endif retro_assert(strlcpy(out_path, in_path, size) < size); }
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size) { if (path_is_absolute(in_path)) rarch_assert(strlcpy(out_path, in_path, size) < size); else { rarch_assert(strlcpy(out_path, in_refpath, size) < size); path_basedir(out_path); rarch_assert(strlcat(out_path, in_path, size) < size); } }
void fill_pathname_expand_special(char *out_path, const char *in_path, size_t size) { #if !defined(RARCH_CONSOLE) if (*in_path == '~') { const char *home = getenv("HOME"); if (home) { size_t src_size = strlcpy(out_path, home, size); retro_assert(src_size < size); out_path += src_size; size -= src_size; in_path++; } } else if ((in_path[0] == ':') && ( (in_path[1] == '/') #ifdef _WIN32 || (in_path[1] == '\\') #endif ) ) { size_t src_size; char application_dir[PATH_MAX_LENGTH]; application_dir[0] = '\0'; fill_pathname_application_path(application_dir, sizeof(application_dir)); path_basedir(application_dir); src_size = strlcpy(out_path, application_dir, size); retro_assert(src_size < size); out_path += src_size; size -= src_size; in_path += 2; } #endif retro_assert(strlcpy(out_path, in_path, size) < size); }
void fill_pathname_abbreviate_special(char *out_path, const char *in_path, size_t size) { #if !defined(RARCH_CONSOLE) unsigned i; const char *home = getenv("HOME"); char application_dir[PATH_MAX]; fill_pathname_application_path(application_dir, sizeof(application_dir)); path_basedir(application_dir); /* application_dir could be zero-string. Safeguard against this. * * Keep application dir in front of home, moving app dir to a * new location inside home would break otherwise. */ const char *candidates[3] = { application_dir, home, NULL }; const char *notations[3] = { ":", "~", NULL }; for (i = 0; candidates[i]; i++) { if (*candidates[i] && strstr(in_path, candidates[i]) == in_path) { size_t src_size = strlcpy(out_path, notations[i], size); rarch_assert(src_size < size); out_path += src_size; size -= src_size; in_path += strlen(candidates[i]); if (!path_char_is_slash(*in_path)) { rarch_assert(strlcpy(out_path, path_default_slash(), size) < size); out_path++; size--; } break; /* Don't allow more abbrevs to take place. */ } } #endif rarch_assert(strlcpy(out_path, in_path, size) < size); }
static int zlib_extract_core_callback(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t crc32, void *userdata) { char path[PATH_MAX_LENGTH]; /* Make directory */ fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); path_basedir(path); if (!path_mkdir(path)) { RARCH_ERR("Failed to create directory: %s.\n", path); return 0; } /* Ignore directories. */ if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\') return 1; fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); RARCH_LOG("path is: %s, CRC32: 0x%x\n", path, crc32); if (!zlib_perform_mode(path, valid_exts, cdata, cmode, csize, size, crc32, userdata)) { if (cmode == 0) { RARCH_ERR("Failed to write file: %s.\n", path); return 0; } goto error; } return 1; error: RARCH_ERR("Failed to deflate to: %s.\n", path); return 0; }
static int zlib_extract_core_callback(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t crc32, void *userdata) { char path[PATH_MAX_LENGTH]; /* Make directory */ fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); path_basedir(path); if (!path_mkdir(path)) { RARCH_ERR("Failed to create directory: %s.\n", path); return 0; } /* Ignore directories. */ if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\') return 1; fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); RARCH_LOG("path is: %s, CRC32: 0x%x\n", path, crc32); switch (cmode) { case 0: /* Uncompressed */ write_file(path, cdata, size); break; case 8: /* Deflate */ zlib_inflate_data_to_file(path, valid_exts, cdata, csize, size, crc32); break; } return 1; }
void fill_pathname_basedir(char *out_dir, const char *in_path, size_t size) { rarch_assert(strlcpy(out_dir, in_path, size) < size); path_basedir(out_dir); }
int lutro_load(const char *path) { char mainfile[PATH_MAX_LENGTH]; char gamedir[PATH_MAX_LENGTH]; strlcpy(mainfile, path, PATH_MAX_LENGTH); strlcpy(gamedir, path, PATH_MAX_LENGTH); if (path_is_directory(mainfile)) fill_pathname_join(mainfile, gamedir, "main.lua", sizeof(mainfile)); else path_basedir(gamedir); if (!strcmp(path_get_extension(mainfile), "lutro")) { fill_pathname(gamedir, mainfile, "/", sizeof(gamedir)); lutro_unzip(mainfile, gamedir); fill_pathname_join(mainfile, gamedir, "main.lua", sizeof(mainfile)); } fill_pathname_slash(gamedir, sizeof(gamedir)); char package_path[PATH_MAX_LENGTH]; snprintf(package_path, PATH_MAX_LENGTH, ";%s?.lua;%s?/init.lua", gamedir, gamedir); lutro_set_package_path(L, package_path); if(luaL_dofile(L, mainfile)) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); return 0; } lua_getglobal(L, "lutro"); strlcpy(settings.gamedir, gamedir, PATH_MAX_LENGTH); lua_pushnumber(L, 0); lua_setfield(L, -2, "camera_x"); lua_pushnumber(L, 0); lua_setfield(L, -2, "camera_y"); lua_getfield(L, -1, "conf"); if (lua_isnoneornil(L, -1)) { puts("skipping custom configuration."); } else { lua_getfield(L, -2, "settings"); if(lua_pcall(L, 1, 0, 0)) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); return 0; } lua_getfield(L, -1, "settings"); lua_getfield(L, -1, "width"); settings.width = lua_tointeger(L, -1); lua_remove(L, -1); lua_getfield(L, -1, "height"); settings.height = lua_tointeger(L, -1); lua_remove(L, -1); lua_getfield(L, -1, "live_enable"); settings.live_enable = lua_toboolean(L, -1); lua_remove(L, -1); lua_getfield(L, -1, "live_call_load"); settings.live_call_load = lua_toboolean(L, -1); lua_remove(L, -1); } lua_pop(L, 1); // either lutro.settings or lutro.conf lutro_graphics_init(); #ifdef HAVE_INOTIFY if (settings.live_enable) lutro_live_init(); #endif lua_getfield(L, -1, "load"); if (lua_isnoneornil(L, -1)) { puts("skipping custom initialization."); } else { if(lua_pcall(L, 0, 0, 0)) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); return 0; } } lua_pop(L, 1); return 1; }
void path_set_redirect(void) { char new_savefile_dir[PATH_MAX_LENGTH]; char new_savestate_dir[PATH_MAX_LENGTH]; uint32_t library_name_hash = 0; bool check_library_name_hash = false; rarch_system_info_t *info = NULL; global_t *global = global_get_ptr(); const char *old_savefile_dir = dir_get(RARCH_DIR_SAVEFILE); const char *old_savestate_dir = dir_get(RARCH_DIR_SAVESTATE); new_savefile_dir[0] = new_savestate_dir[0] = '\0'; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); if (info && info->info.library_name && !string_is_empty(info->info.library_name)) library_name_hash = msg_hash_calculate(info->info.library_name); /* Initialize current save directories * with the values from the config. */ strlcpy(new_savefile_dir, old_savefile_dir, sizeof(new_savefile_dir)); strlcpy(new_savestate_dir, old_savestate_dir, sizeof(new_savestate_dir)); check_library_name_hash = (library_name_hash != 0); #ifdef HAVE_MENU check_library_name_hash = check_library_name_hash && (library_name_hash != MENU_VALUE_NO_CORE); #endif if (check_library_name_hash) { settings_t *settings = config_get_ptr(); /* per-core saves: append the library_name to the save location */ if ( settings->sort_savefiles_enable && !string_is_empty(old_savefile_dir)) { fill_pathname_join( new_savefile_dir, old_savefile_dir, info->info.library_name, sizeof(new_savefile_dir)); /* If path doesn't exist, try to create it, * if everything fails revert to the original path. */ if(!path_is_directory(new_savefile_dir) && !string_is_empty(new_savefile_dir)) { path_mkdir(new_savefile_dir); if(!path_is_directory(new_savefile_dir)) { RARCH_LOG("%s %s\n", msg_hash_to_str(MSG_REVERTING_SAVEFILE_DIRECTORY_TO), old_savefile_dir); strlcpy(new_savefile_dir, old_savefile_dir, sizeof(new_savefile_dir)); } } } /* per-core states: append the library_name to the save location */ if (settings->sort_savestates_enable && !string_is_empty(old_savestate_dir)) { fill_pathname_join( new_savestate_dir, old_savestate_dir, info->info.library_name, sizeof(new_savestate_dir)); /* If path doesn't exist, try to create it. * If everything fails, revert to the original path. */ if(!path_is_directory(new_savestate_dir) && !string_is_empty(new_savestate_dir)) { path_mkdir(new_savestate_dir); if(!path_is_directory(new_savestate_dir)) { RARCH_LOG("%s %s\n", msg_hash_to_str(MSG_REVERTING_SAVESTATE_DIRECTORY_TO), old_savestate_dir); strlcpy(new_savestate_dir, old_savestate_dir, sizeof(new_savestate_dir)); } } } } /* Set savefile directory if empty based on content directory */ if (string_is_empty(new_savefile_dir)) { strlcpy(new_savefile_dir, path_main_basename, sizeof(new_savefile_dir)); path_basedir(new_savefile_dir); } if (global) { if(path_is_directory(new_savefile_dir)) strlcpy(global->name.savefile, new_savefile_dir, sizeof(global->name.savefile)); if(path_is_directory(new_savestate_dir)) strlcpy(global->name.savestate, new_savestate_dir, sizeof(global->name.savestate)); if (path_is_directory(global->name.savefile)) { fill_pathname_dir(global->name.savefile, path_main_basename, file_path_str(FILE_PATH_SRM_EXTENSION), sizeof(global->name.savefile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO), global->name.savefile); } 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); } if (path_is_directory(global->name.cheatfile)) { fill_pathname_dir(global->name.cheatfile, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.cheatfile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_CHEATFILE_TO), global->name.cheatfile); } } dir_set(RARCH_DIR_CURRENT_SAVEFILE, new_savefile_dir); dir_set(RARCH_DIR_CURRENT_SAVESTATE, new_savestate_dir); }