Example #1
0
bool MDFNFILE::Open(const char *path, const void *known_ext, const char *purpose, const bool suppress_notfound_pe)
{
   FILE *fp;
   (void)known_ext;

   if (!(fp = fopen(path, "rb")))
      return FALSE;

   ::fseek(fp, 0, SEEK_SET);

   if (!MakeMemWrapAndClose(fp))
      return FALSE;

   const char *ld = (const char*)strrchr(path, '.');
   f_ext = strdup(ld ? ld + 1 : "");

   return(TRUE);
}
Example #2
0
bool MDFNFILE::Open(const char *path, const FileExtensionSpecStruct *known_ext, const char *purpose, const bool suppress_notfound_pe)
{
 unzFile tz;

 local_errno = 0;
 error_code = MDFNFILE_EC_OTHER;	// Set to 0 at the end if the function succeeds.

 //f_data = (uint8 *)0xDEADBEEF;

 // Try opening it as a zip file first
 if((tz = unzOpen(path)))
 {
  char tempu[1024];
  int errcode;

  if((errcode = unzGoToFirstFile(tz)) != UNZ_OK)
  {
   MDFN_PrintError(_("Could not seek to first file in ZIP archive: %s"), unzErrorString(errcode));
   unzClose(tz);

   return(NULL);
  }

  if(known_ext)
  {
   bool FileFound = FALSE;
   while(!FileFound)
   {
    size_t tempu_strlen;
    const FileExtensionSpecStruct *ext_search = known_ext;

    if((errcode = unzGetCurrentFileInfo(tz, 0, tempu, 1024, 0, 0, 0, 0)) != UNZ_OK)
    {
     MDFN_PrintError(_("Could not get file information in ZIP archive: %s"), unzErrorString(errcode));
     unzClose(tz);

     return(NULL);
    }

    tempu[1023] = 0;
    tempu_strlen = strlen(tempu);

    while(ext_search->extension && !FileFound)
    {
     size_t ttmeow = strlen(ext_search->extension);
     if(tempu_strlen >= ttmeow)
     {
      if(!strcasecmp(tempu + tempu_strlen - ttmeow, ext_search->extension))
       FileFound = TRUE;
     }
     ext_search++;
    }

    if(FileFound)
     break;

    if((errcode = unzGoToNextFile(tz)) != UNZ_OK)
    { 
     if(errcode != UNZ_END_OF_LIST_OF_FILE)
     {
      MDFN_PrintError(_("Error seeking to next file in ZIP archive: %s"), unzErrorString(errcode));
      unzClose(tz);
      return(NULL);
     }

     if((errcode = unzGoToFirstFile(tz)) != UNZ_OK)
     {
      MDFN_PrintError(_("Could not seek to first file in ZIP archive: %s"), unzErrorString(errcode));
      unzClose(tz);
      return(NULL);
     }
     break;     
    }

   } // end to while(!FileFound)
  } // end to if(ext)

  if((errcode = unzOpenCurrentFile(tz)) != UNZ_OK)
  {
   MDFN_PrintError(_("Could not open file in ZIP archive: %s"), unzErrorString(errcode));
   unzClose(tz);
   return(NULL);
  }

  if(!MakeMemWrapAndClose(tz, MDFN_FILETYPE_ZIP))
   return(0);

  char *ld = strrchr(tempu, '.');

  f_ext = strdup(ld ? ld + 1 : "");
 }
 else // If it's not a zip file, handle it as...another type of file!
 {
	FILE *fp;

  if(!(fp = fopen(path, "rb")))
  {
   ErrnoHolder ene(errno);
   local_errno = ene.Errno();

   if(ene.Errno() == ENOENT)
   {
    local_errno = ene.Errno();
    error_code = MDFNFILE_EC_NOTFOUND;
   }
   
   if(ene.Errno() != ENOENT || !suppress_notfound_pe)
    MDFN_PrintError(_("Error opening \"%s\": %s"), path, ene.StrError());

   return(0);
  }

  uint32 gzmagic;

  gzmagic = ::fgetc(fp);
  gzmagic |= ::fgetc(fp) << 8;
  gzmagic |= ::fgetc(fp) << 16;

  if(gzmagic != 0x088b1f)   /* Not gzip... */
  {
   ::fseek(fp, 0, SEEK_SET);

   if(!MakeMemWrapAndClose(fp, MDFN_FILETYPE_PLAIN))
    return(0);

   const char *ld = strrchr(path, '.');
   f_ext = strdup(ld ? ld + 1 : "");
  }
  else                  /* Probably gzip */
  {
    gzFile gzp;

    fclose(fp);

    // Clear errno so we can see if the error occurred within zlib or the C lib
    errno = 0;
    if(!(gzp = gzopen(path, "rb")))
    {
     if(errno != 0)
     {
      ErrnoHolder ene(errno);
      local_errno = ene.Errno();

      if(ene.Errno() == ENOENT)
      {
       local_errno = ene.Errno();
       error_code = MDFNFILE_EC_NOTFOUND;
      }

      if(ene.Errno() != ENOENT || !suppress_notfound_pe)
       MDFN_PrintError(_("Error opening \"%s\": %s"), path, ene.StrError());
     }
     else
      MDFN_PrintError(_("Error opening \"%s\": %s"), path, _("zlib error"));

     return(0);
    }

    if(!MakeMemWrapAndClose(gzp, MDFN_FILETYPE_GZIP))
     return(0);

    char *tmp_path = strdup(path);
    char *ld = strrchr(tmp_path, '.');

    if(ld && ld > tmp_path)
    {
     char *last_ld = ld;
     *ld = 0;
     ld = strrchr(tmp_path, '.');
     if(!ld) { *last_ld = '.'; ld = last_ld; }
    }
    f_ext = strdup(ld ? ld + 1 : "");
    free(tmp_path);
   } // End gzip handling
  } // End normal and gzip file handling else to zip

  // FIXME:  Handle extension fixing for cases where loaded filename is like "moo.moo/lalala"

  error_code = 0;

 return(TRUE);
}