extern int ZEXPORT unzGoToNextFile(unzFile file) { unz_s *s; int err; if (file == NULL) { return UNZ_PARAMERROR; } s = (unz_s*)file; if (!s->current_file_ok) { return UNZ_END_OF_LIST_OF_FILE; } if (s->gi.number_entry != 0xffff) { /* 2^16 files overflow hack */ if (s->num_file + 1 == s->gi.number_entry) { return UNZ_END_OF_LIST_OF_FILE; } } s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; s->num_file++; err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); s->current_file_ok = (err == UNZ_OK); return err; }
bool ZIP_StatFile (unzFile archive, const char *filename, struct stat *stats) { gpointer file_entry; int pos; int err; unz_s* s; char *lowerfilename; unz_s unz_backup; struct tm newdate; tm_unz tmu_date; if (archive==NULL) return UNZ_PARAMERROR; s=(unz_s*)archive; lowerfilename = g_ascii_strdown(filename, -1); file_entry = g_hash_table_lookup(s->filenameHash, lowerfilename); g_free(lowerfilename); if (file_entry) { Mem_Copy(&unz_backup, s, sizeof(unz_s)); pos = GPOINTER_TO_UINT(file_entry); s->pos_in_central_dir = pos; err = unzlocal_GetCurrentFileInfoInternal(archive,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); if (err != UNZ_OK) { Mem_Copy(s, &unz_backup, sizeof(unz_s)); return false; } memset(stats, 0, sizeof(struct stat)); stats->st_size = s->cur_file_info.uncompressed_size; tmu_date = s->cur_file_info.tmu_date; newdate.tm_sec = tmu_date.tm_sec; newdate.tm_min = tmu_date.tm_min; newdate.tm_hour = tmu_date.tm_hour; newdate.tm_mday = tmu_date.tm_mday; newdate.tm_mon = tmu_date.tm_mon; if (tmu_date.tm_year > 1900) newdate.tm_year = tmu_date.tm_year - 1900; else newdate.tm_year = tmu_date.tm_year ; newdate.tm_isdst=-1; stats->st_mtime = mktime(&newdate); stats->st_ctime = stats->st_mtime; Mem_Copy(s, &unz_backup, sizeof(unz_s)); return true; } return false; }
//extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) { unz_s* s; int err; /* We remember the 'current' position in the file so that we can jump * back there if we fail. */ unz_file_info cur_file_infoSaved; unz_file_info_internal cur_file_info_internalSaved; uLong num_fileSaved; uLong pos_in_central_dirSaved; char *szCurrentFileName = NULL; if (file==NULL) return UNZ_PARAMERROR; if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) { return UNZ_END_OF_LIST_OF_FILE; } /* Save the current state */ num_fileSaved = s->num_file; pos_in_central_dirSaved = s->pos_in_central_dir; cur_file_infoSaved = s->cur_file_info; cur_file_info_internalSaved = s->cur_file_info_internal; err = unzGoToFirstFile(file); szCurrentFileName = (char*) ALLOC(UNZ_MAXFILENAMEINZIP+1); // heap_alloc - 256 while (err == UNZ_OK) { err = unzlocal_GetCurrentFileInfoInternal(file,NULL, NULL, szCurrentFileName,sizeof(szCurrentFileName)-1, NULL,0,NULL,0); if (err == UNZ_OK) { if (unzStringFileNameCompare(szCurrentFileName, szFileName,iCaseSensitivity)==0) { TRYFREE(szCurrentFileName); return UNZ_OK; } err = unzGoToNextFile(file); } } TRYFREE(szCurrentFileName); /* We failed, so restore the state of the 'current file' to where we * were. */ s->num_file = num_fileSaved ; s->pos_in_central_dir = pos_in_central_dirSaved ; s->cur_file_info = cur_file_infoSaved; s->cur_file_info_internal = cur_file_info_internalSaved; return err; }
/* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int unzGetCurrentFileInfo ( unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) { return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, szComment,commentBufferSize); }
/* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ int unzGoToFirstFile(unzFile file) { int err=UNZ_OK; unz_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; s->pos_in_central_dir=s->offset_central_dir; s->num_file=0; err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; }
/* Set the position of the info of the current file in the zip. return UNZ_OK if there is no problem */ extern int unzSetCurrentFileInfoPosition (unzFile file, unsigned long pos ) { unz_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; s->pos_in_central_dir = pos; err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return UNZ_OK; }
int unzSetOffset (unzFile file, uLong pos) { unz_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; s->pos_in_central_dir = pos; s->num_file = s->gi.number_entry; /* hack */ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; }
extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir) { unz_s *s; int err; if (file == NULL) { return UNZ_PARAMERROR; } s = (unz_s*)file; s->num_file = file_num; s->pos_in_central_dir = pos_in_central_dir; err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); s->current_file_ok = (err == UNZ_OK); return err; }
/* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ int unzGoToNextFile(unzFile file) { unz_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; }
//extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) { unz_s* s; int err; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; /* jump to the right spot */ s->pos_in_central_dir = file_pos->pos_in_zip_directory; s->num_file = file_pos->num_of_file; /* set the current file */ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); /* return results */ s->current_file_ok = (err == UNZ_OK); return err; }
/* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer "zlib/zlib109.zip". If the zipfile cannot be opened (file don't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ unzFile ZIP_Open (const char *path, unsigned char hash[MAX_HASH_SIZE], int *hashlen) { unz_s us; unz_s *s; uLong central_pos,uL; FILE * fin ; char buf[22]; char *lowercase_name; int i; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int numFiles, err=UNZ_OK; fin=fopen(path,"rb"); if (fin==NULL) return NULL; central_pos = unzlocal_SearchCentralDir(fin); if (central_pos==0) err=UNZ_ERRNO; if (fseek(fin,central_pos,SEEK_SET)!=0) err=UNZ_ERRNO; // UTTAR: Reducing the number of calls to fread drastically to improve loading performance if(fread(buf, 22, 1, fin) != 1) { fclose(fin); return NULL; } else { uL = LITTLE_INT(*((int*)&buf[0])); number_disk = LITTLE_SHORT(*((short*)&buf[4])); number_disk_with_CD = LITTLE_SHORT(*((short*)&buf[6])); us.gi.number_entry = LITTLE_SHORT(*((short*)&buf[8])); number_entry_CD = LITTLE_SHORT(*((short*)&buf[10])); us.size_central_dir = LITTLE_INT(*((int*)&buf[12])); us.offset_central_dir = LITTLE_INT(*((int*)&buf[16])); us.gi.size_comment = LITTLE_SHORT(*((short*)&buf[20])); if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; if ((central_pos<us.offset_central_dir+us.size_central_dir) && (err==UNZ_OK)) err=UNZ_BADZIPFILE; } if (err!=UNZ_OK) { fclose(fin); return NULL; } us.file=fin; us.byte_before_the_zipfile = central_pos - (us.offset_central_dir+us.size_central_dir); us.central_pos = central_pos; us.pfile_in_zip_read = NULL; s=(unz_s*)Tag_Malloc(sizeof(unz_s), MEM_ZIP); *s=us; err = unzGoToFirstFile((unzFile)s); Console_DPrintf("creating new filenameHash\n"); s->filenameHash = g_hash_table_new(g_str_hash, zip_str_equal); numFiles = 0; memset(hash, 0, MAX_HASH_SIZE); Hash_StartHash(); while (err == UNZ_OK) { char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; unzlocal_GetCurrentFileInfoInternal ((unzFile)s, &s->cur_file_info, &s->cur_file_info_internal, szCurrentFileName, sizeof(szCurrentFileName)-1, NULL, 0, NULL, 0); Hash_AddData((char *)&s->cur_file_info, sizeof(s->cur_file_info)); Hash_AddData((char *)&s->cur_file_info_internal, sizeof(s->cur_file_info_internal)); lowercase_name = g_ascii_strdown(szCurrentFileName, -1); //Console_DPrintf("hashing key %s (%u) with value %p\n", lowercase_name, g_str_hash(lowercase_name), GUINT_TO_POINTER(s->pos_in_central_dir)); g_hash_table_insert(s->filenameHash, lowercase_name, GUINT_TO_POINTER(s->pos_in_central_dir)); numFiles++; err = unzGoToNextFile((unzFile)s); } *hashlen = Hash_EndHash(hash); Console_DPrintf("s2z hash \"%s\" is: ", path); for(i = 0; i < *hashlen; i++) Console_DPrintf("%02x", hash[i]); Console_DPrintf("\n"); Console_DPrintf("Done reading zip file contents - %i files\n", numFiles); if (err != UNZ_END_OF_LIST_OF_FILE) Console_DPrintf("ZIP error: err was %i\n", err); return (unzFile)s; }