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