annotate src/zlib-1.2.7/contrib/minizip/miniunz.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents e13257ea84a4
children
rev   line source
Chris@4 1 /*
Chris@4 2 miniunz.c
Chris@4 3 Version 1.1, February 14h, 2010
Chris@4 4 sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Chris@4 5
Chris@4 6 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Chris@4 7
Chris@4 8 Modifications of Unzip for Zip64
Chris@4 9 Copyright (C) 2007-2008 Even Rouault
Chris@4 10
Chris@4 11 Modifications for Zip64 support on both zip and unzip
Chris@4 12 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
Chris@4 13 */
Chris@4 14
Chris@4 15 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
Chris@4 16 #ifndef __USE_FILE_OFFSET64
Chris@4 17 #define __USE_FILE_OFFSET64
Chris@4 18 #endif
Chris@4 19 #ifndef __USE_LARGEFILE64
Chris@4 20 #define __USE_LARGEFILE64
Chris@4 21 #endif
Chris@4 22 #ifndef _LARGEFILE64_SOURCE
Chris@4 23 #define _LARGEFILE64_SOURCE
Chris@4 24 #endif
Chris@4 25 #ifndef _FILE_OFFSET_BIT
Chris@4 26 #define _FILE_OFFSET_BIT 64
Chris@4 27 #endif
Chris@4 28 #endif
Chris@4 29
Chris@4 30 #ifdef __APPLE__
Chris@4 31 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
Chris@4 32 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
Chris@4 33 #define FTELLO_FUNC(stream) ftello(stream)
Chris@4 34 #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
Chris@4 35 #else
Chris@4 36 #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
Chris@4 37 #define FTELLO_FUNC(stream) ftello64(stream)
Chris@4 38 #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
Chris@4 39 #endif
Chris@4 40
Chris@4 41
Chris@4 42 #include <stdio.h>
Chris@4 43 #include <stdlib.h>
Chris@4 44 #include <string.h>
Chris@4 45 #include <time.h>
Chris@4 46 #include <errno.h>
Chris@4 47 #include <fcntl.h>
Chris@4 48
Chris@4 49 #ifdef _WIN32
Chris@4 50 # include <direct.h>
Chris@4 51 # include <io.h>
Chris@4 52 #else
Chris@4 53 # include <unistd.h>
Chris@4 54 # include <utime.h>
Chris@4 55 #endif
Chris@4 56
Chris@4 57
Chris@4 58 #include "unzip.h"
Chris@4 59
Chris@4 60 #define CASESENSITIVITY (0)
Chris@4 61 #define WRITEBUFFERSIZE (8192)
Chris@4 62 #define MAXFILENAME (256)
Chris@4 63
Chris@4 64 #ifdef _WIN32
Chris@4 65 #define USEWIN32IOAPI
Chris@4 66 #include "iowin32.h"
Chris@4 67 #endif
Chris@4 68 /*
Chris@4 69 mini unzip, demo of unzip package
Chris@4 70
Chris@4 71 usage :
Chris@4 72 Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
Chris@4 73
Chris@4 74 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
Chris@4 75 if it exists
Chris@4 76 */
Chris@4 77
Chris@4 78
Chris@4 79 /* change_file_date : change the date/time of a file
Chris@4 80 filename : the filename of the file where date/time must be modified
Chris@4 81 dosdate : the new date at the MSDos format (4 bytes)
Chris@4 82 tmu_date : the SAME new date at the tm_unz format */
Chris@4 83 void change_file_date(filename,dosdate,tmu_date)
Chris@4 84 const char *filename;
Chris@4 85 uLong dosdate;
Chris@4 86 tm_unz tmu_date;
Chris@4 87 {
Chris@4 88 #ifdef _WIN32
Chris@4 89 HANDLE hFile;
Chris@4 90 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
Chris@4 91
Chris@4 92 hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
Chris@4 93 0,NULL,OPEN_EXISTING,0,NULL);
Chris@4 94 GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
Chris@4 95 DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
Chris@4 96 LocalFileTimeToFileTime(&ftLocal,&ftm);
Chris@4 97 SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
Chris@4 98 CloseHandle(hFile);
Chris@4 99 #else
Chris@4 100 #ifdef unix || __APPLE__
Chris@4 101 struct utimbuf ut;
Chris@4 102 struct tm newdate;
Chris@4 103 newdate.tm_sec = tmu_date.tm_sec;
Chris@4 104 newdate.tm_min=tmu_date.tm_min;
Chris@4 105 newdate.tm_hour=tmu_date.tm_hour;
Chris@4 106 newdate.tm_mday=tmu_date.tm_mday;
Chris@4 107 newdate.tm_mon=tmu_date.tm_mon;
Chris@4 108 if (tmu_date.tm_year > 1900)
Chris@4 109 newdate.tm_year=tmu_date.tm_year - 1900;
Chris@4 110 else
Chris@4 111 newdate.tm_year=tmu_date.tm_year ;
Chris@4 112 newdate.tm_isdst=-1;
Chris@4 113
Chris@4 114 ut.actime=ut.modtime=mktime(&newdate);
Chris@4 115 utime(filename,&ut);
Chris@4 116 #endif
Chris@4 117 #endif
Chris@4 118 }
Chris@4 119
Chris@4 120
Chris@4 121 /* mymkdir and change_file_date are not 100 % portable
Chris@4 122 As I don't know well Unix, I wait feedback for the unix portion */
Chris@4 123
Chris@4 124 int mymkdir(dirname)
Chris@4 125 const char* dirname;
Chris@4 126 {
Chris@4 127 int ret=0;
Chris@4 128 #ifdef _WIN32
Chris@4 129 ret = _mkdir(dirname);
Chris@4 130 #elif unix
Chris@4 131 ret = mkdir (dirname,0775);
Chris@4 132 #elif __APPLE__
Chris@4 133 ret = mkdir (dirname,0775);
Chris@4 134 #endif
Chris@4 135 return ret;
Chris@4 136 }
Chris@4 137
Chris@4 138 int makedir (newdir)
Chris@4 139 char *newdir;
Chris@4 140 {
Chris@4 141 char *buffer ;
Chris@4 142 char *p;
Chris@4 143 int len = (int)strlen(newdir);
Chris@4 144
Chris@4 145 if (len <= 0)
Chris@4 146 return 0;
Chris@4 147
Chris@4 148 buffer = (char*)malloc(len+1);
Chris@4 149 if (buffer==NULL)
Chris@4 150 {
Chris@4 151 printf("Error allocating memory\n");
Chris@4 152 return UNZ_INTERNALERROR;
Chris@4 153 }
Chris@4 154 strcpy(buffer,newdir);
Chris@4 155
Chris@4 156 if (buffer[len-1] == '/') {
Chris@4 157 buffer[len-1] = '\0';
Chris@4 158 }
Chris@4 159 if (mymkdir(buffer) == 0)
Chris@4 160 {
Chris@4 161 free(buffer);
Chris@4 162 return 1;
Chris@4 163 }
Chris@4 164
Chris@4 165 p = buffer+1;
Chris@4 166 while (1)
Chris@4 167 {
Chris@4 168 char hold;
Chris@4 169
Chris@4 170 while(*p && *p != '\\' && *p != '/')
Chris@4 171 p++;
Chris@4 172 hold = *p;
Chris@4 173 *p = 0;
Chris@4 174 if ((mymkdir(buffer) == -1) && (errno == ENOENT))
Chris@4 175 {
Chris@4 176 printf("couldn't create directory %s\n",buffer);
Chris@4 177 free(buffer);
Chris@4 178 return 0;
Chris@4 179 }
Chris@4 180 if (hold == 0)
Chris@4 181 break;
Chris@4 182 *p++ = hold;
Chris@4 183 }
Chris@4 184 free(buffer);
Chris@4 185 return 1;
Chris@4 186 }
Chris@4 187
Chris@4 188 void do_banner()
Chris@4 189 {
Chris@4 190 printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
Chris@4 191 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
Chris@4 192 }
Chris@4 193
Chris@4 194 void do_help()
Chris@4 195 {
Chris@4 196 printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
Chris@4 197 " -e Extract without pathname (junk paths)\n" \
Chris@4 198 " -x Extract with pathname\n" \
Chris@4 199 " -v list files\n" \
Chris@4 200 " -l list files\n" \
Chris@4 201 " -d directory to extract into\n" \
Chris@4 202 " -o overwrite files without prompting\n" \
Chris@4 203 " -p extract crypted file using password\n\n");
Chris@4 204 }
Chris@4 205
Chris@4 206 void Display64BitsSize(ZPOS64_T n, int size_char)
Chris@4 207 {
Chris@4 208 /* to avoid compatibility problem , we do here the conversion */
Chris@4 209 char number[21];
Chris@4 210 int offset=19;
Chris@4 211 int pos_string = 19;
Chris@4 212 number[20]=0;
Chris@4 213 for (;;) {
Chris@4 214 number[offset]=(char)((n%10)+'0');
Chris@4 215 if (number[offset] != '0')
Chris@4 216 pos_string=offset;
Chris@4 217 n/=10;
Chris@4 218 if (offset==0)
Chris@4 219 break;
Chris@4 220 offset--;
Chris@4 221 }
Chris@4 222 {
Chris@4 223 int size_display_string = 19-pos_string;
Chris@4 224 while (size_char > size_display_string)
Chris@4 225 {
Chris@4 226 size_char--;
Chris@4 227 printf(" ");
Chris@4 228 }
Chris@4 229 }
Chris@4 230
Chris@4 231 printf("%s",&number[pos_string]);
Chris@4 232 }
Chris@4 233
Chris@4 234 int do_list(uf)
Chris@4 235 unzFile uf;
Chris@4 236 {
Chris@4 237 uLong i;
Chris@4 238 unz_global_info64 gi;
Chris@4 239 int err;
Chris@4 240
Chris@4 241 err = unzGetGlobalInfo64(uf,&gi);
Chris@4 242 if (err!=UNZ_OK)
Chris@4 243 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
Chris@4 244 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
Chris@4 245 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
Chris@4 246 for (i=0;i<gi.number_entry;i++)
Chris@4 247 {
Chris@4 248 char filename_inzip[256];
Chris@4 249 unz_file_info64 file_info;
Chris@4 250 uLong ratio=0;
Chris@4 251 const char *string_method;
Chris@4 252 char charCrypt=' ';
Chris@4 253 err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
Chris@4 254 if (err!=UNZ_OK)
Chris@4 255 {
Chris@4 256 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
Chris@4 257 break;
Chris@4 258 }
Chris@4 259 if (file_info.uncompressed_size>0)
Chris@4 260 ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
Chris@4 261
Chris@4 262 /* display a '*' if the file is crypted */
Chris@4 263 if ((file_info.flag & 1) != 0)
Chris@4 264 charCrypt='*';
Chris@4 265
Chris@4 266 if (file_info.compression_method==0)
Chris@4 267 string_method="Stored";
Chris@4 268 else
Chris@4 269 if (file_info.compression_method==Z_DEFLATED)
Chris@4 270 {
Chris@4 271 uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
Chris@4 272 if (iLevel==0)
Chris@4 273 string_method="Defl:N";
Chris@4 274 else if (iLevel==1)
Chris@4 275 string_method="Defl:X";
Chris@4 276 else if ((iLevel==2) || (iLevel==3))
Chris@4 277 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
Chris@4 278 }
Chris@4 279 else
Chris@4 280 if (file_info.compression_method==Z_BZIP2ED)
Chris@4 281 {
Chris@4 282 string_method="BZip2 ";
Chris@4 283 }
Chris@4 284 else
Chris@4 285 string_method="Unkn. ";
Chris@4 286
Chris@4 287 Display64BitsSize(file_info.uncompressed_size,7);
Chris@4 288 printf(" %6s%c",string_method,charCrypt);
Chris@4 289 Display64BitsSize(file_info.compressed_size,7);
Chris@4 290 printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
Chris@4 291 ratio,
Chris@4 292 (uLong)file_info.tmu_date.tm_mon + 1,
Chris@4 293 (uLong)file_info.tmu_date.tm_mday,
Chris@4 294 (uLong)file_info.tmu_date.tm_year % 100,
Chris@4 295 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
Chris@4 296 (uLong)file_info.crc,filename_inzip);
Chris@4 297 if ((i+1)<gi.number_entry)
Chris@4 298 {
Chris@4 299 err = unzGoToNextFile(uf);
Chris@4 300 if (err!=UNZ_OK)
Chris@4 301 {
Chris@4 302 printf("error %d with zipfile in unzGoToNextFile\n",err);
Chris@4 303 break;
Chris@4 304 }
Chris@4 305 }
Chris@4 306 }
Chris@4 307
Chris@4 308 return 0;
Chris@4 309 }
Chris@4 310
Chris@4 311
Chris@4 312 int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
Chris@4 313 unzFile uf;
Chris@4 314 const int* popt_extract_without_path;
Chris@4 315 int* popt_overwrite;
Chris@4 316 const char* password;
Chris@4 317 {
Chris@4 318 char filename_inzip[256];
Chris@4 319 char* filename_withoutpath;
Chris@4 320 char* p;
Chris@4 321 int err=UNZ_OK;
Chris@4 322 FILE *fout=NULL;
Chris@4 323 void* buf;
Chris@4 324 uInt size_buf;
Chris@4 325
Chris@4 326 unz_file_info64 file_info;
Chris@4 327 uLong ratio=0;
Chris@4 328 err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
Chris@4 329
Chris@4 330 if (err!=UNZ_OK)
Chris@4 331 {
Chris@4 332 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
Chris@4 333 return err;
Chris@4 334 }
Chris@4 335
Chris@4 336 size_buf = WRITEBUFFERSIZE;
Chris@4 337 buf = (void*)malloc(size_buf);
Chris@4 338 if (buf==NULL)
Chris@4 339 {
Chris@4 340 printf("Error allocating memory\n");
Chris@4 341 return UNZ_INTERNALERROR;
Chris@4 342 }
Chris@4 343
Chris@4 344 p = filename_withoutpath = filename_inzip;
Chris@4 345 while ((*p) != '\0')
Chris@4 346 {
Chris@4 347 if (((*p)=='/') || ((*p)=='\\'))
Chris@4 348 filename_withoutpath = p+1;
Chris@4 349 p++;
Chris@4 350 }
Chris@4 351
Chris@4 352 if ((*filename_withoutpath)=='\0')
Chris@4 353 {
Chris@4 354 if ((*popt_extract_without_path)==0)
Chris@4 355 {
Chris@4 356 printf("creating directory: %s\n",filename_inzip);
Chris@4 357 mymkdir(filename_inzip);
Chris@4 358 }
Chris@4 359 }
Chris@4 360 else
Chris@4 361 {
Chris@4 362 const char* write_filename;
Chris@4 363 int skip=0;
Chris@4 364
Chris@4 365 if ((*popt_extract_without_path)==0)
Chris@4 366 write_filename = filename_inzip;
Chris@4 367 else
Chris@4 368 write_filename = filename_withoutpath;
Chris@4 369
Chris@4 370 err = unzOpenCurrentFilePassword(uf,password);
Chris@4 371 if (err!=UNZ_OK)
Chris@4 372 {
Chris@4 373 printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
Chris@4 374 }
Chris@4 375
Chris@4 376 if (((*popt_overwrite)==0) && (err==UNZ_OK))
Chris@4 377 {
Chris@4 378 char rep=0;
Chris@4 379 FILE* ftestexist;
Chris@4 380 ftestexist = FOPEN_FUNC(write_filename,"rb");
Chris@4 381 if (ftestexist!=NULL)
Chris@4 382 {
Chris@4 383 fclose(ftestexist);
Chris@4 384 do
Chris@4 385 {
Chris@4 386 char answer[128];
Chris@4 387 int ret;
Chris@4 388
Chris@4 389 printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
Chris@4 390 ret = scanf("%1s",answer);
Chris@4 391 if (ret != 1)
Chris@4 392 {
Chris@4 393 exit(EXIT_FAILURE);
Chris@4 394 }
Chris@4 395 rep = answer[0] ;
Chris@4 396 if ((rep>='a') && (rep<='z'))
Chris@4 397 rep -= 0x20;
Chris@4 398 }
Chris@4 399 while ((rep!='Y') && (rep!='N') && (rep!='A'));
Chris@4 400 }
Chris@4 401
Chris@4 402 if (rep == 'N')
Chris@4 403 skip = 1;
Chris@4 404
Chris@4 405 if (rep == 'A')
Chris@4 406 *popt_overwrite=1;
Chris@4 407 }
Chris@4 408
Chris@4 409 if ((skip==0) && (err==UNZ_OK))
Chris@4 410 {
Chris@4 411 fout=FOPEN_FUNC(write_filename,"wb");
Chris@4 412 /* some zipfile don't contain directory alone before file */
Chris@4 413 if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
Chris@4 414 (filename_withoutpath!=(char*)filename_inzip))
Chris@4 415 {
Chris@4 416 char c=*(filename_withoutpath-1);
Chris@4 417 *(filename_withoutpath-1)='\0';
Chris@4 418 makedir(write_filename);
Chris@4 419 *(filename_withoutpath-1)=c;
Chris@4 420 fout=FOPEN_FUNC(write_filename,"wb");
Chris@4 421 }
Chris@4 422
Chris@4 423 if (fout==NULL)
Chris@4 424 {
Chris@4 425 printf("error opening %s\n",write_filename);
Chris@4 426 }
Chris@4 427 }
Chris@4 428
Chris@4 429 if (fout!=NULL)
Chris@4 430 {
Chris@4 431 printf(" extracting: %s\n",write_filename);
Chris@4 432
Chris@4 433 do
Chris@4 434 {
Chris@4 435 err = unzReadCurrentFile(uf,buf,size_buf);
Chris@4 436 if (err<0)
Chris@4 437 {
Chris@4 438 printf("error %d with zipfile in unzReadCurrentFile\n",err);
Chris@4 439 break;
Chris@4 440 }
Chris@4 441 if (err>0)
Chris@4 442 if (fwrite(buf,err,1,fout)!=1)
Chris@4 443 {
Chris@4 444 printf("error in writing extracted file\n");
Chris@4 445 err=UNZ_ERRNO;
Chris@4 446 break;
Chris@4 447 }
Chris@4 448 }
Chris@4 449 while (err>0);
Chris@4 450 if (fout)
Chris@4 451 fclose(fout);
Chris@4 452
Chris@4 453 if (err==0)
Chris@4 454 change_file_date(write_filename,file_info.dosDate,
Chris@4 455 file_info.tmu_date);
Chris@4 456 }
Chris@4 457
Chris@4 458 if (err==UNZ_OK)
Chris@4 459 {
Chris@4 460 err = unzCloseCurrentFile (uf);
Chris@4 461 if (err!=UNZ_OK)
Chris@4 462 {
Chris@4 463 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
Chris@4 464 }
Chris@4 465 }
Chris@4 466 else
Chris@4 467 unzCloseCurrentFile(uf); /* don't lose the error */
Chris@4 468 }
Chris@4 469
Chris@4 470 free(buf);
Chris@4 471 return err;
Chris@4 472 }
Chris@4 473
Chris@4 474
Chris@4 475 int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
Chris@4 476 unzFile uf;
Chris@4 477 int opt_extract_without_path;
Chris@4 478 int opt_overwrite;
Chris@4 479 const char* password;
Chris@4 480 {
Chris@4 481 uLong i;
Chris@4 482 unz_global_info64 gi;
Chris@4 483 int err;
Chris@4 484 FILE* fout=NULL;
Chris@4 485
Chris@4 486 err = unzGetGlobalInfo64(uf,&gi);
Chris@4 487 if (err!=UNZ_OK)
Chris@4 488 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
Chris@4 489
Chris@4 490 for (i=0;i<gi.number_entry;i++)
Chris@4 491 {
Chris@4 492 if (do_extract_currentfile(uf,&opt_extract_without_path,
Chris@4 493 &opt_overwrite,
Chris@4 494 password) != UNZ_OK)
Chris@4 495 break;
Chris@4 496
Chris@4 497 if ((i+1)<gi.number_entry)
Chris@4 498 {
Chris@4 499 err = unzGoToNextFile(uf);
Chris@4 500 if (err!=UNZ_OK)
Chris@4 501 {
Chris@4 502 printf("error %d with zipfile in unzGoToNextFile\n",err);
Chris@4 503 break;
Chris@4 504 }
Chris@4 505 }
Chris@4 506 }
Chris@4 507
Chris@4 508 return 0;
Chris@4 509 }
Chris@4 510
Chris@4 511 int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
Chris@4 512 unzFile uf;
Chris@4 513 const char* filename;
Chris@4 514 int opt_extract_without_path;
Chris@4 515 int opt_overwrite;
Chris@4 516 const char* password;
Chris@4 517 {
Chris@4 518 int err = UNZ_OK;
Chris@4 519 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
Chris@4 520 {
Chris@4 521 printf("file %s not found in the zipfile\n",filename);
Chris@4 522 return 2;
Chris@4 523 }
Chris@4 524
Chris@4 525 if (do_extract_currentfile(uf,&opt_extract_without_path,
Chris@4 526 &opt_overwrite,
Chris@4 527 password) == UNZ_OK)
Chris@4 528 return 0;
Chris@4 529 else
Chris@4 530 return 1;
Chris@4 531 }
Chris@4 532
Chris@4 533
Chris@4 534 int main(argc,argv)
Chris@4 535 int argc;
Chris@4 536 char *argv[];
Chris@4 537 {
Chris@4 538 const char *zipfilename=NULL;
Chris@4 539 const char *filename_to_extract=NULL;
Chris@4 540 const char *password=NULL;
Chris@4 541 char filename_try[MAXFILENAME+16] = "";
Chris@4 542 int i;
Chris@4 543 int ret_value=0;
Chris@4 544 int opt_do_list=0;
Chris@4 545 int opt_do_extract=1;
Chris@4 546 int opt_do_extract_withoutpath=0;
Chris@4 547 int opt_overwrite=0;
Chris@4 548 int opt_extractdir=0;
Chris@4 549 const char *dirname=NULL;
Chris@4 550 unzFile uf=NULL;
Chris@4 551
Chris@4 552 do_banner();
Chris@4 553 if (argc==1)
Chris@4 554 {
Chris@4 555 do_help();
Chris@4 556 return 0;
Chris@4 557 }
Chris@4 558 else
Chris@4 559 {
Chris@4 560 for (i=1;i<argc;i++)
Chris@4 561 {
Chris@4 562 if ((*argv[i])=='-')
Chris@4 563 {
Chris@4 564 const char *p=argv[i]+1;
Chris@4 565
Chris@4 566 while ((*p)!='\0')
Chris@4 567 {
Chris@4 568 char c=*(p++);;
Chris@4 569 if ((c=='l') || (c=='L'))
Chris@4 570 opt_do_list = 1;
Chris@4 571 if ((c=='v') || (c=='V'))
Chris@4 572 opt_do_list = 1;
Chris@4 573 if ((c=='x') || (c=='X'))
Chris@4 574 opt_do_extract = 1;
Chris@4 575 if ((c=='e') || (c=='E'))
Chris@4 576 opt_do_extract = opt_do_extract_withoutpath = 1;
Chris@4 577 if ((c=='o') || (c=='O'))
Chris@4 578 opt_overwrite=1;
Chris@4 579 if ((c=='d') || (c=='D'))
Chris@4 580 {
Chris@4 581 opt_extractdir=1;
Chris@4 582 dirname=argv[i+1];
Chris@4 583 }
Chris@4 584
Chris@4 585 if (((c=='p') || (c=='P')) && (i+1<argc))
Chris@4 586 {
Chris@4 587 password=argv[i+1];
Chris@4 588 i++;
Chris@4 589 }
Chris@4 590 }
Chris@4 591 }
Chris@4 592 else
Chris@4 593 {
Chris@4 594 if (zipfilename == NULL)
Chris@4 595 zipfilename = argv[i];
Chris@4 596 else if ((filename_to_extract==NULL) && (!opt_extractdir))
Chris@4 597 filename_to_extract = argv[i] ;
Chris@4 598 }
Chris@4 599 }
Chris@4 600 }
Chris@4 601
Chris@4 602 if (zipfilename!=NULL)
Chris@4 603 {
Chris@4 604
Chris@4 605 # ifdef USEWIN32IOAPI
Chris@4 606 zlib_filefunc64_def ffunc;
Chris@4 607 # endif
Chris@4 608
Chris@4 609 strncpy(filename_try, zipfilename,MAXFILENAME-1);
Chris@4 610 /* strncpy doesnt append the trailing NULL, of the string is too long. */
Chris@4 611 filename_try[ MAXFILENAME ] = '\0';
Chris@4 612
Chris@4 613 # ifdef USEWIN32IOAPI
Chris@4 614 fill_win32_filefunc64A(&ffunc);
Chris@4 615 uf = unzOpen2_64(zipfilename,&ffunc);
Chris@4 616 # else
Chris@4 617 uf = unzOpen64(zipfilename);
Chris@4 618 # endif
Chris@4 619 if (uf==NULL)
Chris@4 620 {
Chris@4 621 strcat(filename_try,".zip");
Chris@4 622 # ifdef USEWIN32IOAPI
Chris@4 623 uf = unzOpen2_64(filename_try,&ffunc);
Chris@4 624 # else
Chris@4 625 uf = unzOpen64(filename_try);
Chris@4 626 # endif
Chris@4 627 }
Chris@4 628 }
Chris@4 629
Chris@4 630 if (uf==NULL)
Chris@4 631 {
Chris@4 632 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
Chris@4 633 return 1;
Chris@4 634 }
Chris@4 635 printf("%s opened\n",filename_try);
Chris@4 636
Chris@4 637 if (opt_do_list==1)
Chris@4 638 ret_value = do_list(uf);
Chris@4 639 else if (opt_do_extract==1)
Chris@4 640 {
Chris@4 641 #ifdef _WIN32
Chris@4 642 if (opt_extractdir && _chdir(dirname))
Chris@4 643 #else
Chris@4 644 if (opt_extractdir && chdir(dirname))
Chris@4 645 #endif
Chris@4 646 {
Chris@4 647 printf("Error changing into %s, aborting\n", dirname);
Chris@4 648 exit(-1);
Chris@4 649 }
Chris@4 650
Chris@4 651 if (filename_to_extract == NULL)
Chris@4 652 ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
Chris@4 653 else
Chris@4 654 ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
Chris@4 655 }
Chris@4 656
Chris@4 657 unzClose(uf);
Chris@4 658
Chris@4 659 return ret_value;
Chris@4 660 }