1275793eaSopenharmony_ci/* 2275793eaSopenharmony_ci miniunz.c 3275793eaSopenharmony_ci Version 1.1, February 14h, 2010 4275793eaSopenharmony_ci sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 5275793eaSopenharmony_ci 6275793eaSopenharmony_ci Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 7275793eaSopenharmony_ci 8275793eaSopenharmony_ci Modifications of Unzip for Zip64 9275793eaSopenharmony_ci Copyright (C) 2007-2008 Even Rouault 10275793eaSopenharmony_ci 11275793eaSopenharmony_ci Modifications for Zip64 support on both zip and unzip 12275793eaSopenharmony_ci Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 13275793eaSopenharmony_ci*/ 14275793eaSopenharmony_ci 15275793eaSopenharmony_ci#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) 16275793eaSopenharmony_ci #ifndef __USE_FILE_OFFSET64 17275793eaSopenharmony_ci #define __USE_FILE_OFFSET64 18275793eaSopenharmony_ci #endif 19275793eaSopenharmony_ci #ifndef __USE_LARGEFILE64 20275793eaSopenharmony_ci #define __USE_LARGEFILE64 21275793eaSopenharmony_ci #endif 22275793eaSopenharmony_ci #ifndef _LARGEFILE64_SOURCE 23275793eaSopenharmony_ci #define _LARGEFILE64_SOURCE 24275793eaSopenharmony_ci #endif 25275793eaSopenharmony_ci #ifndef _FILE_OFFSET_BIT 26275793eaSopenharmony_ci #define _FILE_OFFSET_BIT 64 27275793eaSopenharmony_ci #endif 28275793eaSopenharmony_ci#endif 29275793eaSopenharmony_ci 30275793eaSopenharmony_ci#if defined(__APPLE__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) 31275793eaSopenharmony_ci// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions 32275793eaSopenharmony_ci#define FOPEN_FUNC(filename, mode) fopen(filename, mode) 33275793eaSopenharmony_ci#define FTELLO_FUNC(stream) ftello(stream) 34275793eaSopenharmony_ci#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) 35275793eaSopenharmony_ci#else 36275793eaSopenharmony_ci#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) 37275793eaSopenharmony_ci#define FTELLO_FUNC(stream) ftello64(stream) 38275793eaSopenharmony_ci#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) 39275793eaSopenharmony_ci#endif 40275793eaSopenharmony_ci 41275793eaSopenharmony_ci 42275793eaSopenharmony_ci#include <stdio.h> 43275793eaSopenharmony_ci#include <stdlib.h> 44275793eaSopenharmony_ci#include <string.h> 45275793eaSopenharmony_ci#include <time.h> 46275793eaSopenharmony_ci#include <errno.h> 47275793eaSopenharmony_ci#include <fcntl.h> 48275793eaSopenharmony_ci#include <sys/stat.h> 49275793eaSopenharmony_ci 50275793eaSopenharmony_ci#ifdef _WIN32 51275793eaSopenharmony_ci# include <direct.h> 52275793eaSopenharmony_ci# include <io.h> 53275793eaSopenharmony_ci#else 54275793eaSopenharmony_ci# include <unistd.h> 55275793eaSopenharmony_ci# include <utime.h> 56275793eaSopenharmony_ci#endif 57275793eaSopenharmony_ci 58275793eaSopenharmony_ci 59275793eaSopenharmony_ci#include "unzip.h" 60275793eaSopenharmony_ci 61275793eaSopenharmony_ci#define CASESENSITIVITY (0) 62275793eaSopenharmony_ci#define WRITEBUFFERSIZE (8192) 63275793eaSopenharmony_ci#define MAXFILENAME (256) 64275793eaSopenharmony_ci 65275793eaSopenharmony_ci#ifdef _WIN32 66275793eaSopenharmony_ci#define USEWIN32IOAPI 67275793eaSopenharmony_ci#include "iowin32.h" 68275793eaSopenharmony_ci#endif 69275793eaSopenharmony_ci/* 70275793eaSopenharmony_ci mini unzip, demo of unzip package 71275793eaSopenharmony_ci 72275793eaSopenharmony_ci usage : 73275793eaSopenharmony_ci Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] 74275793eaSopenharmony_ci 75275793eaSopenharmony_ci list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT 76275793eaSopenharmony_ci if it exists 77275793eaSopenharmony_ci*/ 78275793eaSopenharmony_ci 79275793eaSopenharmony_ci 80275793eaSopenharmony_ci/* change_file_date : change the date/time of a file 81275793eaSopenharmony_ci filename : the filename of the file where date/time must be modified 82275793eaSopenharmony_ci dosdate : the new date at the MSDOS format (4 bytes) 83275793eaSopenharmony_ci tmu_date : the SAME new date at the tm_unz format */ 84275793eaSopenharmony_cistatic void change_file_date(const char *filename, uLong dosdate, tm_unz tmu_date) 85275793eaSopenharmony_ci{ 86275793eaSopenharmony_ci#ifdef _WIN32 87275793eaSopenharmony_ci HANDLE hFile; 88275793eaSopenharmony_ci FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; 89275793eaSopenharmony_ci 90275793eaSopenharmony_ci hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, 91275793eaSopenharmony_ci 0,NULL,OPEN_EXISTING,0,NULL); 92275793eaSopenharmony_ci GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); 93275793eaSopenharmony_ci DosDateTimeToFileTime((WORD)(dosdate >> 16),(WORD)dosdate,&ftLocal); 94275793eaSopenharmony_ci LocalFileTimeToFileTime(&ftLocal,&ftm); 95275793eaSopenharmony_ci SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); 96275793eaSopenharmony_ci CloseHandle(hFile); 97275793eaSopenharmony_ci#else 98275793eaSopenharmony_ci#if defined(unix) || defined(__APPLE__) 99275793eaSopenharmony_ci (void)dosdate; 100275793eaSopenharmony_ci struct utimbuf ut; 101275793eaSopenharmony_ci struct tm newdate; 102275793eaSopenharmony_ci newdate.tm_sec = tmu_date.tm_sec; 103275793eaSopenharmony_ci newdate.tm_min = tmu_date.tm_min; 104275793eaSopenharmony_ci newdate.tm_hour = tmu_date.tm_hour; 105275793eaSopenharmony_ci newdate.tm_mday = tmu_date.tm_mday; 106275793eaSopenharmony_ci newdate.tm_mon = tmu_date.tm_mon; 107275793eaSopenharmony_ci if (tmu_date.tm_year > 1900) 108275793eaSopenharmony_ci { 109275793eaSopenharmony_ci newdate.tm_year = tmu_date.tm_year - 1900; 110275793eaSopenharmony_ci } 111275793eaSopenharmony_ci else 112275793eaSopenharmony_ci { 113275793eaSopenharmony_ci newdate.tm_year = tmu_date.tm_year ; 114275793eaSopenharmony_ci } 115275793eaSopenharmony_ci newdate.tm_isdst = -1; 116275793eaSopenharmony_ci 117275793eaSopenharmony_ci ut.actime = ut.modtime = mktime(&newdate); 118275793eaSopenharmony_ci utime(filename,&ut); 119275793eaSopenharmony_ci#else 120275793eaSopenharmony_ci (void)filename; 121275793eaSopenharmony_ci (void)dosdate; 122275793eaSopenharmony_ci (void)tmu_date; 123275793eaSopenharmony_ci#endif 124275793eaSopenharmony_ci#endif 125275793eaSopenharmony_ci} 126275793eaSopenharmony_ci 127275793eaSopenharmony_ci 128275793eaSopenharmony_ci/* mymkdir and change_file_date are not 100 % portable 129275793eaSopenharmony_ci As I don't know well Unix, I wait feedback for the unix portion */ 130275793eaSopenharmony_ci 131275793eaSopenharmony_cistatic int mymkdir(const char* dirname) 132275793eaSopenharmony_ci{ 133275793eaSopenharmony_ci int ret = 0; 134275793eaSopenharmony_ci#ifdef _WIN32 135275793eaSopenharmony_ci ret = _mkdir(dirname); 136275793eaSopenharmony_ci#elif unix 137275793eaSopenharmony_ci ret = mkdir (dirname,0775); 138275793eaSopenharmony_ci#elif __APPLE__ 139275793eaSopenharmony_ci ret = mkdir (dirname,0775); 140275793eaSopenharmony_ci#else 141275793eaSopenharmony_ci (void)dirname; 142275793eaSopenharmony_ci#endif 143275793eaSopenharmony_ci return ret; 144275793eaSopenharmony_ci} 145275793eaSopenharmony_ci 146275793eaSopenharmony_cistatic int makedir(const char *newdir) 147275793eaSopenharmony_ci{ 148275793eaSopenharmony_ci char *buffer ; 149275793eaSopenharmony_ci char *p; 150275793eaSopenharmony_ci size_t len = strlen(newdir); 151275793eaSopenharmony_ci 152275793eaSopenharmony_ci if (len == 0) 153275793eaSopenharmony_ci { 154275793eaSopenharmony_ci return 0; 155275793eaSopenharmony_ci } 156275793eaSopenharmony_ci 157275793eaSopenharmony_ci buffer = (char*)malloc(len+1); 158275793eaSopenharmony_ci if (buffer==NULL) 159275793eaSopenharmony_ci { 160275793eaSopenharmony_ci printf("Error allocating memory\n"); 161275793eaSopenharmony_ci return UNZ_INTERNALERROR; 162275793eaSopenharmony_ci } 163275793eaSopenharmony_ci strcpy(buffer,newdir); 164275793eaSopenharmony_ci 165275793eaSopenharmony_ci if (buffer[len-1] == '/') { 166275793eaSopenharmony_ci buffer[len-1] = '\0'; 167275793eaSopenharmony_ci } 168275793eaSopenharmony_ci if (mymkdir(buffer) == 0) 169275793eaSopenharmony_ci { 170275793eaSopenharmony_ci free(buffer); 171275793eaSopenharmony_ci return 1; 172275793eaSopenharmony_ci } 173275793eaSopenharmony_ci 174275793eaSopenharmony_ci p = buffer+1; 175275793eaSopenharmony_ci while (1) 176275793eaSopenharmony_ci { 177275793eaSopenharmony_ci char hold; 178275793eaSopenharmony_ci 179275793eaSopenharmony_ci while(*p && *p != '\\' && *p != '/') 180275793eaSopenharmony_ci { 181275793eaSopenharmony_ci p++; 182275793eaSopenharmony_ci } 183275793eaSopenharmony_ci hold = *p; 184275793eaSopenharmony_ci *p = 0; 185275793eaSopenharmony_ci if ((mymkdir(buffer) == -1) && (errno == ENOENT)) 186275793eaSopenharmony_ci { 187275793eaSopenharmony_ci printf("couldn't create directory %s\n",buffer); 188275793eaSopenharmony_ci free(buffer); 189275793eaSopenharmony_ci return 0; 190275793eaSopenharmony_ci } 191275793eaSopenharmony_ci if (hold == 0) 192275793eaSopenharmony_ci { 193275793eaSopenharmony_ci break; 194275793eaSopenharmony_ci } 195275793eaSopenharmony_ci *p++ = hold; 196275793eaSopenharmony_ci } 197275793eaSopenharmony_ci free(buffer); 198275793eaSopenharmony_ci return 1; 199275793eaSopenharmony_ci} 200275793eaSopenharmony_ci 201275793eaSopenharmony_cistatic void do_banner(void) 202275793eaSopenharmony_ci{ 203275793eaSopenharmony_ci printf("MiniUnz 1.1, demo of zLib + Unz package written by Gilles Vollant\n"); 204275793eaSopenharmony_ci printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); 205275793eaSopenharmony_ci} 206275793eaSopenharmony_ci 207275793eaSopenharmony_cistatic void do_help(void) 208275793eaSopenharmony_ci{ 209275793eaSopenharmony_ci printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ 210275793eaSopenharmony_ci " -e Extract without pathname (junk paths)\n" \ 211275793eaSopenharmony_ci " -x Extract with pathname\n" \ 212275793eaSopenharmony_ci " -v list files\n" \ 213275793eaSopenharmony_ci " -l list files\n" \ 214275793eaSopenharmony_ci " -d directory to extract into\n" \ 215275793eaSopenharmony_ci " -o overwrite files without prompting\n" \ 216275793eaSopenharmony_ci " -p extract encrypted file using password\n\n"); 217275793eaSopenharmony_ci} 218275793eaSopenharmony_ci 219275793eaSopenharmony_cistatic void Display64BitsSize(ZPOS64_T n, int size_char) 220275793eaSopenharmony_ci{ 221275793eaSopenharmony_ci /* to avoid compatibility problem , we do here the conversion */ 222275793eaSopenharmony_ci char number[21]; 223275793eaSopenharmony_ci int offset=19; 224275793eaSopenharmony_ci int pos_string = 19; 225275793eaSopenharmony_ci number[20]=0; 226275793eaSopenharmony_ci for (;;) 227275793eaSopenharmony_ci { 228275793eaSopenharmony_ci number[offset]=(char)((n%10)+'0'); 229275793eaSopenharmony_ci if (number[offset] != '0') 230275793eaSopenharmony_ci { 231275793eaSopenharmony_ci pos_string=offset; 232275793eaSopenharmony_ci } 233275793eaSopenharmony_ci n/=10; 234275793eaSopenharmony_ci if (offset==0) 235275793eaSopenharmony_ci { 236275793eaSopenharmony_ci break; 237275793eaSopenharmony_ci } 238275793eaSopenharmony_ci offset--; 239275793eaSopenharmony_ci } 240275793eaSopenharmony_ci { 241275793eaSopenharmony_ci int size_display_string = 19-pos_string; 242275793eaSopenharmony_ci while (size_char > size_display_string) 243275793eaSopenharmony_ci { 244275793eaSopenharmony_ci size_char--; 245275793eaSopenharmony_ci printf(" "); 246275793eaSopenharmony_ci } 247275793eaSopenharmony_ci } 248275793eaSopenharmony_ci 249275793eaSopenharmony_ci printf("%s",&number[pos_string]); 250275793eaSopenharmony_ci} 251275793eaSopenharmony_ci 252275793eaSopenharmony_cistatic int do_list(unzFile uf) 253275793eaSopenharmony_ci{ 254275793eaSopenharmony_ci uLong i; 255275793eaSopenharmony_ci unz_global_info64 gi; 256275793eaSopenharmony_ci int err; 257275793eaSopenharmony_ci 258275793eaSopenharmony_ci err = unzGetGlobalInfo64(uf,&gi); 259275793eaSopenharmony_ci if (err != UNZ_OK) 260275793eaSopenharmony_ci { 261275793eaSopenharmony_ci printf("error %d with zipfile in unzGetGlobalInfo \n",err); 262275793eaSopenharmony_ci } 263275793eaSopenharmony_ci printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); 264275793eaSopenharmony_ci printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); 265275793eaSopenharmony_ci for (i = 0;i < gi.number_entry; i++) 266275793eaSopenharmony_ci { 267275793eaSopenharmony_ci char filename_inzip[256]; 268275793eaSopenharmony_ci unz_file_info64 file_info; 269275793eaSopenharmony_ci uLong ratio = 0; 270275793eaSopenharmony_ci const char *string_method = ""; 271275793eaSopenharmony_ci char charCrypt = ' '; 272275793eaSopenharmony_ci err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); 273275793eaSopenharmony_ci if (err != UNZ_OK) 274275793eaSopenharmony_ci { 275275793eaSopenharmony_ci printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); 276275793eaSopenharmony_ci break; 277275793eaSopenharmony_ci } 278275793eaSopenharmony_ci if (file_info.uncompressed_size > 0) 279275793eaSopenharmony_ci ratio = (uLong)((file_info.compressed_size*100) / file_info.uncompressed_size); 280275793eaSopenharmony_ci 281275793eaSopenharmony_ci /* display a '*' if the file is encrypted */ 282275793eaSopenharmony_ci if ((file_info.flag & 1) != 0) 283275793eaSopenharmony_ci { 284275793eaSopenharmony_ci charCrypt = '*'; 285275793eaSopenharmony_ci } 286275793eaSopenharmony_ci 287275793eaSopenharmony_ci if (file_info.compression_method == 0) 288275793eaSopenharmony_ci { 289275793eaSopenharmony_ci string_method = "Stored"; 290275793eaSopenharmony_ci } 291275793eaSopenharmony_ci else 292275793eaSopenharmony_ci if (file_info.compression_method == Z_DEFLATED) 293275793eaSopenharmony_ci { 294275793eaSopenharmony_ci uInt iLevel=(uInt)((file_info.flag & 0x6) / 2); 295275793eaSopenharmony_ci if (iLevel == 0) 296275793eaSopenharmony_ci { 297275793eaSopenharmony_ci string_method = "Defl:N"; 298275793eaSopenharmony_ci } 299275793eaSopenharmony_ci else if (iLevel == 1) 300275793eaSopenharmony_ci { 301275793eaSopenharmony_ci string_method = "Defl:X"; 302275793eaSopenharmony_ci } 303275793eaSopenharmony_ci else if ((iLevel == 2) || (iLevel == 3)) 304275793eaSopenharmony_ci { 305275793eaSopenharmony_ci string_method = "Defl:F"; /* 2:fast , 3 : extra fast*/ 306275793eaSopenharmony_ci } 307275793eaSopenharmony_ci } 308275793eaSopenharmony_ci else 309275793eaSopenharmony_ci if (file_info.compression_method == Z_BZIP2ED) 310275793eaSopenharmony_ci { 311275793eaSopenharmony_ci string_method = "BZip2 "; 312275793eaSopenharmony_ci } 313275793eaSopenharmony_ci else 314275793eaSopenharmony_ci { 315275793eaSopenharmony_ci string_method = "Unkn. "; 316275793eaSopenharmony_ci } 317275793eaSopenharmony_ci 318275793eaSopenharmony_ci Display64BitsSize(file_info.uncompressed_size,7); 319275793eaSopenharmony_ci printf(" %6s%c",string_method,charCrypt); 320275793eaSopenharmony_ci Display64BitsSize(file_info.compressed_size,7); 321275793eaSopenharmony_ci printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", 322275793eaSopenharmony_ci ratio, 323275793eaSopenharmony_ci (uLong)file_info.tmu_date.tm_mon + 1, 324275793eaSopenharmony_ci (uLong)file_info.tmu_date.tm_mday, 325275793eaSopenharmony_ci (uLong)file_info.tmu_date.tm_year % 100, 326275793eaSopenharmony_ci (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, 327275793eaSopenharmony_ci (uLong)file_info.crc,filename_inzip); 328275793eaSopenharmony_ci if (gi.number_entry > (i+1)) 329275793eaSopenharmony_ci { 330275793eaSopenharmony_ci err = unzGoToNextFile(uf); 331275793eaSopenharmony_ci if (err != UNZ_OK) 332275793eaSopenharmony_ci { 333275793eaSopenharmony_ci printf("error %d with zipfile in unzGoToNextFile\n",err); 334275793eaSopenharmony_ci break; 335275793eaSopenharmony_ci } 336275793eaSopenharmony_ci } 337275793eaSopenharmony_ci } 338275793eaSopenharmony_ci 339275793eaSopenharmony_ci return 0; 340275793eaSopenharmony_ci} 341275793eaSopenharmony_ci 342275793eaSopenharmony_ci 343275793eaSopenharmony_cistatic int do_extract_currentfile(unzFile uf, 344275793eaSopenharmony_ci const int* popt_extract_without_path, 345275793eaSopenharmony_ci int* popt_overwrite, 346275793eaSopenharmony_ci const char* password) 347275793eaSopenharmony_ci{ 348275793eaSopenharmony_ci char filename_inzip[256]; 349275793eaSopenharmony_ci char* filename_withoutpath; 350275793eaSopenharmony_ci char* p; 351275793eaSopenharmony_ci int err = UNZ_OK; 352275793eaSopenharmony_ci FILE *fout = NULL; 353275793eaSopenharmony_ci void* buf; 354275793eaSopenharmony_ci uInt size_buf; 355275793eaSopenharmony_ci 356275793eaSopenharmony_ci unz_file_info64 file_info; 357275793eaSopenharmony_ci err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); 358275793eaSopenharmony_ci 359275793eaSopenharmony_ci if (err != UNZ_OK) 360275793eaSopenharmony_ci { 361275793eaSopenharmony_ci printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); 362275793eaSopenharmony_ci return err; 363275793eaSopenharmony_ci } 364275793eaSopenharmony_ci 365275793eaSopenharmony_ci size_buf = WRITEBUFFERSIZE; 366275793eaSopenharmony_ci buf = (void*)malloc(size_buf); 367275793eaSopenharmony_ci if (buf == NULL) 368275793eaSopenharmony_ci { 369275793eaSopenharmony_ci printf("Error allocating memory\n"); 370275793eaSopenharmony_ci return UNZ_INTERNALERROR; 371275793eaSopenharmony_ci } 372275793eaSopenharmony_ci 373275793eaSopenharmony_ci p = filename_withoutpath = filename_inzip; 374275793eaSopenharmony_ci while ((*p) != '\0') 375275793eaSopenharmony_ci { 376275793eaSopenharmony_ci if (((*p) == '/') || ((*p) == '\\')) 377275793eaSopenharmony_ci { 378275793eaSopenharmony_ci filename_withoutpath = p+1; 379275793eaSopenharmony_ci } 380275793eaSopenharmony_ci p++; 381275793eaSopenharmony_ci } 382275793eaSopenharmony_ci 383275793eaSopenharmony_ci if ((*filename_withoutpath) == '\0') 384275793eaSopenharmony_ci { 385275793eaSopenharmony_ci if ((*popt_extract_without_path) == 0) 386275793eaSopenharmony_ci { 387275793eaSopenharmony_ci printf("creating directory: %s\n",filename_inzip); 388275793eaSopenharmony_ci mymkdir(filename_inzip); 389275793eaSopenharmony_ci } 390275793eaSopenharmony_ci } 391275793eaSopenharmony_ci else 392275793eaSopenharmony_ci { 393275793eaSopenharmony_ci const char* write_filename; 394275793eaSopenharmony_ci int skip = 0; 395275793eaSopenharmony_ci 396275793eaSopenharmony_ci if ((*popt_extract_without_path) == 0) 397275793eaSopenharmony_ci { 398275793eaSopenharmony_ci write_filename = filename_inzip; 399275793eaSopenharmony_ci } 400275793eaSopenharmony_ci else 401275793eaSopenharmony_ci { 402275793eaSopenharmony_ci write_filename = filename_withoutpath; 403275793eaSopenharmony_ci } 404275793eaSopenharmony_ci 405275793eaSopenharmony_ci if (write_filename[0] != '\0') 406275793eaSopenharmony_ci { 407275793eaSopenharmony_ci const char* relative_check = write_filename; 408275793eaSopenharmony_ci while (relative_check[1] != '\0') 409275793eaSopenharmony_ci { 410275793eaSopenharmony_ci if (relative_check[0] == '.' && relative_check[1] == '.') 411275793eaSopenharmony_ci { 412275793eaSopenharmony_ci write_filename = relative_check; 413275793eaSopenharmony_ci } 414275793eaSopenharmony_ci relative_check++; 415275793eaSopenharmony_ci } 416275793eaSopenharmony_ci } 417275793eaSopenharmony_ci 418275793eaSopenharmony_ci while (write_filename[0] == '/' || write_filename[0] == '.') 419275793eaSopenharmony_ci { 420275793eaSopenharmony_ci write_filename++; 421275793eaSopenharmony_ci } 422275793eaSopenharmony_ci 423275793eaSopenharmony_ci err = unzOpenCurrentFilePassword(uf,password); 424275793eaSopenharmony_ci if (err != UNZ_OK) 425275793eaSopenharmony_ci { 426275793eaSopenharmony_ci printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err); 427275793eaSopenharmony_ci } 428275793eaSopenharmony_ci 429275793eaSopenharmony_ci if (((*popt_overwrite) == 0) && (err == UNZ_OK)) 430275793eaSopenharmony_ci { 431275793eaSopenharmony_ci char rep = 0; 432275793eaSopenharmony_ci FILE* ftestexist; 433275793eaSopenharmony_ci ftestexist = FOPEN_FUNC(write_filename,"rb"); 434275793eaSopenharmony_ci if (ftestexist != NULL) 435275793eaSopenharmony_ci { 436275793eaSopenharmony_ci fclose(ftestexist); 437275793eaSopenharmony_ci do 438275793eaSopenharmony_ci { 439275793eaSopenharmony_ci char answer[128]; 440275793eaSopenharmony_ci int ret; 441275793eaSopenharmony_ci 442275793eaSopenharmony_ci printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); 443275793eaSopenharmony_ci ret = scanf("%1s",answer); 444275793eaSopenharmony_ci if (ret != 1) 445275793eaSopenharmony_ci { 446275793eaSopenharmony_ci exit(EXIT_FAILURE); 447275793eaSopenharmony_ci } 448275793eaSopenharmony_ci rep = answer[0] ; 449275793eaSopenharmony_ci if ((rep >= 'a') && (rep <= 'z')) 450275793eaSopenharmony_ci { 451275793eaSopenharmony_ci rep -= 0x20; 452275793eaSopenharmony_ci } 453275793eaSopenharmony_ci } 454275793eaSopenharmony_ci while ((rep != 'Y') && (rep != 'N') && (rep != 'A')); 455275793eaSopenharmony_ci } 456275793eaSopenharmony_ci 457275793eaSopenharmony_ci if (rep == 'N') 458275793eaSopenharmony_ci { 459275793eaSopenharmony_ci skip = 1; 460275793eaSopenharmony_ci } 461275793eaSopenharmony_ci 462275793eaSopenharmony_ci if (rep == 'A') 463275793eaSopenharmony_ci { 464275793eaSopenharmony_ci *popt_overwrite=1; 465275793eaSopenharmony_ci } 466275793eaSopenharmony_ci } 467275793eaSopenharmony_ci 468275793eaSopenharmony_ci if ((skip == 0) && (err == UNZ_OK)) 469275793eaSopenharmony_ci { 470275793eaSopenharmony_ci fout=FOPEN_FUNC(write_filename,"wb"); 471275793eaSopenharmony_ci /* some zipfile don't contain directory alone before file */ 472275793eaSopenharmony_ci if ((fout == NULL) && ((*popt_extract_without_path) == 0) && 473275793eaSopenharmony_ci (filename_withoutpath!=(char*)filename_inzip)) 474275793eaSopenharmony_ci { 475275793eaSopenharmony_ci char c=*(filename_withoutpath - 1); 476275793eaSopenharmony_ci *(filename_withoutpath-1) = '\0'; 477275793eaSopenharmony_ci makedir(write_filename); 478275793eaSopenharmony_ci *(filename_withoutpath-1) = c; 479275793eaSopenharmony_ci fout=FOPEN_FUNC(write_filename,"wb"); 480275793eaSopenharmony_ci } 481275793eaSopenharmony_ci 482275793eaSopenharmony_ci if (fout == NULL) 483275793eaSopenharmony_ci { 484275793eaSopenharmony_ci printf("error opening %s\n",write_filename); 485275793eaSopenharmony_ci } 486275793eaSopenharmony_ci } 487275793eaSopenharmony_ci 488275793eaSopenharmony_ci if (fout != NULL) 489275793eaSopenharmony_ci { 490275793eaSopenharmony_ci printf(" extracting: %s\n",write_filename); 491275793eaSopenharmony_ci 492275793eaSopenharmony_ci do 493275793eaSopenharmony_ci { 494275793eaSopenharmony_ci err = unzReadCurrentFile(uf,buf,size_buf); 495275793eaSopenharmony_ci if (err < 0) 496275793eaSopenharmony_ci { 497275793eaSopenharmony_ci printf("error %d with zipfile in unzReadCurrentFile\n",err); 498275793eaSopenharmony_ci break; 499275793eaSopenharmony_ci } 500275793eaSopenharmony_ci if (err > 0) 501275793eaSopenharmony_ci if (fwrite(buf,(unsigned)err,1,fout) != 1) 502275793eaSopenharmony_ci { 503275793eaSopenharmony_ci printf("error in writing extracted file\n"); 504275793eaSopenharmony_ci err=UNZ_ERRNO; 505275793eaSopenharmony_ci break; 506275793eaSopenharmony_ci } 507275793eaSopenharmony_ci } 508275793eaSopenharmony_ci while (err > 0); 509275793eaSopenharmony_ci if (fout) 510275793eaSopenharmony_ci { 511275793eaSopenharmony_ci fclose(fout); 512275793eaSopenharmony_ci } 513275793eaSopenharmony_ci 514275793eaSopenharmony_ci if (err == 0) 515275793eaSopenharmony_ci { 516275793eaSopenharmony_ci change_file_date(write_filename,file_info.dosDate, 517275793eaSopenharmony_ci file_info.tmu_date); 518275793eaSopenharmony_ci } 519275793eaSopenharmony_ci } 520275793eaSopenharmony_ci 521275793eaSopenharmony_ci if (err == UNZ_OK) 522275793eaSopenharmony_ci { 523275793eaSopenharmony_ci err = unzCloseCurrentFile (uf); 524275793eaSopenharmony_ci if (err != UNZ_OK) 525275793eaSopenharmony_ci { 526275793eaSopenharmony_ci printf("error %d with zipfile in unzCloseCurrentFile\n",err); 527275793eaSopenharmony_ci } 528275793eaSopenharmony_ci } 529275793eaSopenharmony_ci else 530275793eaSopenharmony_ci { 531275793eaSopenharmony_ci unzCloseCurrentFile(uf); /* don't lose the error */ 532275793eaSopenharmony_ci } 533275793eaSopenharmony_ci } 534275793eaSopenharmony_ci 535275793eaSopenharmony_ci free(buf); 536275793eaSopenharmony_ci return err; 537275793eaSopenharmony_ci} 538275793eaSopenharmony_ci 539275793eaSopenharmony_ci 540275793eaSopenharmony_cistatic int do_extract(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char* password) 541275793eaSopenharmony_ci{ 542275793eaSopenharmony_ci uLong i; 543275793eaSopenharmony_ci unz_global_info64 gi; 544275793eaSopenharmony_ci int err; 545275793eaSopenharmony_ci 546275793eaSopenharmony_ci err = unzGetGlobalInfo64(uf,&gi); 547275793eaSopenharmony_ci if (err != UNZ_OK) 548275793eaSopenharmony_ci { 549275793eaSopenharmony_ci printf("error %d with zipfile in unzGetGlobalInfo \n",err); 550275793eaSopenharmony_ci } 551275793eaSopenharmony_ci 552275793eaSopenharmony_ci for (i = 0;i < gi.number_entry; i++) 553275793eaSopenharmony_ci { 554275793eaSopenharmony_ci if (do_extract_currentfile(uf,&opt_extract_without_path, 555275793eaSopenharmony_ci &opt_overwrite, 556275793eaSopenharmony_ci password) != UNZ_OK) 557275793eaSopenharmony_ci break; 558275793eaSopenharmony_ci 559275793eaSopenharmony_ci if (gi.number_entry > (i+1)) 560275793eaSopenharmony_ci { 561275793eaSopenharmony_ci err = unzGoToNextFile(uf); 562275793eaSopenharmony_ci if (err != UNZ_OK) 563275793eaSopenharmony_ci { 564275793eaSopenharmony_ci printf("error %d with zipfile in unzGoToNextFile\n",err); 565275793eaSopenharmony_ci break; 566275793eaSopenharmony_ci } 567275793eaSopenharmony_ci } 568275793eaSopenharmony_ci } 569275793eaSopenharmony_ci 570275793eaSopenharmony_ci return 0; 571275793eaSopenharmony_ci} 572275793eaSopenharmony_ci 573275793eaSopenharmony_cistatic int do_extract_onefile(unzFile uf, 574275793eaSopenharmony_ci const char* filename, 575275793eaSopenharmony_ci int opt_extract_without_path, 576275793eaSopenharmony_ci int opt_overwrite, 577275793eaSopenharmony_ci const char* password) 578275793eaSopenharmony_ci{ 579275793eaSopenharmony_ci if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK) 580275793eaSopenharmony_ci { 581275793eaSopenharmony_ci printf("file %s not found in the zipfile\n",filename); 582275793eaSopenharmony_ci return 2; 583275793eaSopenharmony_ci } 584275793eaSopenharmony_ci 585275793eaSopenharmony_ci if (do_extract_currentfile(uf,&opt_extract_without_path, 586275793eaSopenharmony_ci &opt_overwrite, 587275793eaSopenharmony_ci password) == UNZ_OK) 588275793eaSopenharmony_ci { 589275793eaSopenharmony_ci return 0; 590275793eaSopenharmony_ci } 591275793eaSopenharmony_ci else 592275793eaSopenharmony_ci { 593275793eaSopenharmony_ci return 1; 594275793eaSopenharmony_ci } 595275793eaSopenharmony_ci} 596275793eaSopenharmony_ci 597275793eaSopenharmony_ci 598275793eaSopenharmony_ciint main(int argc, char *argv[]) 599275793eaSopenharmony_ci{ 600275793eaSopenharmony_ci const char *zipfilename = NULL; 601275793eaSopenharmony_ci const char *filename_to_extract = NULL; 602275793eaSopenharmony_ci const char *password = NULL; 603275793eaSopenharmony_ci char filename_try[MAXFILENAME+16] = ""; 604275793eaSopenharmony_ci int i; 605275793eaSopenharmony_ci int ret_value = 0; 606275793eaSopenharmony_ci int opt_do_list = 0; 607275793eaSopenharmony_ci int opt_do_extract = 1; 608275793eaSopenharmony_ci int opt_do_extract_withoutpath = 0; 609275793eaSopenharmony_ci int opt_overwrite = 0; 610275793eaSopenharmony_ci int opt_extractdir = 0; 611275793eaSopenharmony_ci const char *dirname = NULL; 612275793eaSopenharmony_ci unzFile uf = NULL; 613275793eaSopenharmony_ci 614275793eaSopenharmony_ci do_banner(); 615275793eaSopenharmony_ci if (argc == 1) 616275793eaSopenharmony_ci { 617275793eaSopenharmony_ci do_help(); 618275793eaSopenharmony_ci return 0; 619275793eaSopenharmony_ci } 620275793eaSopenharmony_ci else 621275793eaSopenharmony_ci { 622275793eaSopenharmony_ci for (i = 1;i < argc; i++) 623275793eaSopenharmony_ci { 624275793eaSopenharmony_ci if ((*argv[i]) == '-') 625275793eaSopenharmony_ci { 626275793eaSopenharmony_ci const char *p = argv[i]+1; 627275793eaSopenharmony_ci 628275793eaSopenharmony_ci while ((*p) != '\0') 629275793eaSopenharmony_ci { 630275793eaSopenharmony_ci char c = *(p++); 631275793eaSopenharmony_ci if ((c == 'l') || (c == 'L')) 632275793eaSopenharmony_ci { 633275793eaSopenharmony_ci opt_do_list = 1; 634275793eaSopenharmony_ci } 635275793eaSopenharmony_ci if ((c == 'v') || (c == 'V')) 636275793eaSopenharmony_ci { 637275793eaSopenharmony_ci opt_do_list = 1; 638275793eaSopenharmony_ci } 639275793eaSopenharmony_ci if ((c == 'x') || (c == 'X')) 640275793eaSopenharmony_ci { 641275793eaSopenharmony_ci opt_do_extract = 1; 642275793eaSopenharmony_ci } 643275793eaSopenharmony_ci if ((c == 'e') || (c == 'E')) 644275793eaSopenharmony_ci { 645275793eaSopenharmony_ci opt_do_extract = opt_do_extract_withoutpath = 1; 646275793eaSopenharmony_ci } 647275793eaSopenharmony_ci if ((c == 'o') || (c == 'O')) 648275793eaSopenharmony_ci { 649275793eaSopenharmony_ci opt_overwrite=1; 650275793eaSopenharmony_ci } 651275793eaSopenharmony_ci if ((c == 'd') || (c == 'D')) 652275793eaSopenharmony_ci { 653275793eaSopenharmony_ci opt_extractdir = 1; 654275793eaSopenharmony_ci dirname = argv[i+1]; 655275793eaSopenharmony_ci } 656275793eaSopenharmony_ci 657275793eaSopenharmony_ci if (((c == 'p') || (c == 'P')) && (i+1 < argc)) 658275793eaSopenharmony_ci { 659275793eaSopenharmony_ci password = argv[i+1]; 660275793eaSopenharmony_ci i++; 661275793eaSopenharmony_ci } 662275793eaSopenharmony_ci } 663275793eaSopenharmony_ci } 664275793eaSopenharmony_ci else 665275793eaSopenharmony_ci { 666275793eaSopenharmony_ci if (zipfilename == NULL) 667275793eaSopenharmony_ci { 668275793eaSopenharmony_ci zipfilename = argv[i]; 669275793eaSopenharmony_ci } 670275793eaSopenharmony_ci else if ((filename_to_extract == NULL) && (!opt_extractdir)) 671275793eaSopenharmony_ci { 672275793eaSopenharmony_ci filename_to_extract = argv[i]; 673275793eaSopenharmony_ci } 674275793eaSopenharmony_ci } 675275793eaSopenharmony_ci } 676275793eaSopenharmony_ci } 677275793eaSopenharmony_ci 678275793eaSopenharmony_ci if (zipfilename != NULL) 679275793eaSopenharmony_ci { 680275793eaSopenharmony_ci 681275793eaSopenharmony_ci# ifdef USEWIN32IOAPI 682275793eaSopenharmony_ci zlib_filefunc64_def ffunc; 683275793eaSopenharmony_ci# endif 684275793eaSopenharmony_ci 685275793eaSopenharmony_ci strncpy(filename_try, zipfilename,MAXFILENAME-1); 686275793eaSopenharmony_ci /* strncpy doesn't append the trailing NULL, of the string is too long. */ 687275793eaSopenharmony_ci filename_try[ MAXFILENAME ] = '\0'; 688275793eaSopenharmony_ci 689275793eaSopenharmony_ci# ifdef USEWIN32IOAPI 690275793eaSopenharmony_ci fill_win32_filefunc64A(&ffunc); 691275793eaSopenharmony_ci uf = unzOpen2_64(zipfilename,&ffunc); 692275793eaSopenharmony_ci# else 693275793eaSopenharmony_ci uf = unzOpen64(zipfilename); 694275793eaSopenharmony_ci# endif 695275793eaSopenharmony_ci if (uf == NULL) 696275793eaSopenharmony_ci { 697275793eaSopenharmony_ci strcat(filename_try,".zip"); 698275793eaSopenharmony_ci# ifdef USEWIN32IOAPI 699275793eaSopenharmony_ci uf = unzOpen2_64(filename_try,&ffunc); 700275793eaSopenharmony_ci# else 701275793eaSopenharmony_ci uf = unzOpen64(filename_try); 702275793eaSopenharmony_ci# endif 703275793eaSopenharmony_ci } 704275793eaSopenharmony_ci } 705275793eaSopenharmony_ci 706275793eaSopenharmony_ci if (uf == NULL) 707275793eaSopenharmony_ci { 708275793eaSopenharmony_ci printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename); 709275793eaSopenharmony_ci return 1; 710275793eaSopenharmony_ci } 711275793eaSopenharmony_ci printf("%s opened\n",filename_try); 712275793eaSopenharmony_ci 713275793eaSopenharmony_ci if (opt_do_list == 1) 714275793eaSopenharmony_ci ret_value = do_list(uf); 715275793eaSopenharmony_ci else if (opt_do_extract == 1) 716275793eaSopenharmony_ci { 717275793eaSopenharmony_ci#ifdef _WIN32 718275793eaSopenharmony_ci if (opt_extractdir && _chdir(dirname)) 719275793eaSopenharmony_ci#else 720275793eaSopenharmony_ci if (opt_extractdir && chdir(dirname)) 721275793eaSopenharmony_ci#endif 722275793eaSopenharmony_ci { 723275793eaSopenharmony_ci printf("Error changing into %s, aborting\n", dirname); 724275793eaSopenharmony_ci exit(-1); 725275793eaSopenharmony_ci } 726275793eaSopenharmony_ci 727275793eaSopenharmony_ci if (filename_to_extract == NULL) 728275793eaSopenharmony_ci { 729275793eaSopenharmony_ci ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password); 730275793eaSopenharmony_ci } 731275793eaSopenharmony_ci else 732275793eaSopenharmony_ci { 733275793eaSopenharmony_ci ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password); 734275793eaSopenharmony_ci } 735275793eaSopenharmony_ci } 736275793eaSopenharmony_ci 737275793eaSopenharmony_ci unzClose(uf); 738275793eaSopenharmony_ci 739275793eaSopenharmony_ci return ret_value; 740275793eaSopenharmony_ci} 741