Initial revision
[official-gcc.git] / zlib / contrib / minizip / miniunz.c
blobf3b7832878fc070c176118f82dd84d7e4b96ccf6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6 #include <fcntl.h>
8 #ifdef unix
9 # include <unistd.h>
10 # include <utime.h>
11 #else
12 # include <direct.h>
13 # include <io.h>
14 #endif
16 #include "unzip.h"
18 #define CASESENSITIVITY (0)
19 #define WRITEBUFFERSIZE (8192)
22 mini unzip, demo of unzip package
24 usage :
25 Usage : miniunz [-exvlo] file.zip [file_to_extract]
27 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
28 if it exists
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;
41 #ifdef WIN32
42 HANDLE hFile;
43 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
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;
67 ut.actime=ut.modtime=mktime(&newdate);
68 utime(filename,&ut);
69 #endif
70 #endif
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 */
77 int mymkdir(dirname)
78 const char* dirname;
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;
91 int makedir (newdir)
92 char *newdir;
94 char *buffer ;
95 char *p;
96 int len = strlen(newdir);
98 if (len <= 0)
99 return 0;
101 buffer = (char*)malloc(len+1);
102 strcpy(buffer,newdir);
104 if (buffer[len-1] == '/') {
105 buffer[len-1] = '\0';
107 if (mymkdir(buffer) == 0)
109 free(buffer);
110 return 1;
113 p = buffer+1;
114 while (1)
116 char hold;
118 while(*p && *p != '\\' && *p != '/')
119 p++;
120 hold = *p;
121 *p = 0;
122 if ((mymkdir(buffer) == -1) && (errno == ENOENT))
124 printf("couldn't create directory %s\n",buffer);
125 free(buffer);
126 return 0;
128 if (hold == 0)
129 break;
130 *p++ = hold;
132 free(buffer);
133 return 1;
136 void do_banner()
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");
142 void do_help()
144 printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]\n\n") ;
148 int do_list(uf)
149 unzFile uf;
151 uLong i;
152 unz_global_info gi;
153 int err;
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++)
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)
169 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
170 break;
172 if (file_info.uncompressed_size>0)
173 ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
175 if (file_info.compression_method==0)
176 string_method="Stored";
177 else
178 if (file_info.compression_method==Z_DEFLATED)
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*/
188 else
189 string_method="Unkn. ";
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)
201 err = unzGoToNextFile(uf);
202 if (err!=UNZ_OK)
204 printf("error %d with zipfile in unzGoToNextFile\n",err);
205 break;
210 return 0;
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;
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;
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);
231 if (err!=UNZ_OK)
233 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
234 return err;
237 size_buf = WRITEBUFFERSIZE;
238 buf = (void*)malloc(size_buf);
239 if (buf==NULL)
241 printf("Error allocating memory\n");
242 return UNZ_INTERNALERROR;
245 p = filename_withoutpath = filename_inzip;
246 while ((*p) != '\0')
248 if (((*p)=='/') || ((*p)=='\\'))
249 filename_withoutpath = p+1;
250 p++;
253 if ((*filename_withoutpath)=='\0')
255 if ((*popt_extract_without_path)==0)
257 printf("creating directory: %s\n",filename_inzip);
258 mymkdir(filename_inzip);
261 else
263 const char* write_filename;
264 int skip=0;
266 if ((*popt_extract_without_path)==0)
267 write_filename = filename_inzip;
268 else
269 write_filename = filename_withoutpath;
271 err = unzOpenCurrentFile(uf);
272 if (err!=UNZ_OK)
274 printf("error %d with zipfile in unzOpenCurrentFile\n",err);
277 if (((*popt_overwrite)==0) && (err==UNZ_OK))
279 char rep;
280 FILE* ftestexist;
281 ftestexist = fopen(write_filename,"rb");
282 if (ftestexist!=NULL)
284 fclose(ftestexist);
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;
294 while ((rep!='Y') && (rep!='N') && (rep!='A'));
297 if (rep == 'N')
298 skip = 1;
300 if (rep == 'A')
301 *popt_overwrite=1;
304 if ((skip==0) && (err==UNZ_OK))
306 fout=fopen(write_filename,"wb");
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))
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");
319 if (fout==NULL)
321 printf("error opening %s\n",write_filename);
325 if (fout!=NULL)
327 printf(" extracting: %s\n",write_filename);
331 err = unzReadCurrentFile(uf,buf,size_buf);
332 if (err<0)
334 printf("error %d with zipfile in unzReadCurrentFile\n",err);
335 break;
337 if (err>0)
338 if (fwrite(buf,err,1,fout)!=1)
340 printf("error in writing extracted file\n");
341 err=UNZ_ERRNO;
342 break;
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);
352 if (err==UNZ_OK)
354 err = unzCloseCurrentFile (uf);
355 if (err!=UNZ_OK)
357 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
360 else
361 unzCloseCurrentFile(uf); /* don't lose the error */
364 free(buf);
365 return err;
369 int do_extract(uf,opt_extract_without_path,opt_overwrite)
370 unzFile uf;
371 int opt_extract_without_path;
372 int opt_overwrite;
374 uLong i;
375 unz_global_info gi;
376 int err;
377 FILE* fout=NULL;
379 err = unzGetGlobalInfo (uf,&gi);
380 if (err!=UNZ_OK)
381 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
383 for (i=0;i<gi.number_entry;i++)
385 if (do_extract_currentfile(uf,&opt_extract_without_path,
386 &opt_overwrite) != UNZ_OK)
387 break;
389 if ((i+1)<gi.number_entry)
391 err = unzGoToNextFile(uf);
392 if (err!=UNZ_OK)
394 printf("error %d with zipfile in unzGoToNextFile\n",err);
395 break;
400 return 0;
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;
409 int err = UNZ_OK;
410 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
412 printf("file %s not found in the zipfile\n",filename);
413 return 2;
416 if (do_extract_currentfile(uf,&opt_extract_without_path,
417 &opt_overwrite) == UNZ_OK)
418 return 0;
419 else
420 return 1;
424 int main(argc,argv)
425 int argc;
426 char *argv[];
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;
438 do_banner();
439 if (argc==1)
441 do_help();
442 exit(0);
444 else
446 for (i=1;i<argc;i++)
448 if ((*argv[i])=='-')
450 const char *p=argv[i]+1;
452 while ((*p)!='\0')
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;
467 else
469 if (zipfilename == NULL)
470 zipfilename = argv[i];
471 else if (filename_to_extract==NULL)
472 filename_to_extract = argv[i] ;
477 if (zipfilename!=NULL)
479 strcpy(filename_try,zipfilename);
480 uf = unzOpen(zipfilename);
481 if (uf==NULL)
483 strcat(filename_try,".zip");
484 uf = unzOpen(filename_try);
488 if (uf==NULL)
490 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
491 exit (1);
493 printf("%s opened\n",filename_try);
495 if (opt_do_list==1)
496 return do_list(uf);
497 else if (opt_do_extract==1)
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);
505 unzCloseCurrentFile(uf);
507 return 0; /* to avoid warning */