~ubuntu-branches/ubuntu/oneiric/psi/oneiric

« back to all changes in this revision

Viewing changes to src/tools/zip/minizip/miniunz.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2006-01-20 00:20:36 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060120002036-7nw6yo6totip0ee5
Tags: 0.10-2
* Added upstream changelog (Closes: Bug#327748)
* Mention --no-gpg and --no-gpg-agent in manpage (Closes: Bug#204416)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}