annotate src/zlib-1.2.7/contrib/minizip/minizip.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 minizip.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
Chris@4 16 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
Chris@4 17 #ifndef __USE_FILE_OFFSET64
Chris@4 18 #define __USE_FILE_OFFSET64
Chris@4 19 #endif
Chris@4 20 #ifndef __USE_LARGEFILE64
Chris@4 21 #define __USE_LARGEFILE64
Chris@4 22 #endif
Chris@4 23 #ifndef _LARGEFILE64_SOURCE
Chris@4 24 #define _LARGEFILE64_SOURCE
Chris@4 25 #endif
Chris@4 26 #ifndef _FILE_OFFSET_BIT
Chris@4 27 #define _FILE_OFFSET_BIT 64
Chris@4 28 #endif
Chris@4 29 #endif
Chris@4 30
Chris@4 31 #ifdef __APPLE__
Chris@4 32 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
Chris@4 33 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
Chris@4 34 #define FTELLO_FUNC(stream) ftello(stream)
Chris@4 35 #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
Chris@4 36 #else
Chris@4 37 #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
Chris@4 38 #define FTELLO_FUNC(stream) ftello64(stream)
Chris@4 39 #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
Chris@4 40 #endif
Chris@4 41
Chris@4 42
Chris@4 43
Chris@4 44 #include <stdio.h>
Chris@4 45 #include <stdlib.h>
Chris@4 46 #include <string.h>
Chris@4 47 #include <time.h>
Chris@4 48 #include <errno.h>
Chris@4 49 #include <fcntl.h>
Chris@4 50
Chris@4 51 #ifdef _WIN32
Chris@4 52 # include <direct.h>
Chris@4 53 # include <io.h>
Chris@4 54 #else
Chris@4 55 # include <unistd.h>
Chris@4 56 # include <utime.h>
Chris@4 57 # include <sys/types.h>
Chris@4 58 # include <sys/stat.h>
Chris@4 59 #endif
Chris@4 60
Chris@4 61 #include "zip.h"
Chris@4 62
Chris@4 63 #ifdef _WIN32
Chris@4 64 #define USEWIN32IOAPI
Chris@4 65 #include "iowin32.h"
Chris@4 66 #endif
Chris@4 67
Chris@4 68
Chris@4 69
Chris@4 70 #define WRITEBUFFERSIZE (16384)
Chris@4 71 #define MAXFILENAME (256)
Chris@4 72
Chris@4 73 #ifdef _WIN32
Chris@4 74 uLong filetime(f, tmzip, dt)
Chris@4 75 char *f; /* name of file to get info on */
Chris@4 76 tm_zip *tmzip; /* return value: access, modific. and creation times */
Chris@4 77 uLong *dt; /* dostime */
Chris@4 78 {
Chris@4 79 int ret = 0;
Chris@4 80 {
Chris@4 81 FILETIME ftLocal;
Chris@4 82 HANDLE hFind;
Chris@4 83 WIN32_FIND_DATAA ff32;
Chris@4 84
Chris@4 85 hFind = FindFirstFileA(f,&ff32);
Chris@4 86 if (hFind != INVALID_HANDLE_VALUE)
Chris@4 87 {
Chris@4 88 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
Chris@4 89 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
Chris@4 90 FindClose(hFind);
Chris@4 91 ret = 1;
Chris@4 92 }
Chris@4 93 }
Chris@4 94 return ret;
Chris@4 95 }
Chris@4 96 #else
Chris@4 97 #ifdef unix || __APPLE__
Chris@4 98 uLong filetime(f, tmzip, dt)
Chris@4 99 char *f; /* name of file to get info on */
Chris@4 100 tm_zip *tmzip; /* return value: access, modific. and creation times */
Chris@4 101 uLong *dt; /* dostime */
Chris@4 102 {
Chris@4 103 int ret=0;
Chris@4 104 struct stat s; /* results of stat() */
Chris@4 105 struct tm* filedate;
Chris@4 106 time_t tm_t=0;
Chris@4 107
Chris@4 108 if (strcmp(f,"-")!=0)
Chris@4 109 {
Chris@4 110 char name[MAXFILENAME+1];
Chris@4 111 int len = strlen(f);
Chris@4 112 if (len > MAXFILENAME)
Chris@4 113 len = MAXFILENAME;
Chris@4 114
Chris@4 115 strncpy(name, f,MAXFILENAME-1);
Chris@4 116 /* strncpy doesnt append the trailing NULL, of the string is too long. */
Chris@4 117 name[ MAXFILENAME ] = '\0';
Chris@4 118
Chris@4 119 if (name[len - 1] == '/')
Chris@4 120 name[len - 1] = '\0';
Chris@4 121 /* not all systems allow stat'ing a file with / appended */
Chris@4 122 if (stat(name,&s)==0)
Chris@4 123 {
Chris@4 124 tm_t = s.st_mtime;
Chris@4 125 ret = 1;
Chris@4 126 }
Chris@4 127 }
Chris@4 128 filedate = localtime(&tm_t);
Chris@4 129
Chris@4 130 tmzip->tm_sec = filedate->tm_sec;
Chris@4 131 tmzip->tm_min = filedate->tm_min;
Chris@4 132 tmzip->tm_hour = filedate->tm_hour;
Chris@4 133 tmzip->tm_mday = filedate->tm_mday;
Chris@4 134 tmzip->tm_mon = filedate->tm_mon ;
Chris@4 135 tmzip->tm_year = filedate->tm_year;
Chris@4 136
Chris@4 137 return ret;
Chris@4 138 }
Chris@4 139 #else
Chris@4 140 uLong filetime(f, tmzip, dt)
Chris@4 141 char *f; /* name of file to get info on */
Chris@4 142 tm_zip *tmzip; /* return value: access, modific. and creation times */
Chris@4 143 uLong *dt; /* dostime */
Chris@4 144 {
Chris@4 145 return 0;
Chris@4 146 }
Chris@4 147 #endif
Chris@4 148 #endif
Chris@4 149
Chris@4 150
Chris@4 151
Chris@4 152
Chris@4 153 int check_exist_file(filename)
Chris@4 154 const char* filename;
Chris@4 155 {
Chris@4 156 FILE* ftestexist;
Chris@4 157 int ret = 1;
Chris@4 158 ftestexist = FOPEN_FUNC(filename,"rb");
Chris@4 159 if (ftestexist==NULL)
Chris@4 160 ret = 0;
Chris@4 161 else
Chris@4 162 fclose(ftestexist);
Chris@4 163 return ret;
Chris@4 164 }
Chris@4 165
Chris@4 166 void do_banner()
Chris@4 167 {
Chris@4 168 printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
Chris@4 169 printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
Chris@4 170 }
Chris@4 171
Chris@4 172 void do_help()
Chris@4 173 {
Chris@4 174 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
Chris@4 175 " -o Overwrite existing file.zip\n" \
Chris@4 176 " -a Append to existing file.zip\n" \
Chris@4 177 " -0 Store only\n" \
Chris@4 178 " -1 Compress faster\n" \
Chris@4 179 " -9 Compress better\n\n" \
Chris@4 180 " -j exclude path. store only the file name.\n\n");
Chris@4 181 }
Chris@4 182
Chris@4 183 /* calculate the CRC32 of a file,
Chris@4 184 because to encrypt a file, we need known the CRC32 of the file before */
Chris@4 185 int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
Chris@4 186 {
Chris@4 187 unsigned long calculate_crc=0;
Chris@4 188 int err=ZIP_OK;
Chris@4 189 FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
Chris@4 190
Chris@4 191 unsigned long size_read = 0;
Chris@4 192 unsigned long total_read = 0;
Chris@4 193 if (fin==NULL)
Chris@4 194 {
Chris@4 195 err = ZIP_ERRNO;
Chris@4 196 }
Chris@4 197
Chris@4 198 if (err == ZIP_OK)
Chris@4 199 do
Chris@4 200 {
Chris@4 201 err = ZIP_OK;
Chris@4 202 size_read = (int)fread(buf,1,size_buf,fin);
Chris@4 203 if (size_read < size_buf)
Chris@4 204 if (feof(fin)==0)
Chris@4 205 {
Chris@4 206 printf("error in reading %s\n",filenameinzip);
Chris@4 207 err = ZIP_ERRNO;
Chris@4 208 }
Chris@4 209
Chris@4 210 if (size_read>0)
Chris@4 211 calculate_crc = crc32(calculate_crc,buf,size_read);
Chris@4 212 total_read += size_read;
Chris@4 213
Chris@4 214 } while ((err == ZIP_OK) && (size_read>0));
Chris@4 215
Chris@4 216 if (fin)
Chris@4 217 fclose(fin);
Chris@4 218
Chris@4 219 *result_crc=calculate_crc;
Chris@4 220 printf("file %s crc %lx\n", filenameinzip, calculate_crc);
Chris@4 221 return err;
Chris@4 222 }
Chris@4 223
Chris@4 224 int isLargeFile(const char* filename)
Chris@4 225 {
Chris@4 226 int largeFile = 0;
Chris@4 227 ZPOS64_T pos = 0;
Chris@4 228 FILE* pFile = FOPEN_FUNC(filename, "rb");
Chris@4 229
Chris@4 230 if(pFile != NULL)
Chris@4 231 {
Chris@4 232 int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
Chris@4 233 pos = FTELLO_FUNC(pFile);
Chris@4 234
Chris@4 235 printf("File : %s is %lld bytes\n", filename, pos);
Chris@4 236
Chris@4 237 if(pos >= 0xffffffff)
Chris@4 238 largeFile = 1;
Chris@4 239
Chris@4 240 fclose(pFile);
Chris@4 241 }
Chris@4 242
Chris@4 243 return largeFile;
Chris@4 244 }
Chris@4 245
Chris@4 246 int main(argc,argv)
Chris@4 247 int argc;
Chris@4 248 char *argv[];
Chris@4 249 {
Chris@4 250 int i;
Chris@4 251 int opt_overwrite=0;
Chris@4 252 int opt_compress_level=Z_DEFAULT_COMPRESSION;
Chris@4 253 int opt_exclude_path=0;
Chris@4 254 int zipfilenamearg = 0;
Chris@4 255 char filename_try[MAXFILENAME+16];
Chris@4 256 int zipok;
Chris@4 257 int err=0;
Chris@4 258 int size_buf=0;
Chris@4 259 void* buf=NULL;
Chris@4 260 const char* password=NULL;
Chris@4 261
Chris@4 262
Chris@4 263 do_banner();
Chris@4 264 if (argc==1)
Chris@4 265 {
Chris@4 266 do_help();
Chris@4 267 return 0;
Chris@4 268 }
Chris@4 269 else
Chris@4 270 {
Chris@4 271 for (i=1;i<argc;i++)
Chris@4 272 {
Chris@4 273 if ((*argv[i])=='-')
Chris@4 274 {
Chris@4 275 const char *p=argv[i]+1;
Chris@4 276
Chris@4 277 while ((*p)!='\0')
Chris@4 278 {
Chris@4 279 char c=*(p++);;
Chris@4 280 if ((c=='o') || (c=='O'))
Chris@4 281 opt_overwrite = 1;
Chris@4 282 if ((c=='a') || (c=='A'))
Chris@4 283 opt_overwrite = 2;
Chris@4 284 if ((c>='0') && (c<='9'))
Chris@4 285 opt_compress_level = c-'0';
Chris@4 286 if ((c=='j') || (c=='J'))
Chris@4 287 opt_exclude_path = 1;
Chris@4 288
Chris@4 289 if (((c=='p') || (c=='P')) && (i+1<argc))
Chris@4 290 {
Chris@4 291 password=argv[i+1];
Chris@4 292 i++;
Chris@4 293 }
Chris@4 294 }
Chris@4 295 }
Chris@4 296 else
Chris@4 297 {
Chris@4 298 if (zipfilenamearg == 0)
Chris@4 299 {
Chris@4 300 zipfilenamearg = i ;
Chris@4 301 }
Chris@4 302 }
Chris@4 303 }
Chris@4 304 }
Chris@4 305
Chris@4 306 size_buf = WRITEBUFFERSIZE;
Chris@4 307 buf = (void*)malloc(size_buf);
Chris@4 308 if (buf==NULL)
Chris@4 309 {
Chris@4 310 printf("Error allocating memory\n");
Chris@4 311 return ZIP_INTERNALERROR;
Chris@4 312 }
Chris@4 313
Chris@4 314 if (zipfilenamearg==0)
Chris@4 315 {
Chris@4 316 zipok=0;
Chris@4 317 }
Chris@4 318 else
Chris@4 319 {
Chris@4 320 int i,len;
Chris@4 321 int dot_found=0;
Chris@4 322
Chris@4 323 zipok = 1 ;
Chris@4 324 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
Chris@4 325 /* strncpy doesnt append the trailing NULL, of the string is too long. */
Chris@4 326 filename_try[ MAXFILENAME ] = '\0';
Chris@4 327
Chris@4 328 len=(int)strlen(filename_try);
Chris@4 329 for (i=0;i<len;i++)
Chris@4 330 if (filename_try[i]=='.')
Chris@4 331 dot_found=1;
Chris@4 332
Chris@4 333 if (dot_found==0)
Chris@4 334 strcat(filename_try,".zip");
Chris@4 335
Chris@4 336 if (opt_overwrite==2)
Chris@4 337 {
Chris@4 338 /* if the file don't exist, we not append file */
Chris@4 339 if (check_exist_file(filename_try)==0)
Chris@4 340 opt_overwrite=1;
Chris@4 341 }
Chris@4 342 else
Chris@4 343 if (opt_overwrite==0)
Chris@4 344 if (check_exist_file(filename_try)!=0)
Chris@4 345 {
Chris@4 346 char rep=0;
Chris@4 347 do
Chris@4 348 {
Chris@4 349 char answer[128];
Chris@4 350 int ret;
Chris@4 351 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
Chris@4 352 ret = scanf("%1s",answer);
Chris@4 353 if (ret != 1)
Chris@4 354 {
Chris@4 355 exit(EXIT_FAILURE);
Chris@4 356 }
Chris@4 357 rep = answer[0] ;
Chris@4 358 if ((rep>='a') && (rep<='z'))
Chris@4 359 rep -= 0x20;
Chris@4 360 }
Chris@4 361 while ((rep!='Y') && (rep!='N') && (rep!='A'));
Chris@4 362 if (rep=='N')
Chris@4 363 zipok = 0;
Chris@4 364 if (rep=='A')
Chris@4 365 opt_overwrite = 2;
Chris@4 366 }
Chris@4 367 }
Chris@4 368
Chris@4 369 if (zipok==1)
Chris@4 370 {
Chris@4 371 zipFile zf;
Chris@4 372 int errclose;
Chris@4 373 # ifdef USEWIN32IOAPI
Chris@4 374 zlib_filefunc64_def ffunc;
Chris@4 375 fill_win32_filefunc64A(&ffunc);
Chris@4 376 zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
Chris@4 377 # else
Chris@4 378 zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
Chris@4 379 # endif
Chris@4 380
Chris@4 381 if (zf == NULL)
Chris@4 382 {
Chris@4 383 printf("error opening %s\n",filename_try);
Chris@4 384 err= ZIP_ERRNO;
Chris@4 385 }
Chris@4 386 else
Chris@4 387 printf("creating %s\n",filename_try);
Chris@4 388
Chris@4 389 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
Chris@4 390 {
Chris@4 391 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
Chris@4 392 ((argv[i][1]=='o') || (argv[i][1]=='O') ||
Chris@4 393 (argv[i][1]=='a') || (argv[i][1]=='A') ||
Chris@4 394 (argv[i][1]=='p') || (argv[i][1]=='P') ||
Chris@4 395 ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
Chris@4 396 (strlen(argv[i]) == 2)))
Chris@4 397 {
Chris@4 398 FILE * fin;
Chris@4 399 int size_read;
Chris@4 400 const char* filenameinzip = argv[i];
Chris@4 401 const char *savefilenameinzip;
Chris@4 402 zip_fileinfo zi;
Chris@4 403 unsigned long crcFile=0;
Chris@4 404 int zip64 = 0;
Chris@4 405
Chris@4 406 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
Chris@4 407 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
Chris@4 408 zi.dosDate = 0;
Chris@4 409 zi.internal_fa = 0;
Chris@4 410 zi.external_fa = 0;
Chris@4 411 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
Chris@4 412
Chris@4 413 /*
Chris@4 414 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
Chris@4 415 NULL,0,NULL,0,NULL / * comment * /,
Chris@4 416 (opt_compress_level != 0) ? Z_DEFLATED : 0,
Chris@4 417 opt_compress_level);
Chris@4 418 */
Chris@4 419 if ((password != NULL) && (err==ZIP_OK))
Chris@4 420 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
Chris@4 421
Chris@4 422 zip64 = isLargeFile(filenameinzip);
Chris@4 423
Chris@4 424 /* The path name saved, should not include a leading slash. */
Chris@4 425 /*if it did, windows/xp and dynazip couldn't read the zip file. */
Chris@4 426 savefilenameinzip = filenameinzip;
Chris@4 427 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
Chris@4 428 {
Chris@4 429 savefilenameinzip++;
Chris@4 430 }
Chris@4 431
Chris@4 432 /*should the zip file contain any path at all?*/
Chris@4 433 if( opt_exclude_path )
Chris@4 434 {
Chris@4 435 const char *tmpptr;
Chris@4 436 const char *lastslash = 0;
Chris@4 437 for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
Chris@4 438 {
Chris@4 439 if( *tmpptr == '\\' || *tmpptr == '/')
Chris@4 440 {
Chris@4 441 lastslash = tmpptr;
Chris@4 442 }
Chris@4 443 }
Chris@4 444 if( lastslash != NULL )
Chris@4 445 {
Chris@4 446 savefilenameinzip = lastslash+1; // base filename follows last slash.
Chris@4 447 }
Chris@4 448 }
Chris@4 449
Chris@4 450 /**/
Chris@4 451 err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
Chris@4 452 NULL,0,NULL,0,NULL /* comment*/,
Chris@4 453 (opt_compress_level != 0) ? Z_DEFLATED : 0,
Chris@4 454 opt_compress_level,0,
Chris@4 455 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
Chris@4 456 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
Chris@4 457 password,crcFile, zip64);
Chris@4 458
Chris@4 459 if (err != ZIP_OK)
Chris@4 460 printf("error in opening %s in zipfile\n",filenameinzip);
Chris@4 461 else
Chris@4 462 {
Chris@4 463 fin = FOPEN_FUNC(filenameinzip,"rb");
Chris@4 464 if (fin==NULL)
Chris@4 465 {
Chris@4 466 err=ZIP_ERRNO;
Chris@4 467 printf("error in opening %s for reading\n",filenameinzip);
Chris@4 468 }
Chris@4 469 }
Chris@4 470
Chris@4 471 if (err == ZIP_OK)
Chris@4 472 do
Chris@4 473 {
Chris@4 474 err = ZIP_OK;
Chris@4 475 size_read = (int)fread(buf,1,size_buf,fin);
Chris@4 476 if (size_read < size_buf)
Chris@4 477 if (feof(fin)==0)
Chris@4 478 {
Chris@4 479 printf("error in reading %s\n",filenameinzip);
Chris@4 480 err = ZIP_ERRNO;
Chris@4 481 }
Chris@4 482
Chris@4 483 if (size_read>0)
Chris@4 484 {
Chris@4 485 err = zipWriteInFileInZip (zf,buf,size_read);
Chris@4 486 if (err<0)
Chris@4 487 {
Chris@4 488 printf("error in writing %s in the zipfile\n",
Chris@4 489 filenameinzip);
Chris@4 490 }
Chris@4 491
Chris@4 492 }
Chris@4 493 } while ((err == ZIP_OK) && (size_read>0));
Chris@4 494
Chris@4 495 if (fin)
Chris@4 496 fclose(fin);
Chris@4 497
Chris@4 498 if (err<0)
Chris@4 499 err=ZIP_ERRNO;
Chris@4 500 else
Chris@4 501 {
Chris@4 502 err = zipCloseFileInZip(zf);
Chris@4 503 if (err!=ZIP_OK)
Chris@4 504 printf("error in closing %s in the zipfile\n",
Chris@4 505 filenameinzip);
Chris@4 506 }
Chris@4 507 }
Chris@4 508 }
Chris@4 509 errclose = zipClose(zf,NULL);
Chris@4 510 if (errclose != ZIP_OK)
Chris@4 511 printf("error in closing %s\n",filename_try);
Chris@4 512 }
Chris@4 513 else
Chris@4 514 {
Chris@4 515 do_help();
Chris@4 516 }
Chris@4 517
Chris@4 518 free(buf);
Chris@4 519 return 0;
Chris@4 520 }