miniunz.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:15k
源码类别:

通讯编程

开发平台:

Visual C++

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