예제 #1
0
/**
 * read_file:
 * @path             : path to file.
 * @buf              : buffer to allocate and read the contents of the
 *                     file into. Needs to be freed manually.
 * @length           : Number of items read, -1 on error.
 *
 * Read the contents of a file into @buf. Will call read_compressed_file
 * if path contains a compressed file, otherwise will call read_generic_file.
 *
 * Returns: 1 if file read, 0 on error.
 */
int read_file(const char *path, void **buf, ssize_t *length)
{
#ifdef HAVE_COMPRESSION
   if (path_contains_compressed_file(path))
   {
      if (read_compressed_file(path, buf, NULL, length))
         return 1;
   }
#endif
   return read_generic_file(path, buf, length);
}
예제 #2
0
파일: file_ops.c 프로젝트: Markko/RetroArch
/* Generic file loader. */
long read_file(const char *path, void **buf)
{
   /* Here we check, whether the file, we are about to read is
    * inside an archive, or not.
    *
    * We determine, whether a file is inside a compressed archive,
    * by checking for the # inside the URL.
    *
    * For example: fullpath: /home/user/game.7z/mygame.rom
    * carchive_path: /home/user/game.7z
    * */
#ifdef HAVE_COMPRESSION
   if (path_contains_compressed_file(path))
      return read_compressed_file(path,buf,0);
#endif
   return read_generic_file(path,buf);
}
예제 #3
0
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;
}
예제 #4
0
static bool load_content_need_fullpath(
      struct retro_game_info *info, unsigned i,
      struct string_list* additional_path_allocs,
      bool need_fullpath, const char *path)
{
#ifdef HAVE_COMPRESSION
   ssize_t len;
   union string_list_elem_attr attributes;
   char new_path[PATH_MAX_LENGTH]    = {0};
   char new_basedir[PATH_MAX_LENGTH] = {0};
   bool ret                          = false;
   settings_t *settings              = config_get_ptr();
   global_t   *global                = global_get_ptr();
   rarch_system_info_t      *sys_info= rarch_system_info_get_ptr();

   if (sys_info && sys_info->info.block_extract)
      return true;

   if (!need_fullpath)
      return true;

   if (!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->extraction_directory,
         sizeof(new_basedir));

   if ((!strcmp(new_basedir, "")) ||
         !path_is_directory(new_basedir))
   {
      RARCH_WARN("Tried extracting to extraction directory, but "
            "extraction directory was not set or found. "
            "Setting extraction 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 = read_compressed_file(path,NULL,new_path, &len);

   if (!ret || len < 0)
   {
      RARCH_ERR("%s \"%s\".\n",
            msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE),
            path);
      return false;
   }

   string_list_append(additional_path_allocs,new_path, attributes);
   info[i].path =
      additional_path_allocs->elems
      [additional_path_allocs->size -1 ].data;

   /* global->temporary_content is initialized in init_content_file
    * The following part takes care of cleanup of the unzipped files
    * after exit.
    */
   rarch_assert(global->temporary_content != NULL);
   string_list_append(global->temporary_content,
         new_path, attributes);

#endif
   return true;
}