1/* $NetBSD: minizip.c,v 1.1.1.1 2006/01/14 20:10:58 christos Exp $ */ 2 3/* 4 minizip.c 5 Version 1.01e, February 12th, 2005 6 7 Copyright (C) 1998-2005 Gilles Vollant 8*/ 9 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <time.h> 14#include <errno.h> 15#include <fcntl.h> 16 17#ifdef unix 18# include <unistd.h> 19# include <utime.h> 20# include <sys/types.h> 21# include <sys/stat.h> 22#else 23# include <direct.h> 24# include <io.h> 25#endif 26 27#include "zip.h" 28 29#ifdef WIN32 30#define USEWIN32IOAPI 31#include "iowin32.h" 32#endif 33 34 35 36#define WRITEBUFFERSIZE (16384) 37#define MAXFILENAME (256) 38 39#ifdef WIN32 40uLong filetime(f, tmzip, dt) 41 char *f; /* name of file to get info on */ 42 tm_zip *tmzip; /* return value: access, modific. and creation times */ 43 uLong *dt; /* dostime */ 44{ 45 int ret = 0; 46 { 47 FILETIME ftLocal; 48 HANDLE hFind; 49 WIN32_FIND_DATA ff32; 50 51 hFind = FindFirstFile(f,&ff32); 52 if (hFind != INVALID_HANDLE_VALUE) 53 { 54 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); 55 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); 56 FindClose(hFind); 57 ret = 1; 58 } 59 } 60 return ret; 61} 62#else 63#ifdef unix 64uLong filetime(f, tmzip, dt) 65 char *f; /* name of file to get info on */ 66 tm_zip *tmzip; /* return value: access, modific. and creation times */ 67 uLong *dt; /* dostime */ 68{ 69 int ret=0; 70 struct stat s; /* results of stat() */ 71 struct tm* filedate; 72 time_t tm_t=0; 73 74 if (strcmp(f,"-")!=0) 75 { 76 char name[MAXFILENAME+1]; 77 int len = strlen(f); 78 if (len > MAXFILENAME) 79 len = MAXFILENAME; 80 81 strncpy(name, f,MAXFILENAME-1); 82 /* strncpy doesnt append the trailing NULL, of the string is too long. */ 83 name[ MAXFILENAME ] = '\0'; 84 85 if (name[len - 1] == '/') 86 name[len - 1] = '\0'; 87 /* not all systems allow stat'ing a file with / appended */ 88 if (stat(name,&s)==0) 89 { 90 tm_t = s.st_mtime; 91 ret = 1; 92 } 93 } 94 filedate = localtime(&tm_t); 95 96 tmzip->tm_sec = filedate->tm_sec; 97 tmzip->tm_min = filedate->tm_min; 98 tmzip->tm_hour = filedate->tm_hour; 99 tmzip->tm_mday = filedate->tm_mday; 100 tmzip->tm_mon = filedate->tm_mon ; 101 tmzip->tm_year = filedate->tm_year; 102 103 return ret; 104} 105#else 106uLong filetime(f, tmzip, dt) 107 char *f; /* name of file to get info on */ 108 tm_zip *tmzip; /* return value: access, modific. and creation times */ 109 uLong *dt; /* dostime */ 110{ 111 return 0; 112} 113#endif 114#endif 115 116 117 118 119int check_exist_file(filename) 120 const char* filename; 121{ 122 FILE* ftestexist; 123 int ret = 1; 124 ftestexist = fopen(filename,"rb"); 125 if (ftestexist==NULL) 126 ret = 0; 127 else 128 fclose(ftestexist); 129 return ret; 130} 131 132void do_banner() 133{ 134 printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n"); 135 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); 136} 137 138void do_help() 139{ 140 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \ 141 " -o Overwrite existing file.zip\n" \ 142 " -a Append to existing file.zip\n" \ 143 " -0 Store only\n" \ 144 " -1 Compress faster\n" \ 145 " -9 Compress better\n\n"); 146} 147 148/* calculate the CRC32 of a file, 149 because to encrypt a file, we need known the CRC32 of the file before */ 150int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) 151{ 152 unsigned long calculate_crc=0; 153 int err=ZIP_OK; 154 FILE * fin = fopen(filenameinzip,"rb"); 155 unsigned long size_read = 0; 156 unsigned long total_read = 0; 157 if (fin==NULL) 158 { 159 err = ZIP_ERRNO; 160 } 161 162 if (err == ZIP_OK) 163 do 164 { 165 err = ZIP_OK; 166 size_read = (int)fread(buf,1,size_buf,fin); 167 if (size_read < size_buf) 168 if (feof(fin)==0) 169 { 170 printf("error in reading %s\n",filenameinzip); 171 err = ZIP_ERRNO; 172 } 173 174 if (size_read>0) 175 calculate_crc = crc32(calculate_crc,buf,size_read); 176 total_read += size_read; 177 178 } while ((err == ZIP_OK) && (size_read>0)); 179 180 if (fin) 181 fclose(fin); 182 183 *result_crc=calculate_crc; 184 printf("file %s crc %x\n",filenameinzip,calculate_crc); 185 return err; 186} 187 188int main(argc,argv) 189 int argc; 190 char *argv[]; 191{ 192 int i; 193 int opt_overwrite=0; 194 int opt_compress_level=Z_DEFAULT_COMPRESSION; 195 int zipfilenamearg = 0; 196 char filename_try[MAXFILENAME+16]; 197 int zipok; 198 int err=0; 199 int size_buf=0; 200 void* buf=NULL; 201 const char* password=NULL; 202 203 204 do_banner(); 205 if (argc==1) 206 { 207 do_help(); 208 return 0; 209 } 210 else 211 { 212 for (i=1;i<argc;i++) 213 { 214 if ((*argv[i])=='-') 215 { 216 const char *p=argv[i]+1; 217 218 while ((*p)!='\0') 219 { 220 char c=*(p++);; 221 if ((c=='o') || (c=='O')) 222 opt_overwrite = 1; 223 if ((c=='a') || (c=='A')) 224 opt_overwrite = 2; 225 if ((c>='0') && (c<='9')) 226 opt_compress_level = c-'0'; 227 228 if (((c=='p') || (c=='P')) && (i+1<argc)) 229 { 230 password=argv[i+1]; 231 i++; 232 } 233 } 234 } 235 else 236 if (zipfilenamearg == 0) 237 zipfilenamearg = i ; 238 } 239 } 240 241 size_buf = WRITEBUFFERSIZE; 242 buf = (void*)malloc(size_buf); 243 if (buf==NULL) 244 { 245 printf("Error allocating memory\n"); 246 return ZIP_INTERNALERROR; 247 } 248 249 if (zipfilenamearg==0) 250 zipok=0; 251 else 252 { 253 int i,len; 254 int dot_found=0; 255 256 zipok = 1 ; 257 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1); 258 /* strncpy doesnt append the trailing NULL, of the string is too long. */ 259 filename_try[ MAXFILENAME ] = '\0'; 260 261 len=(int)strlen(filename_try); 262 for (i=0;i<len;i++) 263 if (filename_try[i]=='.') 264 dot_found=1; 265 266 if (dot_found==0) 267 strcat(filename_try,".zip"); 268 269 if (opt_overwrite==2) 270 { 271 /* if the file don't exist, we not append file */ 272 if (check_exist_file(filename_try)==0) 273 opt_overwrite=1; 274 } 275 else 276 if (opt_overwrite==0) 277 if (check_exist_file(filename_try)!=0) 278 { 279 char rep=0; 280 do 281 { 282 char answer[128]; 283 int ret; 284 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); 285 ret = scanf("%1s",answer); 286 if (ret != 1) 287 { 288 exit(EXIT_FAILURE); 289 } 290 rep = answer[0] ; 291 if ((rep>='a') && (rep<='z')) 292 rep -= 0x20; 293 } 294 while ((rep!='Y') && (rep!='N') && (rep!='A')); 295 if (rep=='N') 296 zipok = 0; 297 if (rep=='A') 298 opt_overwrite = 2; 299 } 300 } 301 302 if (zipok==1) 303 { 304 zipFile zf; 305 int errclose; 306# ifdef USEWIN32IOAPI 307 zlib_filefunc_def ffunc; 308 fill_win32_filefunc(&ffunc); 309 zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); 310# else 311 zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0); 312# endif 313 314 if (zf == NULL) 315 { 316 printf("error opening %s\n",filename_try); 317 err= ZIP_ERRNO; 318 } 319 else 320 printf("creating %s\n",filename_try); 321 322 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++) 323 { 324 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) && 325 ((argv[i][1]=='o') || (argv[i][1]=='O') || 326 (argv[i][1]=='a') || (argv[i][1]=='A') || 327 (argv[i][1]=='p') || (argv[i][1]=='P') || 328 ((argv[i][1]>='0') || (argv[i][1]<='9'))) && 329 (strlen(argv[i]) == 2))) 330 { 331 FILE * fin; 332 int size_read; 333 const char* filenameinzip = argv[i]; 334 zip_fileinfo zi; 335 unsigned long crcFile=0; 336 337 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = 338 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; 339 zi.dosDate = 0; 340 zi.internal_fa = 0; 341 zi.external_fa = 0; 342 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); 343 344/* 345 err = zipOpenNewFileInZip(zf,filenameinzip,&zi, 346 NULL,0,NULL,0,NULL / * comment * /, 347 (opt_compress_level != 0) ? Z_DEFLATED : 0, 348 opt_compress_level); 349*/ 350 if ((password != NULL) && (err==ZIP_OK)) 351 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); 352 353 err = zipOpenNewFileInZip3(zf,filenameinzip,&zi, 354 NULL,0,NULL,0,NULL /* comment*/, 355 (opt_compress_level != 0) ? Z_DEFLATED : 0, 356 opt_compress_level,0, 357 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ 358 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 359 password,crcFile); 360 361 if (err != ZIP_OK) 362 printf("error in opening %s in zipfile\n",filenameinzip); 363 else 364 { 365 fin = fopen(filenameinzip,"rb"); 366 if (fin==NULL) 367 { 368 err=ZIP_ERRNO; 369 printf("error in opening %s for reading\n",filenameinzip); 370 } 371 } 372 373 if (err == ZIP_OK) 374 do 375 { 376 err = ZIP_OK; 377 size_read = (int)fread(buf,1,size_buf,fin); 378 if (size_read < size_buf) 379 if (feof(fin)==0) 380 { 381 printf("error in reading %s\n",filenameinzip); 382 err = ZIP_ERRNO; 383 } 384 385 if (size_read>0) 386 { 387 err = zipWriteInFileInZip (zf,buf,size_read); 388 if (err<0) 389 { 390 printf("error in writing %s in the zipfile\n", 391 filenameinzip); 392 } 393 394 } 395 } while ((err == ZIP_OK) && (size_read>0)); 396 397 if (fin) 398 fclose(fin); 399 400 if (err<0) 401 err=ZIP_ERRNO; 402 else 403 { 404 err = zipCloseFileInZip(zf); 405 if (err!=ZIP_OK) 406 printf("error in closing %s in the zipfile\n", 407 filenameinzip); 408 } 409 } 410 } 411 errclose = zipClose(zf,NULL); 412 if (errclose != ZIP_OK) 413 printf("error in closing %s\n",filename_try); 414 } 415 else 416 { 417 do_help(); 418 } 419 420 free(buf); 421 return 0; 422} 423