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