reshuffling of dlls
[reactos.git] / reactos / dll / win32 / zlib / contrib / minizip / miniunz.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6 #include <fcntl.h>
7
8 #ifdef unix
9 # include <unistd.h>
10 # include <utime.h>
11 #else
12 # include <direct.h>
13 # include <io.h>
14 #endif
15
16 #include "unzip.h"
17
18 #define CASESENSITIVITY (0)
19 #define WRITEBUFFERSIZE (8192)
20
21 /*
22 mini unzip, demo of unzip package
23
24 usage :
25 Usage : miniunz [-exvlo] file.zip [file_to_extract]
26
27 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
28 if it exists
29 */
30
31
32 /* change_file_date : change the date/time of a file
33 filename : the filename of the file where date/time must be modified
34 dosdate : the new date at the MSDos format (4 bytes)
35 tmu_date : the SAME new date at the tm_unz format */
36 void change_file_date(filename,dosdate,tmu_date)
37 const char *filename;
38 uLong dosdate;
39 tm_unz tmu_date;
40 {
41 #ifdef WIN32
42 HANDLE hFile;
43 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
44
45 hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
46 0,NULL,OPEN_EXISTING,0,NULL);
47 GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
48 DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
49 LocalFileTimeToFileTime(&ftLocal,&ftm);
50 SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
51 CloseHandle(hFile);
52 #else
53 #ifdef unix
54 struct utimbuf ut;
55 struct tm newdate;
56 newdate.tm_sec = tmu_date.tm_sec;
57 newdate.tm_min=tmu_date.tm_min;
58 newdate.tm_hour=tmu_date.tm_hour;
59 newdate.tm_mday=tmu_date.tm_mday;
60 newdate.tm_mon=tmu_date.tm_mon;
61 if (tmu_date.tm_year > 1900)
62 newdate.tm_year=tmu_date.tm_year - 1900;
63 else
64 newdate.tm_year=tmu_date.tm_year ;
65 newdate.tm_isdst=-1;
66
67 ut.actime=ut.modtime=mktime(&newdate);
68 utime(filename,&ut);
69 #endif
70 #endif
71 }
72
73
74 /* mymkdir and change_file_date are not 100 % portable
75 As I don't know well Unix, I wait feedback for the unix portion */
76
77 int mymkdir(dirname)
78 const char* dirname;
79 {
80 int ret=0;
81 #ifdef WIN32
82 ret = mkdir(dirname);
83 #else
84 #ifdef unix
85 ret = mkdir (dirname,0775);
86 #endif
87 #endif
88 return ret;
89 }
90
91 int makedir (newdir)
92 char *newdir;
93 {
94 char *buffer ;
95 char *p;
96 int len = strlen(newdir);
97
98 if (len <= 0)
99 return 0;
100
101 buffer = (char*)malloc(len+1);
102 strcpy(buffer,newdir);
103
104 if (buffer[len-1] == '/') {
105 buffer[len-1] = '\0';
106 }
107 if (mymkdir(buffer) == 0)
108 {
109 free(buffer);
110 return 1;
111 }
112
113 p = buffer+1;
114 while (1)
115 {
116 char hold;
117
118 while(*p && *p != '\\' && *p != '/')
119 p++;
120 hold = *p;
121 *p = 0;
122 if ((mymkdir(buffer) == -1) && (errno == ENOENT))
123 {
124 printf("couldn't create directory %s\n",buffer);
125 free(buffer);
126 return 0;
127 }
128 if (hold == 0)
129 break;
130 *p++ = hold;
131 }
132 free(buffer);
133 return 1;
134 }
135
136 void do_banner()
137 {
138 printf("MiniUnz 0.15, demo of zLib + Unz package written by Gilles Vollant\n");
139 printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n");
140 }
141
142 void do_help()
143 {
144 printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]\n\n") ;
145 }
146
147
148 int do_list(uf)
149 unzFile uf;
150 {
151 uLong i;
152 unz_global_info gi;
153 int err;
154
155 err = unzGetGlobalInfo (uf,&gi);
156 if (err!=UNZ_OK)
157 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
158 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
159 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
160 for (i=0;i<gi.number_entry;i++)
161 {
162 char filename_inzip[256];
163 unz_file_info file_info;
164 uLong ratio=0;
165 const char *string_method;
166 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
167 if (err!=UNZ_OK)
168 {
169 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
170 break;
171 }
172 if (file_info.uncompressed_size>0)
173 ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
174
175 if (file_info.compression_method==0)
176 string_method="Stored";
177 else
178 if (file_info.compression_method==Z_DEFLATED)
179 {
180 uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
181 if (iLevel==0)
182 string_method="Defl:N";
183 else if (iLevel==1)
184 string_method="Defl:X";
185 else if ((iLevel==2) || (iLevel==3))
186 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
187 }
188 else
189 string_method="Unkn. ";
190
191 printf("%7lu %6s %7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
192 file_info.uncompressed_size,string_method,file_info.compressed_size,
193 ratio,
194 (uLong)file_info.tmu_date.tm_mon + 1,
195 (uLong)file_info.tmu_date.tm_mday,
196 (uLong)file_info.tmu_date.tm_year % 100,
197 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
198 (uLong)file_info.crc,filename_inzip);
199 if ((i+1)<gi.number_entry)
200 {
201 err = unzGoToNextFile(uf);
202 if (err!=UNZ_OK)
203 {
204 printf("error %d with zipfile in unzGoToNextFile\n",err);
205 break;
206 }
207 }
208 }
209
210 return 0;
211 }
212
213
214 int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite)
215 unzFile uf;
216 const int* popt_extract_without_path;
217 int* popt_overwrite;
218 {
219 char filename_inzip[256];
220 char* filename_withoutpath;
221 char* p;
222 int err=UNZ_OK;
223 FILE *fout=NULL;
224 void* buf;
225 uInt size_buf;
226
227 unz_file_info file_info;
228 uLong ratio=0;
229 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
230
231 if (err!=UNZ_OK)
232 {
233 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
234 return err;
235 }
236
237 size_buf = WRITEBUFFERSIZE;
238 buf = (void*)malloc(size_buf);
239 if (buf==NULL)
240 {
241 printf("Error allocating memory\n");
242 return UNZ_INTERNALERROR;
243 }
244
245 p = filename_withoutpath = filename_inzip;
246 while ((*p) != '\0')
247 {
248 if (((*p)=='/') || ((*p)=='\\'))
249 filename_withoutpath = p+1;
250 p++;
251 }
252
253 if ((*filename_withoutpath)=='\0')
254 {
255 if ((*popt_extract_without_path)==0)
256 {
257 printf("creating directory: %s\n",filename_inzip);
258 mymkdir(filename_inzip);
259 }
260 }
261 else
262 {
263 const char* write_filename;
264 int skip=0;
265
266 if ((*popt_extract_without_path)==0)
267 write_filename = filename_inzip;
268 else
269 write_filename = filename_withoutpath;
270
271 err = unzOpenCurrentFile(uf);
272 if (err!=UNZ_OK)
273 {
274 printf("error %d with zipfile in unzOpenCurrentFile\n",err);
275 }
276
277 if (((*popt_overwrite)==0) && (err==UNZ_OK))
278 {
279 char rep;
280 FILE* ftestexist;
281 ftestexist = fopen(write_filename,"rb");
282 if (ftestexist!=NULL)
283 {
284 fclose(ftestexist);
285 do
286 {
287 char answer[128];
288 printf("The file %s exist. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
289 scanf("%1s",answer);
290 rep = answer[0] ;
291 if ((rep>='a') && (rep<='z'))
292 rep -= 0x20;
293 }
294 while ((rep!='Y') && (rep!='N') && (rep!='A'));
295 }
296
297 if (rep == 'N')
298 skip = 1;
299
300 if (rep == 'A')
301 *popt_overwrite=1;
302 }
303
304 if ((skip==0) && (err==UNZ_OK))
305 {
306 fout=fopen(write_filename,"wb");
307
308 /* some zipfile don't contain directory alone before file */
309 if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
310 (filename_withoutpath!=(char*)filename_inzip))
311 {
312 char c=*(filename_withoutpath-1);
313 *(filename_withoutpath-1)='\0';
314 makedir(write_filename);
315 *(filename_withoutpath-1)=c;
316 fout=fopen(write_filename,"wb");
317 }
318
319 if (fout==NULL)
320 {
321 printf("error opening %s\n",write_filename);
322 }
323 }
324
325 if (fout!=NULL)
326 {
327 printf(" extracting: %s\n",write_filename);
328
329 do
330 {
331 err = unzReadCurrentFile(uf,buf,size_buf);
332 if (err<0)
333 {
334 printf("error %d with zipfile in unzReadCurrentFile\n",err);
335 break;
336 }
337 if (err>0)
338 if (fwrite(buf,err,1,fout)!=1)
339 {
340 printf("error in writing extracted file\n");
341 err=UNZ_ERRNO;
342 break;
343 }
344 }
345 while (err>0);
346 fclose(fout);
347 if (err==0)
348 change_file_date(write_filename,file_info.dosDate,
349 file_info.tmu_date);
350 }
351
352 if (err==UNZ_OK)
353 {
354 err = unzCloseCurrentFile (uf);
355 if (err!=UNZ_OK)
356 {
357 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
358 }
359 }
360 else
361 unzCloseCurrentFile(uf); /* don't lose the error */
362 }
363
364 free(buf);
365 return err;
366 }
367
368
369 int do_extract(uf,opt_extract_without_path,opt_overwrite)
370 unzFile uf;
371 int opt_extract_without_path;
372 int opt_overwrite;
373 {
374 uLong i;
375 unz_global_info gi;
376 int err;
377 FILE* fout=NULL;
378
379 err = unzGetGlobalInfo (uf,&gi);
380 if (err!=UNZ_OK)
381 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
382
383 for (i=0;i<gi.number_entry;i++)
384 {
385 if (do_extract_currentfile(uf,&opt_extract_without_path,
386 &opt_overwrite) != UNZ_OK)
387 break;
388
389 if ((i+1)<gi.number_entry)
390 {
391 err = unzGoToNextFile(uf);
392 if (err!=UNZ_OK)
393 {
394 printf("error %d with zipfile in unzGoToNextFile\n",err);
395 break;
396 }
397 }
398 }
399
400 return 0;
401 }
402
403 int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite)
404 unzFile uf;
405 const char* filename;
406 int opt_extract_without_path;
407 int opt_overwrite;
408 {
409 int err = UNZ_OK;
410 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
411 {
412 printf("file %s not found in the zipfile\n",filename);
413 return 2;
414 }
415
416 if (do_extract_currentfile(uf,&opt_extract_without_path,
417 &opt_overwrite) == UNZ_OK)
418 return 0;
419 else
420 return 1;
421 }
422
423
424 int main(argc,argv)
425 int argc;
426 char *argv[];
427 {
428 const char *zipfilename=NULL;
429 const char *filename_to_extract=NULL;
430 int i;
431 int opt_do_list=0;
432 int opt_do_extract=1;
433 int opt_do_extract_withoutpath=0;
434 int opt_overwrite=0;
435 char filename_try[512];
436 unzFile uf=NULL;
437
438 do_banner();
439 if (argc==1)
440 {
441 do_help();
442 exit(0);
443 }
444 else
445 {
446 for (i=1;i<argc;i++)
447 {
448 if ((*argv[i])=='-')
449 {
450 const char *p=argv[i]+1;
451
452 while ((*p)!='\0')
453 {
454 char c=*(p++);;
455 if ((c=='l') || (c=='L'))
456 opt_do_list = 1;
457 if ((c=='v') || (c=='V'))
458 opt_do_list = 1;
459 if ((c=='x') || (c=='X'))
460 opt_do_extract = 1;
461 if ((c=='e') || (c=='E'))
462 opt_do_extract = opt_do_extract_withoutpath = 1;
463 if ((c=='o') || (c=='O'))
464 opt_overwrite=1;
465 }
466 }
467 else
468 {
469 if (zipfilename == NULL)
470 zipfilename = argv[i];
471 else if (filename_to_extract==NULL)
472 filename_to_extract = argv[i] ;
473 }
474 }
475 }
476
477 if (zipfilename!=NULL)
478 {
479 strcpy(filename_try,zipfilename);
480 uf = unzOpen(zipfilename);
481 if (uf==NULL)
482 {
483 strcat(filename_try,".zip");
484 uf = unzOpen(filename_try);
485 }
486 }
487
488 if (uf==NULL)
489 {
490 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
491 exit (1);
492 }
493 printf("%s opened\n",filename_try);
494
495 if (opt_do_list==1)
496 return do_list(uf);
497 else if (opt_do_extract==1)
498 {
499 if (filename_to_extract == NULL)
500 return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite);
501 else
502 return do_extract_onefile(uf,filename_to_extract,
503 opt_do_extract_withoutpath,opt_overwrite);
504 }
505 unzCloseCurrentFile(uf);
506
507 return 0; /* to avoid warning */
508 }