"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/contrib/minizip/miniunz.c" (21 Nov 2020, 17763 Bytes) of package /linux/privat/muscle7.62.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "miniunz.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

    1 /*
    2    miniunz.c
    3    Version 1.1, February 14h, 2010
    4    sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
    5 
    6          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
    7 
    8          Modifications of Unzip for Zip64
    9          Copyright (C) 2007-2008 Even Rouault
   10 
   11          Modifications for Zip64 support on both zip and unzip
   12          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
   13 */
   14 
   15 #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
   16         #ifndef __USE_FILE_OFFSET64
   17                 #define __USE_FILE_OFFSET64
   18         #endif
   19         #ifndef __USE_LARGEFILE64
   20                 #define __USE_LARGEFILE64
   21         #endif
   22         #ifndef _LARGEFILE64_SOURCE
   23                 #define _LARGEFILE64_SOURCE
   24         #endif
   25         #ifndef _FILE_OFFSET_BIT
   26                 #define _FILE_OFFSET_BIT 64
   27         #endif
   28 #endif
   29 
   30 #ifdef __APPLE__
   31 // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
   32 #define FOPEN_FUNC(filename, mode) fopen(filename, mode)
   33 #define FTELLO_FUNC(stream) ftello(stream)
   34 #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
   35 #else
   36 #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
   37 #define FTELLO_FUNC(stream) ftello64(stream)
   38 #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
   39 #endif
   40 
   41 
   42 #include <stdio.h>
   43 #include <stdlib.h>
   44 #include <string.h>
   45 #include <time.h>
   46 #include <errno.h>
   47 #include <fcntl.h>
   48 
   49 #ifdef _WIN32
   50 # include <direct.h>
   51 # include <io.h>
   52 #else
   53 # include <unistd.h>
   54 # include <utime.h>
   55 #endif
   56 
   57 
   58 #include "unzip.h"
   59 
   60 #define CASESENSITIVITY (0)
   61 #define WRITEBUFFERSIZE (8192)
   62 #define MAXFILENAME (256)
   63 
   64 #ifdef _WIN32
   65 #define USEWIN32IOAPI
   66 #include "iowin32.h"
   67 #endif
   68 /*
   69   mini unzip, demo of unzip package
   70 
   71   usage :
   72   Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
   73 
   74   list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
   75     if it exists
   76 */
   77 
   78 
   79 /* change_file_date : change the date/time of a file
   80     filename : the filename of the file where date/time must be modified
   81     dosdate : the new date at the MSDos format (4 bytes)
   82     tmu_date : the SAME new date at the tm_unz format */
   83 void change_file_date(filename,dosdate,tmu_date)
   84     const char *filename;
   85     uLong dosdate;
   86     tm_unz tmu_date;
   87 {
   88 #ifdef _WIN32
   89   HANDLE hFile;
   90   FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
   91 
   92   hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
   93                       0,NULL,OPEN_EXISTING,0,NULL);
   94   GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
   95   DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
   96   LocalFileTimeToFileTime(&ftLocal,&ftm);
   97   SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
   98   CloseHandle(hFile);
   99 #else
  100 #ifdef unix || __APPLE__
  101   struct utimbuf ut;
  102   struct tm newdate;
  103   newdate.tm_sec = tmu_date.tm_sec;
  104   newdate.tm_min=tmu_date.tm_min;
  105   newdate.tm_hour=tmu_date.tm_hour;
  106   newdate.tm_mday=tmu_date.tm_mday;
  107   newdate.tm_mon=tmu_date.tm_mon;
  108   if (tmu_date.tm_year > 1900)
  109       newdate.tm_year=tmu_date.tm_year - 1900;
  110   else
  111       newdate.tm_year=tmu_date.tm_year ;
  112   newdate.tm_isdst=-1;
  113 
  114   ut.actime=ut.modtime=mktime(&newdate);
  115   utime(filename,&ut);
  116 #endif
  117 #endif
  118 }
  119 
  120 
  121 /* mymkdir and change_file_date are not 100 % portable
  122    As I don't know well Unix, I wait feedback for the unix portion */
  123 
  124 int mymkdir(dirname)
  125     const char* dirname;
  126 {
  127     int ret=0;
  128 #ifdef _WIN32
  129     ret = _mkdir(dirname);
  130 #elif unix
  131     ret = mkdir (dirname,0775);
  132 #elif __APPLE__
  133     ret = mkdir (dirname,0775);
  134 #endif
  135     return ret;
  136 }
  137 
  138 int makedir (newdir)
  139     char *newdir;
  140 {
  141   char *buffer ;
  142   char *p;
  143   int  len = (int)strlen(newdir);
  144 
  145   if (len <= 0)
  146     return 0;
  147 
  148   buffer = (char*)malloc(len+1);
  149         if (buffer==NULL)
  150         {
  151                 printf("Error allocating memory\n");
  152                 return UNZ_INTERNALERROR;
  153         }
  154   strcpy(buffer,newdir);
  155 
  156   if (buffer[len-1] == '/') {
  157     buffer[len-1] = '\0';
  158   }
  159   if (mymkdir(buffer) == 0)
  160     {
  161       free(buffer);
  162       return 1;
  163     }
  164 
  165   p = buffer+1;
  166   while (1)
  167     {
  168       char hold;
  169 
  170       while(*p && *p != '\\' && *p != '/')
  171         p++;
  172       hold = *p;
  173       *p = 0;
  174       if ((mymkdir(buffer) == -1) && (errno == ENOENT))
  175         {
  176           printf("couldn't create directory %s\n",buffer);
  177           free(buffer);
  178           return 0;
  179         }
  180       if (hold == 0)
  181         break;
  182       *p++ = hold;
  183     }
  184   free(buffer);
  185   return 1;
  186 }
  187 
  188 void do_banner()
  189 {
  190     printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
  191     printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
  192 }
  193 
  194 void do_help()
  195 {
  196     printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
  197            "  -e  Extract without pathname (junk paths)\n" \
  198            "  -x  Extract with pathname\n" \
  199            "  -v  list files\n" \
  200            "  -l  list files\n" \
  201            "  -d  directory to extract into\n" \
  202            "  -o  overwrite files without prompting\n" \
  203            "  -p  extract crypted file using password\n\n");
  204 }
  205 
  206 void Display64BitsSize(ZPOS64_T n, int size_char)
  207 {
  208   /* to avoid compatibility problem , we do here the conversion */
  209   char number[21];
  210   int offset=19;
  211   int pos_string = 19;
  212   number[20]=0;
  213   for (;;) {
  214       number[offset]=(char)((n%10)+'0');
  215       if (number[offset] != '0')
  216           pos_string=offset;
  217       n/=10;
  218       if (offset==0)
  219           break;
  220       offset--;
  221   }
  222   {
  223       int size_display_string = 19-pos_string;
  224       while (size_char > size_display_string)
  225       {
  226           size_char--;
  227           printf(" ");
  228       }
  229   }
  230 
  231   printf("%s",&number[pos_string]);
  232 }
  233 
  234 int do_list(uf)
  235     unzFile uf;
  236 {
  237     uLong i;
  238     unz_global_info64 gi;
  239     int err;
  240 
  241     err = unzGetGlobalInfo64(uf,&gi);
  242     if (err!=UNZ_OK)
  243         printf("error %d with zipfile in unzGetGlobalInfo \n",err);
  244     printf("  Length  Method     Size Ratio   Date    Time   CRC-32     Name\n");
  245     printf("  ------  ------     ---- -----   ----    ----   ------     ----\n");
  246     for (i=0;i<gi.number_entry;i++)
  247     {
  248         char filename_inzip[256];
  249         unz_file_info64 file_info;
  250         uLong ratio=0;
  251         const char *string_method;
  252         char charCrypt=' ';
  253         err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
  254         if (err!=UNZ_OK)
  255         {
  256             printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
  257             break;
  258         }
  259         if (file_info.uncompressed_size>0)
  260             ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
  261 
  262         /* display a '*' if the file is crypted */
  263         if ((file_info.flag & 1) != 0)
  264             charCrypt='*';
  265 
  266         if (file_info.compression_method==0)
  267             string_method="Stored";
  268         else
  269         if (file_info.compression_method==Z_DEFLATED)
  270         {
  271             uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
  272             if (iLevel==0)
  273               string_method="Defl:N";
  274             else if (iLevel==1)
  275               string_method="Defl:X";
  276             else if ((iLevel==2) || (iLevel==3))
  277               string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
  278         }
  279         else
  280         if (file_info.compression_method==Z_BZIP2ED)
  281         {
  282               string_method="BZip2 ";
  283         }
  284         else
  285             string_method="Unkn. ";
  286 
  287         Display64BitsSize(file_info.uncompressed_size,7);
  288         printf("  %6s%c",string_method,charCrypt);
  289         Display64BitsSize(file_info.compressed_size,7);
  290         printf(" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
  291                 ratio,
  292                 (uLong)file_info.tmu_date.tm_mon + 1,
  293                 (uLong)file_info.tmu_date.tm_mday,
  294                 (uLong)file_info.tmu_date.tm_year % 100,
  295                 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
  296                 (uLong)file_info.crc,filename_inzip);
  297         if ((i+1)<gi.number_entry)
  298         {
  299             err = unzGoToNextFile(uf);
  300             if (err!=UNZ_OK)
  301             {
  302                 printf("error %d with zipfile in unzGoToNextFile\n",err);
  303                 break;
  304             }
  305         }
  306     }
  307 
  308     return 0;
  309 }
  310 
  311 
  312 int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
  313     unzFile uf;
  314     const int* popt_extract_without_path;
  315     int* popt_overwrite;
  316     const char* password;
  317 {
  318     char filename_inzip[256];
  319     char* filename_withoutpath;
  320     char* p;
  321     int err=UNZ_OK;
  322     FILE *fout=NULL;
  323     void* buf;
  324     uInt size_buf;
  325 
  326     unz_file_info64 file_info;
  327     uLong ratio=0;
  328     err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
  329 
  330     if (err!=UNZ_OK)
  331     {
  332         printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
  333         return err;
  334     }
  335 
  336     size_buf = WRITEBUFFERSIZE;
  337     buf = (void*)malloc(size_buf);
  338     if (buf==NULL)
  339     {
  340         printf("Error allocating memory\n");
  341         return UNZ_INTERNALERROR;
  342     }
  343 
  344     p = filename_withoutpath = filename_inzip;
  345     while ((*p) != '\0')
  346     {
  347         if (((*p)=='/') || ((*p)=='\\'))
  348             filename_withoutpath = p+1;
  349         p++;
  350     }
  351 
  352     if ((*filename_withoutpath)=='\0')
  353     {
  354         if ((*popt_extract_without_path)==0)
  355         {
  356             printf("creating directory: %s\n",filename_inzip);
  357             mymkdir(filename_inzip);
  358         }
  359     }
  360     else
  361     {
  362         const char* write_filename;
  363         int skip=0;
  364 
  365         if ((*popt_extract_without_path)==0)
  366             write_filename = filename_inzip;
  367         else
  368             write_filename = filename_withoutpath;
  369 
  370         err = unzOpenCurrentFilePassword(uf,password);
  371         if (err!=UNZ_OK)
  372         {
  373             printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
  374         }
  375 
  376         if (((*popt_overwrite)==0) && (err==UNZ_OK))
  377         {
  378             char rep=0;
  379             FILE* ftestexist;
  380             ftestexist = FOPEN_FUNC(write_filename,"rb");
  381             if (ftestexist!=NULL)
  382             {
  383                 fclose(ftestexist);
  384                 do
  385                 {
  386                     char answer[128];
  387                     int ret;
  388 
  389                     printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
  390                     ret = scanf("%1s",answer);
  391                     if (ret != 1)
  392                     {
  393                        exit(EXIT_FAILURE);
  394                     }
  395                     rep = answer[0] ;
  396                     if ((rep>='a') && (rep<='z'))
  397                         rep -= 0x20;
  398                 }
  399                 while ((rep!='Y') && (rep!='N') && (rep!='A'));
  400             }
  401 
  402             if (rep == 'N')
  403                 skip = 1;
  404 
  405             if (rep == 'A')
  406                 *popt_overwrite=1;
  407         }
  408 
  409         if ((skip==0) && (err==UNZ_OK))
  410         {
  411             fout=FOPEN_FUNC(write_filename,"wb");
  412             /* some zipfile don't contain directory alone before file */
  413             if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
  414                                 (filename_withoutpath!=(char*)filename_inzip))
  415             {
  416                 char c=*(filename_withoutpath-1);
  417                 *(filename_withoutpath-1)='\0';
  418                 makedir(write_filename);
  419                 *(filename_withoutpath-1)=c;
  420                 fout=FOPEN_FUNC(write_filename,"wb");
  421             }
  422 
  423             if (fout==NULL)
  424             {
  425                 printf("error opening %s\n",write_filename);
  426             }
  427         }
  428 
  429         if (fout!=NULL)
  430         {
  431             printf(" extracting: %s\n",write_filename);
  432 
  433             do
  434             {
  435                 err = unzReadCurrentFile(uf,buf,size_buf);
  436                 if (err<0)
  437                 {
  438                     printf("error %d with zipfile in unzReadCurrentFile\n",err);
  439                     break;
  440                 }
  441                 if (err>0)
  442                     if (fwrite(buf,err,1,fout)!=1)
  443                     {
  444                         printf("error in writing extracted file\n");
  445                         err=UNZ_ERRNO;
  446                         break;
  447                     }
  448             }
  449             while (err>0);
  450             if (fout)
  451                     fclose(fout);
  452 
  453             if (err==0)
  454                 change_file_date(write_filename,file_info.dosDate,
  455                                  file_info.tmu_date);
  456         }
  457 
  458         if (err==UNZ_OK)
  459         {
  460             err = unzCloseCurrentFile (uf);
  461             if (err!=UNZ_OK)
  462             {
  463                 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
  464             }
  465         }
  466         else
  467             unzCloseCurrentFile(uf); /* don't lose the error */
  468     }
  469 
  470     free(buf);
  471     return err;
  472 }
  473 
  474 
  475 int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
  476     unzFile uf;
  477     int opt_extract_without_path;
  478     int opt_overwrite;
  479     const char* password;
  480 {
  481     uLong i;
  482     unz_global_info64 gi;
  483     int err;
  484     FILE* fout=NULL;
  485 
  486     err = unzGetGlobalInfo64(uf,&gi);
  487     if (err!=UNZ_OK)
  488         printf("error %d with zipfile in unzGetGlobalInfo \n",err);
  489 
  490     for (i=0;i<gi.number_entry;i++)
  491     {
  492         if (do_extract_currentfile(uf,&opt_extract_without_path,
  493                                       &opt_overwrite,
  494                                       password) != UNZ_OK)
  495             break;
  496 
  497         if ((i+1)<gi.number_entry)
  498         {
  499             err = unzGoToNextFile(uf);
  500             if (err!=UNZ_OK)
  501             {
  502                 printf("error %d with zipfile in unzGoToNextFile\n",err);
  503                 break;
  504             }
  505         }
  506     }
  507 
  508     return 0;
  509 }
  510 
  511 int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
  512     unzFile uf;
  513     const char* filename;
  514     int opt_extract_without_path;
  515     int opt_overwrite;
  516     const char* password;
  517 {
  518     int err = UNZ_OK;
  519     if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
  520     {
  521         printf("file %s not found in the zipfile\n",filename);
  522         return 2;
  523     }
  524 
  525     if (do_extract_currentfile(uf,&opt_extract_without_path,
  526                                       &opt_overwrite,
  527                                       password) == UNZ_OK)
  528         return 0;
  529     else
  530         return 1;
  531 }
  532 
  533 
  534 int main(argc,argv)
  535     int argc;
  536     char *argv[];
  537 {
  538     const char *zipfilename=NULL;
  539     const char *filename_to_extract=NULL;
  540     const char *password=NULL;
  541     char filename_try[MAXFILENAME+16] = "";
  542     int i;
  543     int ret_value=0;
  544     int opt_do_list=0;
  545     int opt_do_extract=1;
  546     int opt_do_extract_withoutpath=0;
  547     int opt_overwrite=0;
  548     int opt_extractdir=0;
  549     const char *dirname=NULL;
  550     unzFile uf=NULL;
  551 
  552     do_banner();
  553     if (argc==1)
  554     {
  555         do_help();
  556         return 0;
  557     }
  558     else
  559     {
  560         for (i=1;i<argc;i++)
  561         {
  562             if ((*argv[i])=='-')
  563             {
  564                 const char *p=argv[i]+1;
  565 
  566                 while ((*p)!='\0')
  567                 {
  568                     char c=*(p++);;
  569                     if ((c=='l') || (c=='L'))
  570                         opt_do_list = 1;
  571                     if ((c=='v') || (c=='V'))
  572                         opt_do_list = 1;
  573                     if ((c=='x') || (c=='X'))
  574                         opt_do_extract = 1;
  575                     if ((c=='e') || (c=='E'))
  576                         opt_do_extract = opt_do_extract_withoutpath = 1;
  577                     if ((c=='o') || (c=='O'))
  578                         opt_overwrite=1;
  579                     if ((c=='d') || (c=='D'))
  580                     {
  581                         opt_extractdir=1;
  582                         dirname=argv[i+1];
  583                     }
  584 
  585                     if (((c=='p') || (c=='P')) && (i+1<argc))
  586                     {
  587                         password=argv[i+1];
  588                         i++;
  589                     }
  590                 }
  591             }
  592             else
  593             {
  594                 if (zipfilename == NULL)
  595                     zipfilename = argv[i];
  596                 else if ((filename_to_extract==NULL) && (!opt_extractdir))
  597                         filename_to_extract = argv[i] ;
  598             }
  599         }
  600     }
  601 
  602     if (zipfilename!=NULL)
  603     {
  604 
  605 #        ifdef USEWIN32IOAPI
  606         zlib_filefunc64_def ffunc;
  607 #        endif
  608 
  609         strncpy(filename_try, zipfilename,MAXFILENAME-1);
  610         /* strncpy doesnt append the trailing NULL, of the string is too long. */
  611         filename_try[ MAXFILENAME ] = '\0';
  612 
  613 #        ifdef USEWIN32IOAPI
  614         fill_win32_filefunc64A(&ffunc);
  615         uf = unzOpen2_64(zipfilename,&ffunc);
  616 #        else
  617         uf = unzOpen64(zipfilename);
  618 #        endif
  619         if (uf==NULL)
  620         {
  621             strcat(filename_try,".zip");
  622 #            ifdef USEWIN32IOAPI
  623             uf = unzOpen2_64(filename_try,&ffunc);
  624 #            else
  625             uf = unzOpen64(filename_try);
  626 #            endif
  627         }
  628     }
  629 
  630     if (uf==NULL)
  631     {
  632         printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
  633         return 1;
  634     }
  635     printf("%s opened\n",filename_try);
  636 
  637     if (opt_do_list==1)
  638         ret_value = do_list(uf);
  639     else if (opt_do_extract==1)
  640     {
  641 #ifdef _WIN32
  642         if (opt_extractdir && _chdir(dirname))
  643 #else
  644         if (opt_extractdir && chdir(dirname))
  645 #endif
  646         {
  647           printf("Error changing into %s, aborting\n", dirname);
  648           exit(-1);
  649         }
  650 
  651         if (filename_to_extract == NULL)
  652             ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
  653         else
  654             ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
  655     }
  656 
  657     unzClose(uf);
  658 
  659     return ret_value;
  660 }