minizip.c
上传用户:shengde
上传日期:2021-02-21
资源大小:638k
文件大小:14k
源码类别:

压缩解压

开发平台:

Visual C++

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