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); }
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); }