xref: /aosp_15_r20/external/zlib/contrib/minizip/minizip.c (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1*86ee64e7SAndroid Build Coastguard Worker /*
2*86ee64e7SAndroid Build Coastguard Worker    minizip.c
3*86ee64e7SAndroid Build Coastguard Worker    Version 1.1, February 14h, 2010
4*86ee64e7SAndroid Build Coastguard Worker    sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
5*86ee64e7SAndroid Build Coastguard Worker 
6*86ee64e7SAndroid Build Coastguard Worker          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
7*86ee64e7SAndroid Build Coastguard Worker 
8*86ee64e7SAndroid Build Coastguard Worker          Modifications of Unzip for Zip64
9*86ee64e7SAndroid Build Coastguard Worker          Copyright (C) 2007-2008 Even Rouault
10*86ee64e7SAndroid Build Coastguard Worker 
11*86ee64e7SAndroid Build Coastguard Worker          Modifications for Zip64 support on both zip and unzip
12*86ee64e7SAndroid Build Coastguard Worker          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
13*86ee64e7SAndroid Build Coastguard Worker */
14*86ee64e7SAndroid Build Coastguard Worker 
15*86ee64e7SAndroid Build Coastguard Worker #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) && (!defined(__ANDROID_API__))
16*86ee64e7SAndroid Build Coastguard Worker         #ifndef __USE_FILE_OFFSET64
17*86ee64e7SAndroid Build Coastguard Worker                 #define __USE_FILE_OFFSET64
18*86ee64e7SAndroid Build Coastguard Worker         #endif
19*86ee64e7SAndroid Build Coastguard Worker         #ifndef __USE_LARGEFILE64
20*86ee64e7SAndroid Build Coastguard Worker                 #define __USE_LARGEFILE64
21*86ee64e7SAndroid Build Coastguard Worker         #endif
22*86ee64e7SAndroid Build Coastguard Worker         #ifndef _LARGEFILE64_SOURCE
23*86ee64e7SAndroid Build Coastguard Worker                 #define _LARGEFILE64_SOURCE
24*86ee64e7SAndroid Build Coastguard Worker         #endif
25*86ee64e7SAndroid Build Coastguard Worker         #ifndef _FILE_OFFSET_BIT
26*86ee64e7SAndroid Build Coastguard Worker                 #define _FILE_OFFSET_BIT 64
27*86ee64e7SAndroid Build Coastguard Worker         #endif
28*86ee64e7SAndroid Build Coastguard Worker #endif
29*86ee64e7SAndroid Build Coastguard Worker 
30*86ee64e7SAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) || defined(__Fuchsia__) || defined(__ANDROID_API__)
31*86ee64e7SAndroid Build Coastguard Worker // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
32*86ee64e7SAndroid Build Coastguard Worker #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
33*86ee64e7SAndroid Build Coastguard Worker #define FTELLO_FUNC(stream) ftello(stream)
34*86ee64e7SAndroid Build Coastguard Worker #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
35*86ee64e7SAndroid Build Coastguard Worker #else
36*86ee64e7SAndroid Build Coastguard Worker #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
37*86ee64e7SAndroid Build Coastguard Worker #define FTELLO_FUNC(stream) ftello64(stream)
38*86ee64e7SAndroid Build Coastguard Worker #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
39*86ee64e7SAndroid Build Coastguard Worker #endif
40*86ee64e7SAndroid Build Coastguard Worker 
41*86ee64e7SAndroid Build Coastguard Worker 
42*86ee64e7SAndroid Build Coastguard Worker 
43*86ee64e7SAndroid Build Coastguard Worker #include <stdio.h>
44*86ee64e7SAndroid Build Coastguard Worker #include <stdlib.h>
45*86ee64e7SAndroid Build Coastguard Worker #include <string.h>
46*86ee64e7SAndroid Build Coastguard Worker #include <time.h>
47*86ee64e7SAndroid Build Coastguard Worker #include <errno.h>
48*86ee64e7SAndroid Build Coastguard Worker #include <fcntl.h>
49*86ee64e7SAndroid Build Coastguard Worker 
50*86ee64e7SAndroid Build Coastguard Worker #ifdef _WIN32
51*86ee64e7SAndroid Build Coastguard Worker # include <direct.h>
52*86ee64e7SAndroid Build Coastguard Worker # include <io.h>
53*86ee64e7SAndroid Build Coastguard Worker #else
54*86ee64e7SAndroid Build Coastguard Worker # include <unistd.h>
55*86ee64e7SAndroid Build Coastguard Worker # include <utime.h>
56*86ee64e7SAndroid Build Coastguard Worker # include <sys/types.h>
57*86ee64e7SAndroid Build Coastguard Worker # include <sys/stat.h>
58*86ee64e7SAndroid Build Coastguard Worker #endif
59*86ee64e7SAndroid Build Coastguard Worker 
60*86ee64e7SAndroid Build Coastguard Worker #include "zip.h"
61*86ee64e7SAndroid Build Coastguard Worker 
62*86ee64e7SAndroid Build Coastguard Worker #ifdef _WIN32
63*86ee64e7SAndroid Build Coastguard Worker         #define USEWIN32IOAPI
64*86ee64e7SAndroid Build Coastguard Worker         #include "iowin32.h"
65*86ee64e7SAndroid Build Coastguard Worker #endif
66*86ee64e7SAndroid Build Coastguard Worker 
67*86ee64e7SAndroid Build Coastguard Worker 
68*86ee64e7SAndroid Build Coastguard Worker 
69*86ee64e7SAndroid Build Coastguard Worker #define WRITEBUFFERSIZE (16384)
70*86ee64e7SAndroid Build Coastguard Worker #define MAXFILENAME (256)
71*86ee64e7SAndroid Build Coastguard Worker 
72*86ee64e7SAndroid Build Coastguard Worker #ifdef _WIN32
73*86ee64e7SAndroid Build Coastguard Worker /* f: name of file to get info on, tmzip: return value: access,
74*86ee64e7SAndroid Build Coastguard Worker    modification and creation times, dt: dostime */
filetime(const char * f,tm_zip * tmzip,uLong * dt)75*86ee64e7SAndroid Build Coastguard Worker static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
76*86ee64e7SAndroid Build Coastguard Worker   int ret = 0;
77*86ee64e7SAndroid Build Coastguard Worker   {
78*86ee64e7SAndroid Build Coastguard Worker       FILETIME ftLocal;
79*86ee64e7SAndroid Build Coastguard Worker       HANDLE hFind;
80*86ee64e7SAndroid Build Coastguard Worker       WIN32_FIND_DATAA ff32;
81*86ee64e7SAndroid Build Coastguard Worker 
82*86ee64e7SAndroid Build Coastguard Worker       hFind = FindFirstFileA(f,&ff32);
83*86ee64e7SAndroid Build Coastguard Worker       if (hFind != INVALID_HANDLE_VALUE)
84*86ee64e7SAndroid Build Coastguard Worker       {
85*86ee64e7SAndroid Build Coastguard Worker         FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
86*86ee64e7SAndroid Build Coastguard Worker         FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
87*86ee64e7SAndroid Build Coastguard Worker         FindClose(hFind);
88*86ee64e7SAndroid Build Coastguard Worker         ret = 1;
89*86ee64e7SAndroid Build Coastguard Worker       }
90*86ee64e7SAndroid Build Coastguard Worker   }
91*86ee64e7SAndroid Build Coastguard Worker   return ret;
92*86ee64e7SAndroid Build Coastguard Worker }
93*86ee64e7SAndroid Build Coastguard Worker #else
94*86ee64e7SAndroid Build Coastguard Worker #if defined(unix) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__ANDROID_API__)
95*86ee64e7SAndroid Build Coastguard Worker /* f: name of file to get info on, tmzip: return value: access,
96*86ee64e7SAndroid Build Coastguard Worker    modification and creation times, dt: dostime */
filetime(const char * f,tm_zip * tmzip,uLong * dt)97*86ee64e7SAndroid Build Coastguard Worker static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
98*86ee64e7SAndroid Build Coastguard Worker   (void)dt;
99*86ee64e7SAndroid Build Coastguard Worker   int ret=0;
100*86ee64e7SAndroid Build Coastguard Worker   struct stat s;        /* results of stat() */
101*86ee64e7SAndroid Build Coastguard Worker   struct tm* filedate;
102*86ee64e7SAndroid Build Coastguard Worker   time_t tm_t=0;
103*86ee64e7SAndroid Build Coastguard Worker 
104*86ee64e7SAndroid Build Coastguard Worker   if (strcmp(f,"-")!=0)
105*86ee64e7SAndroid Build Coastguard Worker   {
106*86ee64e7SAndroid Build Coastguard Worker     char name[MAXFILENAME+1];
107*86ee64e7SAndroid Build Coastguard Worker     size_t len = strlen(f);
108*86ee64e7SAndroid Build Coastguard Worker     if (len > MAXFILENAME)
109*86ee64e7SAndroid Build Coastguard Worker       len = MAXFILENAME;
110*86ee64e7SAndroid Build Coastguard Worker 
111*86ee64e7SAndroid Build Coastguard Worker     strncpy(name, f,MAXFILENAME-1);
112*86ee64e7SAndroid Build Coastguard Worker     /* strncpy doesn't append the trailing NULL, of the string is too long. */
113*86ee64e7SAndroid Build Coastguard Worker     name[ MAXFILENAME ] = '\0';
114*86ee64e7SAndroid Build Coastguard Worker 
115*86ee64e7SAndroid Build Coastguard Worker     if (name[len - 1] == '/')
116*86ee64e7SAndroid Build Coastguard Worker       name[len - 1] = '\0';
117*86ee64e7SAndroid Build Coastguard Worker     /* not all systems allow stat'ing a file with / appended */
118*86ee64e7SAndroid Build Coastguard Worker     if (stat(name,&s)==0)
119*86ee64e7SAndroid Build Coastguard Worker     {
120*86ee64e7SAndroid Build Coastguard Worker       tm_t = s.st_mtime;
121*86ee64e7SAndroid Build Coastguard Worker       ret = 1;
122*86ee64e7SAndroid Build Coastguard Worker     }
123*86ee64e7SAndroid Build Coastguard Worker   }
124*86ee64e7SAndroid Build Coastguard Worker   filedate = localtime(&tm_t);
125*86ee64e7SAndroid Build Coastguard Worker 
126*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_sec  = filedate->tm_sec;
127*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_min  = filedate->tm_min;
128*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_hour = filedate->tm_hour;
129*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_mday = filedate->tm_mday;
130*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_mon  = filedate->tm_mon ;
131*86ee64e7SAndroid Build Coastguard Worker   tmzip->tm_year = filedate->tm_year;
132*86ee64e7SAndroid Build Coastguard Worker 
133*86ee64e7SAndroid Build Coastguard Worker   return ret;
134*86ee64e7SAndroid Build Coastguard Worker }
135*86ee64e7SAndroid Build Coastguard Worker #else
136*86ee64e7SAndroid Build Coastguard Worker /* f: name of file to get info on, tmzip: return value: access,
137*86ee64e7SAndroid Build Coastguard Worker    modification and creation times, dt: dostime */
filetime(const char * f,tm_zip * tmzip,uLong * dt)138*86ee64e7SAndroid Build Coastguard Worker static int filetime(const char *f, tm_zip *tmzip, uLong *dt) {
139*86ee64e7SAndroid Build Coastguard Worker     (void)f;
140*86ee64e7SAndroid Build Coastguard Worker     (void)tmzip;
141*86ee64e7SAndroid Build Coastguard Worker     (void)dt;
142*86ee64e7SAndroid Build Coastguard Worker     return 0;
143*86ee64e7SAndroid Build Coastguard Worker }
144*86ee64e7SAndroid Build Coastguard Worker #endif
145*86ee64e7SAndroid Build Coastguard Worker #endif
146*86ee64e7SAndroid Build Coastguard Worker 
147*86ee64e7SAndroid Build Coastguard Worker 
148*86ee64e7SAndroid Build Coastguard Worker 
149*86ee64e7SAndroid Build Coastguard Worker 
check_exist_file(const char * filename)150*86ee64e7SAndroid Build Coastguard Worker static int check_exist_file(const char* filename) {
151*86ee64e7SAndroid Build Coastguard Worker     FILE* ftestexist;
152*86ee64e7SAndroid Build Coastguard Worker     int ret = 1;
153*86ee64e7SAndroid Build Coastguard Worker     ftestexist = FOPEN_FUNC(filename,"rb");
154*86ee64e7SAndroid Build Coastguard Worker     if (ftestexist==NULL)
155*86ee64e7SAndroid Build Coastguard Worker         ret = 0;
156*86ee64e7SAndroid Build Coastguard Worker     else
157*86ee64e7SAndroid Build Coastguard Worker         fclose(ftestexist);
158*86ee64e7SAndroid Build Coastguard Worker     return ret;
159*86ee64e7SAndroid Build Coastguard Worker }
160*86ee64e7SAndroid Build Coastguard Worker 
do_banner(void)161*86ee64e7SAndroid Build Coastguard Worker static void do_banner(void) {
162*86ee64e7SAndroid Build Coastguard Worker     printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
163*86ee64e7SAndroid Build Coastguard Worker     printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
164*86ee64e7SAndroid Build Coastguard Worker }
165*86ee64e7SAndroid Build Coastguard Worker 
do_help(void)166*86ee64e7SAndroid Build Coastguard Worker static void do_help(void) {
167*86ee64e7SAndroid Build Coastguard Worker     printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
168*86ee64e7SAndroid Build Coastguard Worker            "  -o  Overwrite existing file.zip\n" \
169*86ee64e7SAndroid Build Coastguard Worker            "  -a  Append to existing file.zip\n" \
170*86ee64e7SAndroid Build Coastguard Worker            "  -0  Store only\n" \
171*86ee64e7SAndroid Build Coastguard Worker            "  -1  Compress faster\n" \
172*86ee64e7SAndroid Build Coastguard Worker            "  -9  Compress better\n\n" \
173*86ee64e7SAndroid Build Coastguard Worker            "  -j  exclude path. store only the file name.\n\n");
174*86ee64e7SAndroid Build Coastguard Worker }
175*86ee64e7SAndroid Build Coastguard Worker 
176*86ee64e7SAndroid Build Coastguard Worker /* calculate the CRC32 of a file,
177*86ee64e7SAndroid Build Coastguard Worker    because to encrypt a file, we need known the CRC32 of the file before */
getFileCrc(const char * filenameinzip,void * buf,unsigned long size_buf,unsigned long * result_crc)178*86ee64e7SAndroid Build Coastguard Worker static int getFileCrc(const char* filenameinzip, void* buf, unsigned long size_buf, unsigned long* result_crc) {
179*86ee64e7SAndroid Build Coastguard Worker    unsigned long calculate_crc=0;
180*86ee64e7SAndroid Build Coastguard Worker    int err=ZIP_OK;
181*86ee64e7SAndroid Build Coastguard Worker    FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
182*86ee64e7SAndroid Build Coastguard Worker 
183*86ee64e7SAndroid Build Coastguard Worker    unsigned long size_read = 0;
184*86ee64e7SAndroid Build Coastguard Worker    /* unsigned long total_read = 0; */
185*86ee64e7SAndroid Build Coastguard Worker    if (fin==NULL)
186*86ee64e7SAndroid Build Coastguard Worker    {
187*86ee64e7SAndroid Build Coastguard Worker        err = ZIP_ERRNO;
188*86ee64e7SAndroid Build Coastguard Worker    }
189*86ee64e7SAndroid Build Coastguard Worker 
190*86ee64e7SAndroid Build Coastguard Worker     if (err == ZIP_OK)
191*86ee64e7SAndroid Build Coastguard Worker         do
192*86ee64e7SAndroid Build Coastguard Worker         {
193*86ee64e7SAndroid Build Coastguard Worker             err = ZIP_OK;
194*86ee64e7SAndroid Build Coastguard Worker             size_read = fread(buf,1,size_buf,fin);
195*86ee64e7SAndroid Build Coastguard Worker             if (size_read < size_buf)
196*86ee64e7SAndroid Build Coastguard Worker                 if (feof(fin)==0)
197*86ee64e7SAndroid Build Coastguard Worker             {
198*86ee64e7SAndroid Build Coastguard Worker                 printf("error in reading %s\n",filenameinzip);
199*86ee64e7SAndroid Build Coastguard Worker                 err = ZIP_ERRNO;
200*86ee64e7SAndroid Build Coastguard Worker             }
201*86ee64e7SAndroid Build Coastguard Worker 
202*86ee64e7SAndroid Build Coastguard Worker             if (size_read>0)
203*86ee64e7SAndroid Build Coastguard Worker                 calculate_crc = crc32_z(calculate_crc,buf,size_read);
204*86ee64e7SAndroid Build Coastguard Worker             /* total_read += size_read; */
205*86ee64e7SAndroid Build Coastguard Worker 
206*86ee64e7SAndroid Build Coastguard Worker         } while ((err == ZIP_OK) && (size_read>0));
207*86ee64e7SAndroid Build Coastguard Worker 
208*86ee64e7SAndroid Build Coastguard Worker     if (fin)
209*86ee64e7SAndroid Build Coastguard Worker         fclose(fin);
210*86ee64e7SAndroid Build Coastguard Worker 
211*86ee64e7SAndroid Build Coastguard Worker     *result_crc=calculate_crc;
212*86ee64e7SAndroid Build Coastguard Worker     printf("file %s crc %lx\n", filenameinzip, calculate_crc);
213*86ee64e7SAndroid Build Coastguard Worker     return err;
214*86ee64e7SAndroid Build Coastguard Worker }
215*86ee64e7SAndroid Build Coastguard Worker 
isLargeFile(const char * filename)216*86ee64e7SAndroid Build Coastguard Worker static int isLargeFile(const char* filename) {
217*86ee64e7SAndroid Build Coastguard Worker   int largeFile = 0;
218*86ee64e7SAndroid Build Coastguard Worker   ZPOS64_T pos = 0;
219*86ee64e7SAndroid Build Coastguard Worker   FILE* pFile = FOPEN_FUNC(filename, "rb");
220*86ee64e7SAndroid Build Coastguard Worker 
221*86ee64e7SAndroid Build Coastguard Worker   if(pFile != NULL)
222*86ee64e7SAndroid Build Coastguard Worker   {
223*86ee64e7SAndroid Build Coastguard Worker     FSEEKO_FUNC(pFile, 0, SEEK_END);
224*86ee64e7SAndroid Build Coastguard Worker     pos = (ZPOS64_T)FTELLO_FUNC(pFile);
225*86ee64e7SAndroid Build Coastguard Worker 
226*86ee64e7SAndroid Build Coastguard Worker                 printf("File : %s is %llu bytes\n", filename, pos);
227*86ee64e7SAndroid Build Coastguard Worker 
228*86ee64e7SAndroid Build Coastguard Worker     if(pos >= 0xffffffff)
229*86ee64e7SAndroid Build Coastguard Worker      largeFile = 1;
230*86ee64e7SAndroid Build Coastguard Worker 
231*86ee64e7SAndroid Build Coastguard Worker                 fclose(pFile);
232*86ee64e7SAndroid Build Coastguard Worker   }
233*86ee64e7SAndroid Build Coastguard Worker 
234*86ee64e7SAndroid Build Coastguard Worker  return largeFile;
235*86ee64e7SAndroid Build Coastguard Worker }
236*86ee64e7SAndroid Build Coastguard Worker 
main(int argc,char * argv[])237*86ee64e7SAndroid Build Coastguard Worker int main(int argc, char *argv[]) {
238*86ee64e7SAndroid Build Coastguard Worker     int i;
239*86ee64e7SAndroid Build Coastguard Worker     int opt_overwrite=0;
240*86ee64e7SAndroid Build Coastguard Worker     int opt_compress_level=Z_DEFAULT_COMPRESSION;
241*86ee64e7SAndroid Build Coastguard Worker     int opt_exclude_path=0;
242*86ee64e7SAndroid Build Coastguard Worker     int zipfilenamearg = 0;
243*86ee64e7SAndroid Build Coastguard Worker     char filename_try[MAXFILENAME+16];
244*86ee64e7SAndroid Build Coastguard Worker     int zipok;
245*86ee64e7SAndroid Build Coastguard Worker     int err=0;
246*86ee64e7SAndroid Build Coastguard Worker     size_t size_buf=0;
247*86ee64e7SAndroid Build Coastguard Worker     void* buf=NULL;
248*86ee64e7SAndroid Build Coastguard Worker     const char* password=NULL;
249*86ee64e7SAndroid Build Coastguard Worker 
250*86ee64e7SAndroid Build Coastguard Worker 
251*86ee64e7SAndroid Build Coastguard Worker     do_banner();
252*86ee64e7SAndroid Build Coastguard Worker     if (argc==1)
253*86ee64e7SAndroid Build Coastguard Worker     {
254*86ee64e7SAndroid Build Coastguard Worker         do_help();
255*86ee64e7SAndroid Build Coastguard Worker         return 0;
256*86ee64e7SAndroid Build Coastguard Worker     }
257*86ee64e7SAndroid Build Coastguard Worker     else
258*86ee64e7SAndroid Build Coastguard Worker     {
259*86ee64e7SAndroid Build Coastguard Worker         for (i=1;i<argc;i++)
260*86ee64e7SAndroid Build Coastguard Worker         {
261*86ee64e7SAndroid Build Coastguard Worker             if ((*argv[i])=='-')
262*86ee64e7SAndroid Build Coastguard Worker             {
263*86ee64e7SAndroid Build Coastguard Worker                 const char *p=argv[i]+1;
264*86ee64e7SAndroid Build Coastguard Worker 
265*86ee64e7SAndroid Build Coastguard Worker                 while ((*p)!='\0')
266*86ee64e7SAndroid Build Coastguard Worker                 {
267*86ee64e7SAndroid Build Coastguard Worker                     char c=*(p++);
268*86ee64e7SAndroid Build Coastguard Worker                     if ((c=='o') || (c=='O'))
269*86ee64e7SAndroid Build Coastguard Worker                         opt_overwrite = 1;
270*86ee64e7SAndroid Build Coastguard Worker                     if ((c=='a') || (c=='A'))
271*86ee64e7SAndroid Build Coastguard Worker                         opt_overwrite = 2;
272*86ee64e7SAndroid Build Coastguard Worker                     if ((c>='0') && (c<='9'))
273*86ee64e7SAndroid Build Coastguard Worker                         opt_compress_level = c-'0';
274*86ee64e7SAndroid Build Coastguard Worker                     if ((c=='j') || (c=='J'))
275*86ee64e7SAndroid Build Coastguard Worker                         opt_exclude_path = 1;
276*86ee64e7SAndroid Build Coastguard Worker 
277*86ee64e7SAndroid Build Coastguard Worker                     if (((c=='p') || (c=='P')) && (i+1<argc))
278*86ee64e7SAndroid Build Coastguard Worker                     {
279*86ee64e7SAndroid Build Coastguard Worker                         password=argv[i+1];
280*86ee64e7SAndroid Build Coastguard Worker                         i++;
281*86ee64e7SAndroid Build Coastguard Worker                     }
282*86ee64e7SAndroid Build Coastguard Worker                 }
283*86ee64e7SAndroid Build Coastguard Worker             }
284*86ee64e7SAndroid Build Coastguard Worker             else
285*86ee64e7SAndroid Build Coastguard Worker             {
286*86ee64e7SAndroid Build Coastguard Worker                 if (zipfilenamearg == 0)
287*86ee64e7SAndroid Build Coastguard Worker                 {
288*86ee64e7SAndroid Build Coastguard Worker                     zipfilenamearg = i ;
289*86ee64e7SAndroid Build Coastguard Worker                 }
290*86ee64e7SAndroid Build Coastguard Worker             }
291*86ee64e7SAndroid Build Coastguard Worker         }
292*86ee64e7SAndroid Build Coastguard Worker     }
293*86ee64e7SAndroid Build Coastguard Worker 
294*86ee64e7SAndroid Build Coastguard Worker     size_buf = WRITEBUFFERSIZE;
295*86ee64e7SAndroid Build Coastguard Worker     buf = (void*)malloc(size_buf);
296*86ee64e7SAndroid Build Coastguard Worker     if (buf==NULL)
297*86ee64e7SAndroid Build Coastguard Worker     {
298*86ee64e7SAndroid Build Coastguard Worker         printf("Error allocating memory\n");
299*86ee64e7SAndroid Build Coastguard Worker         return ZIP_INTERNALERROR;
300*86ee64e7SAndroid Build Coastguard Worker     }
301*86ee64e7SAndroid Build Coastguard Worker 
302*86ee64e7SAndroid Build Coastguard Worker     if (zipfilenamearg==0)
303*86ee64e7SAndroid Build Coastguard Worker     {
304*86ee64e7SAndroid Build Coastguard Worker         zipok=0;
305*86ee64e7SAndroid Build Coastguard Worker     }
306*86ee64e7SAndroid Build Coastguard Worker     else
307*86ee64e7SAndroid Build Coastguard Worker     {
308*86ee64e7SAndroid Build Coastguard Worker         int i,len;
309*86ee64e7SAndroid Build Coastguard Worker         int dot_found=0;
310*86ee64e7SAndroid Build Coastguard Worker 
311*86ee64e7SAndroid Build Coastguard Worker         zipok = 1 ;
312*86ee64e7SAndroid Build Coastguard Worker         strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
313*86ee64e7SAndroid Build Coastguard Worker         /* strncpy doesn't append the trailing NULL, of the string is too long. */
314*86ee64e7SAndroid Build Coastguard Worker         filename_try[ MAXFILENAME ] = '\0';
315*86ee64e7SAndroid Build Coastguard Worker 
316*86ee64e7SAndroid Build Coastguard Worker         len=(int)strlen(filename_try);
317*86ee64e7SAndroid Build Coastguard Worker         for (i=0;i<len;i++)
318*86ee64e7SAndroid Build Coastguard Worker             if (filename_try[i]=='.')
319*86ee64e7SAndroid Build Coastguard Worker                 dot_found=1;
320*86ee64e7SAndroid Build Coastguard Worker 
321*86ee64e7SAndroid Build Coastguard Worker         if (dot_found==0)
322*86ee64e7SAndroid Build Coastguard Worker             strcat(filename_try,".zip");
323*86ee64e7SAndroid Build Coastguard Worker 
324*86ee64e7SAndroid Build Coastguard Worker         if (opt_overwrite==2)
325*86ee64e7SAndroid Build Coastguard Worker         {
326*86ee64e7SAndroid Build Coastguard Worker             /* if the file don't exist, we not append file */
327*86ee64e7SAndroid Build Coastguard Worker             if (check_exist_file(filename_try)==0)
328*86ee64e7SAndroid Build Coastguard Worker                 opt_overwrite=1;
329*86ee64e7SAndroid Build Coastguard Worker         }
330*86ee64e7SAndroid Build Coastguard Worker         else
331*86ee64e7SAndroid Build Coastguard Worker         if (opt_overwrite==0)
332*86ee64e7SAndroid Build Coastguard Worker             if (check_exist_file(filename_try)!=0)
333*86ee64e7SAndroid Build Coastguard Worker             {
334*86ee64e7SAndroid Build Coastguard Worker                 char rep=0;
335*86ee64e7SAndroid Build Coastguard Worker                 do
336*86ee64e7SAndroid Build Coastguard Worker                 {
337*86ee64e7SAndroid Build Coastguard Worker                     char answer[128];
338*86ee64e7SAndroid Build Coastguard Worker                     int ret;
339*86ee64e7SAndroid Build Coastguard Worker                     printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
340*86ee64e7SAndroid Build Coastguard Worker                     ret = scanf("%1s",answer);
341*86ee64e7SAndroid Build Coastguard Worker                     if (ret != 1)
342*86ee64e7SAndroid Build Coastguard Worker                     {
343*86ee64e7SAndroid Build Coastguard Worker                        exit(EXIT_FAILURE);
344*86ee64e7SAndroid Build Coastguard Worker                     }
345*86ee64e7SAndroid Build Coastguard Worker                     rep = answer[0] ;
346*86ee64e7SAndroid Build Coastguard Worker                     if ((rep>='a') && (rep<='z'))
347*86ee64e7SAndroid Build Coastguard Worker                         rep -= 0x20;
348*86ee64e7SAndroid Build Coastguard Worker                 }
349*86ee64e7SAndroid Build Coastguard Worker                 while ((rep!='Y') && (rep!='N') && (rep!='A'));
350*86ee64e7SAndroid Build Coastguard Worker                 if (rep=='N')
351*86ee64e7SAndroid Build Coastguard Worker                     zipok = 0;
352*86ee64e7SAndroid Build Coastguard Worker                 if (rep=='A')
353*86ee64e7SAndroid Build Coastguard Worker                     opt_overwrite = 2;
354*86ee64e7SAndroid Build Coastguard Worker             }
355*86ee64e7SAndroid Build Coastguard Worker     }
356*86ee64e7SAndroid Build Coastguard Worker 
357*86ee64e7SAndroid Build Coastguard Worker     if (zipok==1)
358*86ee64e7SAndroid Build Coastguard Worker     {
359*86ee64e7SAndroid Build Coastguard Worker         zipFile zf;
360*86ee64e7SAndroid Build Coastguard Worker         int errclose;
361*86ee64e7SAndroid Build Coastguard Worker #        ifdef USEWIN32IOAPI
362*86ee64e7SAndroid Build Coastguard Worker         zlib_filefunc64_def ffunc;
363*86ee64e7SAndroid Build Coastguard Worker         fill_win32_filefunc64A(&ffunc);
364*86ee64e7SAndroid Build Coastguard Worker         zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
365*86ee64e7SAndroid Build Coastguard Worker #        else
366*86ee64e7SAndroid Build Coastguard Worker         zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
367*86ee64e7SAndroid Build Coastguard Worker #        endif
368*86ee64e7SAndroid Build Coastguard Worker 
369*86ee64e7SAndroid Build Coastguard Worker         if (zf == NULL)
370*86ee64e7SAndroid Build Coastguard Worker         {
371*86ee64e7SAndroid Build Coastguard Worker             printf("error opening %s\n",filename_try);
372*86ee64e7SAndroid Build Coastguard Worker             err= ZIP_ERRNO;
373*86ee64e7SAndroid Build Coastguard Worker         }
374*86ee64e7SAndroid Build Coastguard Worker         else
375*86ee64e7SAndroid Build Coastguard Worker             printf("creating %s\n",filename_try);
376*86ee64e7SAndroid Build Coastguard Worker 
377*86ee64e7SAndroid Build Coastguard Worker         for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
378*86ee64e7SAndroid Build Coastguard Worker         {
379*86ee64e7SAndroid Build Coastguard Worker             if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
380*86ee64e7SAndroid Build Coastguard Worker                   ((argv[i][1]=='o') || (argv[i][1]=='O') ||
381*86ee64e7SAndroid Build Coastguard Worker                    (argv[i][1]=='a') || (argv[i][1]=='A') ||
382*86ee64e7SAndroid Build Coastguard Worker                    (argv[i][1]=='p') || (argv[i][1]=='P') ||
383*86ee64e7SAndroid Build Coastguard Worker                    ((argv[i][1]>='0') && (argv[i][1]<='9'))) &&
384*86ee64e7SAndroid Build Coastguard Worker                   (strlen(argv[i]) == 2)))
385*86ee64e7SAndroid Build Coastguard Worker             {
386*86ee64e7SAndroid Build Coastguard Worker                 FILE * fin = NULL;
387*86ee64e7SAndroid Build Coastguard Worker                 size_t size_read;
388*86ee64e7SAndroid Build Coastguard Worker                 const char* filenameinzip = argv[i];
389*86ee64e7SAndroid Build Coastguard Worker                 const char *savefilenameinzip;
390*86ee64e7SAndroid Build Coastguard Worker                 zip_fileinfo zi;
391*86ee64e7SAndroid Build Coastguard Worker                 unsigned long crcFile=0;
392*86ee64e7SAndroid Build Coastguard Worker                 int zip64 = 0;
393*86ee64e7SAndroid Build Coastguard Worker 
394*86ee64e7SAndroid Build Coastguard Worker                 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
395*86ee64e7SAndroid Build Coastguard Worker                 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
396*86ee64e7SAndroid Build Coastguard Worker                 zi.dosDate = 0;
397*86ee64e7SAndroid Build Coastguard Worker                 zi.internal_fa = 0;
398*86ee64e7SAndroid Build Coastguard Worker                 zi.external_fa = 0;
399*86ee64e7SAndroid Build Coastguard Worker                 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
400*86ee64e7SAndroid Build Coastguard Worker 
401*86ee64e7SAndroid Build Coastguard Worker /*
402*86ee64e7SAndroid Build Coastguard Worker                 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
403*86ee64e7SAndroid Build Coastguard Worker                                  NULL,0,NULL,0,NULL / * comment * /,
404*86ee64e7SAndroid Build Coastguard Worker                                  (opt_compress_level != 0) ? Z_DEFLATED : 0,
405*86ee64e7SAndroid Build Coastguard Worker                                  opt_compress_level);
406*86ee64e7SAndroid Build Coastguard Worker */
407*86ee64e7SAndroid Build Coastguard Worker                 if ((password != NULL) && (err==ZIP_OK))
408*86ee64e7SAndroid Build Coastguard Worker                     err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
409*86ee64e7SAndroid Build Coastguard Worker 
410*86ee64e7SAndroid Build Coastguard Worker                 zip64 = isLargeFile(filenameinzip);
411*86ee64e7SAndroid Build Coastguard Worker 
412*86ee64e7SAndroid Build Coastguard Worker                                                          /* The path name saved, should not include a leading slash. */
413*86ee64e7SAndroid Build Coastguard Worker                /*if it did, windows/xp and dynazip couldn't read the zip file. */
414*86ee64e7SAndroid Build Coastguard Worker                  savefilenameinzip = filenameinzip;
415*86ee64e7SAndroid Build Coastguard Worker                  while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
416*86ee64e7SAndroid Build Coastguard Worker                  {
417*86ee64e7SAndroid Build Coastguard Worker                      savefilenameinzip++;
418*86ee64e7SAndroid Build Coastguard Worker                  }
419*86ee64e7SAndroid Build Coastguard Worker 
420*86ee64e7SAndroid Build Coastguard Worker                  /*should the zip file contain any path at all?*/
421*86ee64e7SAndroid Build Coastguard Worker                  if( opt_exclude_path )
422*86ee64e7SAndroid Build Coastguard Worker                  {
423*86ee64e7SAndroid Build Coastguard Worker                      const char *tmpptr;
424*86ee64e7SAndroid Build Coastguard Worker                      const char *lastslash = 0;
425*86ee64e7SAndroid Build Coastguard Worker                      for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
426*86ee64e7SAndroid Build Coastguard Worker                      {
427*86ee64e7SAndroid Build Coastguard Worker                          if( *tmpptr == '\\' || *tmpptr == '/')
428*86ee64e7SAndroid Build Coastguard Worker                          {
429*86ee64e7SAndroid Build Coastguard Worker                              lastslash = tmpptr;
430*86ee64e7SAndroid Build Coastguard Worker                          }
431*86ee64e7SAndroid Build Coastguard Worker                      }
432*86ee64e7SAndroid Build Coastguard Worker                      if( lastslash != NULL )
433*86ee64e7SAndroid Build Coastguard Worker                      {
434*86ee64e7SAndroid Build Coastguard Worker                          savefilenameinzip = lastslash+1; // base filename follows last slash.
435*86ee64e7SAndroid Build Coastguard Worker                      }
436*86ee64e7SAndroid Build Coastguard Worker                  }
437*86ee64e7SAndroid Build Coastguard Worker 
438*86ee64e7SAndroid Build Coastguard Worker                  /**/
439*86ee64e7SAndroid Build Coastguard Worker                 err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
440*86ee64e7SAndroid Build Coastguard Worker                                  NULL,0,NULL,0,NULL /* comment*/,
441*86ee64e7SAndroid Build Coastguard Worker                                  (opt_compress_level != 0) ? Z_DEFLATED : 0,
442*86ee64e7SAndroid Build Coastguard Worker                                  opt_compress_level,0,
443*86ee64e7SAndroid Build Coastguard Worker                                  /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
444*86ee64e7SAndroid Build Coastguard Worker                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
445*86ee64e7SAndroid Build Coastguard Worker                                  password,crcFile, zip64);
446*86ee64e7SAndroid Build Coastguard Worker 
447*86ee64e7SAndroid Build Coastguard Worker                 if (err != ZIP_OK)
448*86ee64e7SAndroid Build Coastguard Worker                     printf("error in opening %s in zipfile\n",filenameinzip);
449*86ee64e7SAndroid Build Coastguard Worker                 else
450*86ee64e7SAndroid Build Coastguard Worker                 {
451*86ee64e7SAndroid Build Coastguard Worker                     fin = FOPEN_FUNC(filenameinzip,"rb");
452*86ee64e7SAndroid Build Coastguard Worker                     if (fin==NULL)
453*86ee64e7SAndroid Build Coastguard Worker                     {
454*86ee64e7SAndroid Build Coastguard Worker                         err=ZIP_ERRNO;
455*86ee64e7SAndroid Build Coastguard Worker                         printf("error in opening %s for reading\n",filenameinzip);
456*86ee64e7SAndroid Build Coastguard Worker                     }
457*86ee64e7SAndroid Build Coastguard Worker                 }
458*86ee64e7SAndroid Build Coastguard Worker 
459*86ee64e7SAndroid Build Coastguard Worker                 if (err == ZIP_OK)
460*86ee64e7SAndroid Build Coastguard Worker                     do
461*86ee64e7SAndroid Build Coastguard Worker                     {
462*86ee64e7SAndroid Build Coastguard Worker                         err = ZIP_OK;
463*86ee64e7SAndroid Build Coastguard Worker                         size_read = fread(buf,1,size_buf,fin);
464*86ee64e7SAndroid Build Coastguard Worker                         if (size_read < size_buf)
465*86ee64e7SAndroid Build Coastguard Worker                             if (feof(fin)==0)
466*86ee64e7SAndroid Build Coastguard Worker                         {
467*86ee64e7SAndroid Build Coastguard Worker                             printf("error in reading %s\n",filenameinzip);
468*86ee64e7SAndroid Build Coastguard Worker                             err = ZIP_ERRNO;
469*86ee64e7SAndroid Build Coastguard Worker                         }
470*86ee64e7SAndroid Build Coastguard Worker 
471*86ee64e7SAndroid Build Coastguard Worker                         if (size_read>0)
472*86ee64e7SAndroid Build Coastguard Worker                         {
473*86ee64e7SAndroid Build Coastguard Worker                             err = zipWriteInFileInZip (zf,buf,(unsigned)size_read);
474*86ee64e7SAndroid Build Coastguard Worker                             if (err<0)
475*86ee64e7SAndroid Build Coastguard Worker                             {
476*86ee64e7SAndroid Build Coastguard Worker                                 printf("error in writing %s in the zipfile\n",
477*86ee64e7SAndroid Build Coastguard Worker                                                  filenameinzip);
478*86ee64e7SAndroid Build Coastguard Worker                             }
479*86ee64e7SAndroid Build Coastguard Worker 
480*86ee64e7SAndroid Build Coastguard Worker                         }
481*86ee64e7SAndroid Build Coastguard Worker                     } while ((err == ZIP_OK) && (size_read>0));
482*86ee64e7SAndroid Build Coastguard Worker 
483*86ee64e7SAndroid Build Coastguard Worker                 if (fin)
484*86ee64e7SAndroid Build Coastguard Worker                     fclose(fin);
485*86ee64e7SAndroid Build Coastguard Worker 
486*86ee64e7SAndroid Build Coastguard Worker                 if (err<0)
487*86ee64e7SAndroid Build Coastguard Worker                     err=ZIP_ERRNO;
488*86ee64e7SAndroid Build Coastguard Worker                 else
489*86ee64e7SAndroid Build Coastguard Worker                 {
490*86ee64e7SAndroid Build Coastguard Worker                     err = zipCloseFileInZip(zf);
491*86ee64e7SAndroid Build Coastguard Worker                     if (err!=ZIP_OK)
492*86ee64e7SAndroid Build Coastguard Worker                         printf("error in closing %s in the zipfile\n",
493*86ee64e7SAndroid Build Coastguard Worker                                     filenameinzip);
494*86ee64e7SAndroid Build Coastguard Worker                 }
495*86ee64e7SAndroid Build Coastguard Worker             }
496*86ee64e7SAndroid Build Coastguard Worker         }
497*86ee64e7SAndroid Build Coastguard Worker         errclose = zipClose(zf,NULL);
498*86ee64e7SAndroid Build Coastguard Worker         if (errclose != ZIP_OK)
499*86ee64e7SAndroid Build Coastguard Worker             printf("error in closing %s\n",filename_try);
500*86ee64e7SAndroid Build Coastguard Worker     }
501*86ee64e7SAndroid Build Coastguard Worker     else
502*86ee64e7SAndroid Build Coastguard Worker     {
503*86ee64e7SAndroid Build Coastguard Worker        do_help();
504*86ee64e7SAndroid Build Coastguard Worker     }
505*86ee64e7SAndroid Build Coastguard Worker 
506*86ee64e7SAndroid Build Coastguard Worker     free(buf);
507*86ee64e7SAndroid Build Coastguard Worker     return 0;
508*86ee64e7SAndroid Build Coastguard Worker }
509