/* based on gpSP which took it from gameplaySP * * Copyright (C) 2017 critor * Copyright (C) 2012 calc84maniac * Copyright (C) 2006 Exophase * Copyright (C) 2006 SiberianSTAR * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "zlib.h" #include "common.h" #define ZIP_BUFFER_SIZE (128 * 1024) u32 path_size; struct SZIPFileDataDescriptor { s32 CRC32; s32 CompressedSize; s32 UncompressedSize; } __attribute__((packed)); struct SZIPFileHeader { s32 Sig; s16 VersionToExtract; s16 GeneralBitFlag; s16 CompressionMethod; s16 LastModFileTime; s16 LastModFileDate; struct SZIPFileDataDescriptor DataDescriptor; s16 FilenameLength; s16 ExtraFieldLength; } __attribute__((packed)); int mkdirs(const char *dir, const mode_t mode) { /* recursive mkdir */ char tmp[PATH_SIZE]; char *p = NULL; struct stat sb; size_t len = strlen(dir); if (len buffer_size) { tptr=buffer; buffer = realloc(buffer,data.DataDescriptor.UncompressedSize); if(buffer) buffer_size=data.DataDescriptor.UncompressedSize; else buffer=tptr; } read_size=0; write_size=0; if(nsext) { ext = strrchr(tmp,'.'); if(!ext || (ext && strcmp(ext,".tns"))) strcat(tmp,".tns"); } ho = fopen(tmp, "wb"); if(!ho) fseek(hi, data.DataDescriptor.CompressedSize, SEEK_CUR); else { switch(data.CompressionMethod) { case 0: printf("Extracting file %s\n",tmp); while(read_size cbuffer_size) { tptr = cbuffer; cbuffer = realloc(cbuffer,data.DataDescriptor.CompressedSize); if(cbuffer) cbuffer_size=data.DataDescriptor.CompressedSize; else cbuffer=tptr; } stream.next_in = (Bytef*)cbuffer; stream.avail_in = cbuffer_size; stream.next_out = (Bytef*)buffer; stream.avail_out = buffer_size; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit2(&stream, -MAX_WBITS); read_size+=fread(cbuffer, 1, MIN(data.DataDescriptor.CompressedSize,cbuffer_size), hi); if(err == Z_OK) { while(err != Z_STREAM_END) { err = inflate(&stream, Z_SYNC_FLUSH); if(err == Z_BUF_ERROR) { if(!stream.avail_in) { stream.avail_in = cbuffer_size; stream.next_in = (Bytef*)cbuffer; read_size+=fread(cbuffer, 1, MIN(data.DataDescriptor.CompressedSize-read_size,cbuffer_size), hi); } else if(!stream.avail_out) { stream.avail_out = buffer_size; stream.next_out = (Bytef*)buffer; write_size+=fwrite(buffer, 1, MIN(data.DataDescriptor.UncompressedSize-write_size,buffer_size), hi); } else break; } } err = Z_OK; inflateEnd(&stream); fwrite(buffer, 1, MIN(data.DataDescriptor.UncompressedSize-write_size,buffer_size), ho); } } fclose(ho); } } } } if(hi) fclose(hi); if(buffer) free(buffer); if(cbuffer) free(cbuffer); return hi && buffer; }