Mercurial > hg > sv-dependency-builds
comparison src/zlib-1.2.7/contrib/minizip/miniunz.c @ 4:e13257ea84a4
Add bzip2, zlib, liblo, portaudio sources
author | Chris Cannam |
---|---|
date | Wed, 20 Mar 2013 13:59:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:6c505a35919a | 4:e13257ea84a4 |
---|---|
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 } |