pcl.pclziplib.php
上传用户:stephen_wu
上传日期:2008-07-05
资源大小:1757k
文件大小:249k
源码类别:

网络

开发平台:

Unix_Linux

  1.           }
  2.         }
  3.       }
  4.       // ----- Look for path to add
  5.       if ($p_add_dir != "") {
  6.         if (substr($p_add_dir, -1) == "/")
  7.           $v_stored_filename = $p_add_dir.$v_stored_filename;
  8.         else
  9.           $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  10.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
  11.       }
  12.     }
  13.     // ----- Filename (reduce the path of stored name)
  14.     $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
  15.     $p_filedescr['stored_filename'] = $v_stored_filename;
  16.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename']));
  17.     
  18.     // ----- Return
  19.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  20.     return $v_result;
  21.   }
  22.   // --------------------------------------------------------------------------------
  23.   // --------------------------------------------------------------------------------
  24.   // Function : privWriteFileHeader()
  25.   // Description :
  26.   // Parameters :
  27.   // Return Values :
  28.   // --------------------------------------------------------------------------------
  29.   function privWriteFileHeader(&$p_header)
  30.   {
  31.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  32.     $v_result=1;
  33.     // ----- Store the offset position of the file
  34.     $p_header['offset'] = ftell($this->zip_fd);
  35.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
  36.     // ----- Transform UNIX mtime to DOS format mdate/mtime
  37.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  38.     $v_date = getdate($p_header['mtime']);
  39.     $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  40.     $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  41.     // ----- Packed data
  42.     $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
  43.                       $p_header['version_extracted'], $p_header['flag'],
  44.                           $p_header['compression'], $v_mtime, $v_mdate,
  45.                           $p_header['crc'], $p_header['compressed_size'],
  46.   $p_header['size'],
  47.                           strlen($p_header['stored_filename']),
  48.   $p_header['extra_len']);
  49.     // ----- Write the first 148 bytes of the header in the archive
  50.     fputs($this->zip_fd, $v_binary_data, 30);
  51.     // ----- Write the variable fields
  52.     if (strlen($p_header['stored_filename']) != 0)
  53.     {
  54.       fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  55.     }
  56.     if ($p_header['extra_len'] != 0)
  57.     {
  58.       fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  59.     }
  60.     // ----- Return
  61.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  62.     return $v_result;
  63.   }
  64.   // --------------------------------------------------------------------------------
  65.   // --------------------------------------------------------------------------------
  66.   // Function : privWriteCentralFileHeader()
  67.   // Description :
  68.   // Parameters :
  69.   // Return Values :
  70.   // --------------------------------------------------------------------------------
  71.   function privWriteCentralFileHeader(&$p_header)
  72.   {
  73.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  74.     $v_result=1;
  75.     // TBC
  76.     //for(reset($p_header); $key = key($p_header); next($p_header)) {
  77.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
  78.     //}
  79.     // ----- Transform UNIX mtime to DOS format mdate/mtime
  80.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  81.     $v_date = getdate($p_header['mtime']);
  82.     $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  83.     $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  84.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment size : ''.$p_header['comment_len'].''');
  85.     // ----- Packed data
  86.     $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
  87.                       $p_header['version'], $p_header['version_extracted'],
  88.                           $p_header['flag'], $p_header['compression'],
  89.   $v_mtime, $v_mdate, $p_header['crc'],
  90.                           $p_header['compressed_size'], $p_header['size'],
  91.                           strlen($p_header['stored_filename']),
  92.   $p_header['extra_len'], $p_header['comment_len'],
  93.                           $p_header['disk'], $p_header['internal'],
  94.   $p_header['external'], $p_header['offset']);
  95.     // ----- Write the 42 bytes of the header in the zip file
  96.     fputs($this->zip_fd, $v_binary_data, 46);
  97.     // ----- Write the variable fields
  98.     if (strlen($p_header['stored_filename']) != 0)
  99.     {
  100.       fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  101.     }
  102.     if ($p_header['extra_len'] != 0)
  103.     {
  104.       fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  105.     }
  106.     if ($p_header['comment_len'] != 0)
  107.     {
  108.       fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
  109.     }
  110.     // ----- Return
  111.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  112.     return $v_result;
  113.   }
  114.   // --------------------------------------------------------------------------------
  115.   // --------------------------------------------------------------------------------
  116.   // Function : privWriteCentralHeader()
  117.   // Description :
  118.   // Parameters :
  119.   // Return Values :
  120.   // --------------------------------------------------------------------------------
  121.   function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
  122.   {
  123.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
  124.     $v_result=1;
  125.     // ----- Packed data
  126.     $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
  127.                       $p_nb_entries, $p_size,
  128.   $p_offset, strlen($p_comment));
  129.     // ----- Write the 22 bytes of the header in the zip file
  130.     fputs($this->zip_fd, $v_binary_data, 22);
  131.     // ----- Write the variable fields
  132.     if (strlen($p_comment) != 0)
  133.     {
  134.       fputs($this->zip_fd, $p_comment, strlen($p_comment));
  135.     }
  136.     // ----- Return
  137.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  138.     return $v_result;
  139.   }
  140.   // --------------------------------------------------------------------------------
  141.   // --------------------------------------------------------------------------------
  142.   // Function : privList()
  143.   // Description :
  144.   // Parameters :
  145.   // Return Values :
  146.   // --------------------------------------------------------------------------------
  147.   function privList(&$p_list)
  148.   {
  149.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
  150.     $v_result=1;
  151.     // ----- Magic quotes trick
  152.     $this->privDisableMagicQuotes();
  153.     // ----- Open the zip file
  154.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  155.     if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  156.     {
  157.       // ----- Magic quotes trick
  158.       $this->privSwapBackMagicQuotes();
  159.       
  160.       // ----- Error log
  161.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive ''.$this->zipname.'' in binary read mode');
  162.       // ----- Return
  163.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  164.       return PclZip::errorCode();
  165.     }
  166.     // ----- Read the central directory informations
  167.     $v_central_dir = array();
  168.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  169.     {
  170.       $this->privSwapBackMagicQuotes();
  171.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  172.       return $v_result;
  173.     }
  174.     // ----- Go to beginning of Central Dir
  175.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
  176.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  177.     @rewind($this->zip_fd);
  178.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  179.     if (@fseek($this->zip_fd, $v_central_dir['offset']))
  180.     {
  181.       $this->privSwapBackMagicQuotes();
  182.       // ----- Error log
  183.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  184.       // ----- Return
  185.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  186.       return PclZip::errorCode();
  187.     }
  188.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  189.     // ----- Read each entry
  190.     for ($i=0; $i<$v_central_dir['entries']; $i++)
  191.     {
  192.       // ----- Read the file header
  193.       if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  194.       {
  195.         $this->privSwapBackMagicQuotes();
  196.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  197.         return $v_result;
  198.       }
  199.       $v_header['index'] = $i;
  200.       // ----- Get the only interesting attributes
  201.       $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
  202.       unset($v_header);
  203.     }
  204.     // ----- Close the zip file
  205.     $this->privCloseFd();
  206.     // ----- Magic quotes trick
  207.     $this->privSwapBackMagicQuotes();
  208.     // ----- Return
  209.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  210.     return $v_result;
  211.   }
  212.   // --------------------------------------------------------------------------------
  213.   // --------------------------------------------------------------------------------
  214.   // Function : privConvertHeader2FileInfo()
  215.   // Description :
  216.   //   This function takes the file informations from the central directory
  217.   //   entries and extract the interesting parameters that will be given back.
  218.   //   The resulting file infos are set in the array $p_info
  219.   //     $p_info['filename'] : Filename with full path. Given by user (add),
  220.   //                           extracted in the filesystem (extract).
  221.   //     $p_info['stored_filename'] : Stored filename in the archive.
  222.   //     $p_info['size'] = Size of the file.
  223.   //     $p_info['compressed_size'] = Compressed size of the file.
  224.   //     $p_info['mtime'] = Last modification date of the file.
  225.   //     $p_info['comment'] = Comment associated with the file.
  226.   //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
  227.   //     $p_info['status'] = status of the action on the file.
  228.   //     $p_info['crc'] = CRC of the file content.
  229.   // Parameters :
  230.   // Return Values :
  231.   // --------------------------------------------------------------------------------
  232.   function privConvertHeader2FileInfo($p_header, &$p_info)
  233.   {
  234.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
  235.     $v_result=1;
  236.     // ----- Get the interesting attributes
  237.     $p_info['filename'] = $p_header['filename'];
  238.     $p_info['stored_filename'] = $p_header['stored_filename'];
  239.     $p_info['size'] = $p_header['size'];
  240.     $p_info['compressed_size'] = $p_header['compressed_size'];
  241.     $p_info['mtime'] = $p_header['mtime'];
  242.     $p_info['comment'] = $p_header['comment'];
  243.     $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
  244.     $p_info['index'] = $p_header['index'];
  245.     $p_info['status'] = $p_header['status'];
  246.     $p_info['crc'] = $p_header['crc'];
  247.     // ----- Return
  248.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  249.     return $v_result;
  250.   }
  251.   // --------------------------------------------------------------------------------
  252.   // --------------------------------------------------------------------------------
  253.   // Function : privExtractByRule()
  254.   // Description :
  255.   //   Extract a file or directory depending of rules (by index, by name, ...)
  256.   // Parameters :
  257.   //   $p_file_list : An array where will be placed the properties of each
  258.   //                  extracted file
  259.   //   $p_path : Path to add while writing the extracted files
  260.   //   $p_remove_path : Path to remove (from the file memorized path) while writing the
  261.   //                    extracted files. If the path does not match the file path,
  262.   //                    the file is extracted with its memorized path.
  263.   //                    $p_remove_path does not apply to 'list' mode.
  264.   //                    $p_path and $p_remove_path are commulative.
  265.   // Return Values :
  266.   //   1 on success,0 or less on error (see error code list)
  267.   // --------------------------------------------------------------------------------
  268.   function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  269.   {
  270.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  271.     $v_result=1;
  272.     // ----- Magic quotes trick
  273.     $this->privDisableMagicQuotes();
  274.     // ----- Check the path
  275.     if (   ($p_path == "")
  276.     || (   (substr($p_path, 0, 1) != "/")
  277.     && (substr($p_path, 0, 3) != "../")
  278. && (substr($p_path,1,2)!=":/")))
  279.       $p_path = "./".$p_path;
  280.     // ----- Reduce the path last (and duplicated) '/'
  281.     if (($p_path != "./") && ($p_path != "/"))
  282.     {
  283.       // ----- Look for the path end '/'
  284.       while (substr($p_path, -1) == "/")
  285.       {
  286.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
  287.         $p_path = substr($p_path, 0, strlen($p_path)-1);
  288.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
  289.       }
  290.     }
  291.     // ----- Look for path to remove format (should end by /)
  292.     if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  293.     {
  294.       $p_remove_path .= '/';
  295.     }
  296.     $p_remove_path_size = strlen($p_remove_path);
  297.     // ----- Open the zip file
  298.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  299.     if (($v_result = $this->privOpenFd('rb')) != 1)
  300.     {
  301.       $this->privSwapBackMagicQuotes();
  302.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  303.       return $v_result;
  304.     }
  305.     // ----- Read the central directory informations
  306.     $v_central_dir = array();
  307.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  308.     {
  309.       // ----- Close the zip file
  310.       $this->privCloseFd();
  311.       $this->privSwapBackMagicQuotes();
  312.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  313.       return $v_result;
  314.     }
  315.     // ----- Start at beginning of Central Dir
  316.     $v_pos_entry = $v_central_dir['offset'];
  317.     // ----- Read each entry
  318.     $j_start = 0;
  319.     for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  320.     {
  321.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
  322.       // ----- Read next Central dir entry
  323.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
  324.       @rewind($this->zip_fd);
  325.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
  326.       if (@fseek($this->zip_fd, $v_pos_entry))
  327.       {
  328.         // ----- Close the zip file
  329.         $this->privCloseFd();
  330.         $this->privSwapBackMagicQuotes();
  331.         // ----- Error log
  332.         PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  333.         // ----- Return
  334.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  335.         return PclZip::errorCode();
  336.       }
  337.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
  338.       // ----- Read the file header
  339.       $v_header = array();
  340.       if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  341.       {
  342.         // ----- Close the zip file
  343.         $this->privCloseFd();
  344.         $this->privSwapBackMagicQuotes();
  345.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  346.         return $v_result;
  347.       }
  348.       // ----- Store the index
  349.       $v_header['index'] = $i;
  350.       // ----- Store the file position
  351.       $v_pos_entry = ftell($this->zip_fd);
  352.       // ----- Look for the specific extract rules
  353.       $v_extract = false;
  354.       // ----- Look for extract by name rule
  355.       if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
  356.           && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  357.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  358.           // ----- Look if the filename is in the list
  359.           for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
  360.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  361.               // ----- Look for a directory
  362.               if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  363.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  364.                   // ----- Look if the directory is in the filename path
  365.                   if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  366.                       && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  367.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  368.                       $v_extract = true;
  369.                   }
  370.               }
  371.               // ----- Look for a filename
  372.               elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  373.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  374.                   $v_extract = true;
  375.               }
  376.           }
  377.       }
  378.       // ----- Look for extract by ereg rule
  379.       else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
  380.                && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  381.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  382.           if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
  383.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  384.               $v_extract = true;
  385.           }
  386.       }
  387.       // ----- Look for extract by preg rule
  388.       else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
  389.                && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  390.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  391.           if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
  392.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  393.               $v_extract = true;
  394.           }
  395.       }
  396.       // ----- Look for extract by index rule
  397.       else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  398.                && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  399.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  400.           
  401.           // ----- Look if the index is in the list
  402.           for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
  403.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
  404.               if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  405.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  406.                   $v_extract = true;
  407.               }
  408.               if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  409.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  410.                   $j_start = $j+1;
  411.               }
  412.               if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  413.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  414.                   break;
  415.               }
  416.           }
  417.       }
  418.       // ----- Look for no rule, which means extract all the archive
  419.       else {
  420.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
  421.           $v_extract = true;
  422.       }
  423.   // ----- Check compression method
  424.   if (   ($v_extract)
  425.       && (   ($v_header['compression'] != 8)
  426.       && ($v_header['compression'] != 0))) {
  427.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
  428.           $v_header['status'] = 'unsupported_compression';
  429.           // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  430.           if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  431.       && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  432.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  433.               $this->privSwapBackMagicQuotes();
  434.               
  435.               PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
  436.                        "Filename '".$v_header['stored_filename']."' is "
  437.               ."compressed by an unsupported compression "
  438.               ."method (".$v_header['compression'].") ");
  439.               //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  440.               return PclZip::errorCode();
  441.   }
  442.   }
  443.   
  444.   // ----- Check encrypted files
  445.   if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
  446.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
  447.           $v_header['status'] = 'unsupported_encryption';
  448.           // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  449.           if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  450.       && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  451.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  452.               $this->privSwapBackMagicQuotes();
  453.               PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
  454.                        "Unsupported encryption for "
  455.               ." filename '".$v_header['stored_filename']
  456.    ."'");
  457.               //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  458.               return PclZip::errorCode();
  459.   }
  460.     }
  461.       // ----- Look for real extraction
  462.       if (($v_extract) && ($v_header['status'] != 'ok')) {
  463.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
  464.           $v_result = $this->privConvertHeader2FileInfo($v_header,
  465.                                         $p_file_list[$v_nb_extracted++]);
  466.           if ($v_result != 1) {
  467.               $this->privCloseFd();
  468.               $this->privSwapBackMagicQuotes();
  469.               //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  470.               return $v_result;
  471.           }
  472.           $v_extract = false;
  473.       }
  474.       
  475.       // ----- Look for real extraction
  476.       if ($v_extract)
  477.       {
  478.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
  479.         // ----- Go to the file position
  480.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  481.         @rewind($this->zip_fd);
  482.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  483.         if (@fseek($this->zip_fd, $v_header['offset']))
  484.         {
  485.           // ----- Close the zip file
  486.           $this->privCloseFd();
  487.           $this->privSwapBackMagicQuotes();
  488.           // ----- Error log
  489.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  490.           // ----- Return
  491.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  492.           return PclZip::errorCode();
  493.         }
  494.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  495.         // ----- Look for extraction as string
  496.         if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
  497.           // ----- Extracting the file
  498.           $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
  499.           if ($v_result1 < 1) {
  500.             $this->privCloseFd();
  501.             $this->privSwapBackMagicQuotes();
  502.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  503.             return $v_result1;
  504.           }
  505.           // ----- Get the only interesting attributes
  506.           if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
  507.           {
  508.             // ----- Close the zip file
  509.             $this->privCloseFd();
  510.             $this->privSwapBackMagicQuotes();
  511.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  512.             return $v_result;
  513.           }
  514.           // ----- Set the file content
  515.           $p_file_list[$v_nb_extracted]['content'] = $v_string;
  516.           // ----- Next extracted file
  517.           $v_nb_extracted++;
  518.           
  519.           // ----- Look for user callback abort
  520.           if ($v_result1 == 2) {
  521.            break;
  522.           }
  523.         }
  524.         // ----- Look for extraction in standard output
  525.         elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
  526.         && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
  527.           // ----- Extracting the file in standard output
  528.           $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
  529.           if ($v_result1 < 1) {
  530.             $this->privCloseFd();
  531.             $this->privSwapBackMagicQuotes();
  532.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  533.             return $v_result1;
  534.           }
  535.           // ----- Get the only interesting attributes
  536.           if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
  537.             $this->privCloseFd();
  538.             $this->privSwapBackMagicQuotes();
  539.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  540.             return $v_result;
  541.           }
  542.           // ----- Look for user callback abort
  543.           if ($v_result1 == 2) {
  544.            break;
  545.           }
  546.         }
  547.         // ----- Look for normal extraction
  548.         else {
  549.           // ----- Extracting the file
  550.           $v_result1 = $this->privExtractFile($v_header,
  551.                                       $p_path, $p_remove_path,
  552.   $p_remove_all_path,
  553.   $p_options);
  554.           if ($v_result1 < 1) {
  555.             $this->privCloseFd();
  556.             $this->privSwapBackMagicQuotes();
  557.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  558.             return $v_result1;
  559.           }
  560.           // ----- Get the only interesting attributes
  561.           if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
  562.           {
  563.             // ----- Close the zip file
  564.             $this->privCloseFd();
  565.             $this->privSwapBackMagicQuotes();
  566.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  567.             return $v_result;
  568.           }
  569.           // ----- Look for user callback abort
  570.           if ($v_result1 == 2) {
  571.            break;
  572.           }
  573.         }
  574.       }
  575.     }
  576.     // ----- Close the zip file
  577.     $this->privCloseFd();
  578.     $this->privSwapBackMagicQuotes();
  579.     // ----- Return
  580.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  581.     return $v_result;
  582.   }
  583.   // --------------------------------------------------------------------------------
  584.   // --------------------------------------------------------------------------------
  585.   // Function : privExtractFile()
  586.   // Description :
  587.   // Parameters :
  588.   // Return Values :
  589.   //
  590.   // 1 : ... ?
  591.   // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
  592.   // --------------------------------------------------------------------------------
  593.   function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  594.   {
  595.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  596.     $v_result=1;
  597.     // ----- Read the file header
  598.     if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  599.     {
  600.       // ----- Return
  601.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  602.       return $v_result;
  603.     }
  604.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  605.     // ----- Check that the file header is coherent with $p_entry info
  606.     if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  607.         // TBC
  608.     }
  609.     // ----- Look for all path to remove
  610.     if ($p_remove_all_path == true) {
  611.         // ----- Look for folder entry that not need to be extracted
  612.         if (($p_entry['external']&0x00000010)==0x00000010) {
  613.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered");
  614.             $p_entry['status'] = "filtered";
  615.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  616.             return $v_result;
  617.         }
  618.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed");
  619.         // ----- Get the basename of the path
  620.         $p_entry['filename'] = basename($p_entry['filename']);
  621.     }
  622.     // ----- Look for path to remove
  623.     else if ($p_remove_path != "")
  624.     {
  625.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove");
  626.       if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
  627.       {
  628.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
  629.         // ----- Change the file status
  630.         $p_entry['status'] = "filtered";
  631.         // ----- Return
  632.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  633.         return $v_result;
  634.       }
  635.       $p_remove_path_size = strlen($p_remove_path);
  636.       if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
  637.       {
  638.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
  639.         // ----- Remove the path
  640.         $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
  641.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
  642.       }
  643.     }
  644.     // ----- Add the path
  645.     if ($p_path != '') {
  646.       $p_entry['filename'] = $p_path."/".$p_entry['filename'];
  647.     }
  648.     
  649.     // ----- Check a base_dir_restriction
  650.     if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
  651.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction");
  652.       $v_inclusion
  653.       = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
  654.                                 $p_entry['filename']); 
  655.       if ($v_inclusion == 0) {
  656.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction");
  657.         PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
  658.                      "Filename '".$p_entry['filename']."' is "
  659.  ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
  660.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  661.         return PclZip::errorCode();
  662.       }
  663.     }
  664.     // ----- Look for pre-extract callback
  665.     if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  666.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
  667.       // ----- Generate a local information
  668.       $v_local_header = array();
  669.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  670.       // ----- Call the callback
  671.       // Here I do not use call_user_func() because I need to send a reference to the
  672.       // header.
  673.       eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  674.       if ($v_result == 0) {
  675.         // ----- Change the file status
  676.         $p_entry['status'] = "skipped";
  677.         $v_result = 1;
  678.       }
  679.       
  680.       // ----- Look for abort result
  681.       if ($v_result == 2) {
  682.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  683.         // ----- This status is internal and will be changed in 'skipped'
  684.         $p_entry['status'] = "aborted";
  685.        $v_result = PCLZIP_ERR_USER_ABORTED;
  686.       }
  687.       // ----- Update the informations
  688.       // Only some fields can be modified
  689.       $p_entry['filename'] = $v_local_header['filename'];
  690.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
  691.     }
  692.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  693.     // ----- Look if extraction should be done
  694.     if ($p_entry['status'] == 'ok') {
  695.     // ----- Look for specific actions while the file exist
  696.     if (file_exists($p_entry['filename']))
  697.     {
  698.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
  699.       // ----- Look if file is a directory
  700.       if (is_dir($p_entry['filename']))
  701.       {
  702.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
  703.         // ----- Change the file status
  704.         $p_entry['status'] = "already_a_directory";
  705.         
  706.         // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  707.         // For historical reason first PclZip implementation does not stop
  708.         // when this kind of error occurs.
  709.         if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  710.     && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  711.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  712.             PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
  713.                      "Filename '".$p_entry['filename']."' is "
  714.  ."already used by an existing directory");
  715.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  716.             return PclZip::errorCode();
  717. }
  718.       }
  719.       // ----- Look if file is write protected
  720.       else if (!is_writeable($p_entry['filename']))
  721.       {
  722.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
  723.         // ----- Change the file status
  724.         $p_entry['status'] = "write_protected";
  725.         // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  726.         // For historical reason first PclZip implementation does not stop
  727.         // when this kind of error occurs.
  728.         if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  729.     && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  730.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  731.             PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  732.                      "Filename '".$p_entry['filename']."' exists "
  733.  ."and is write protected");
  734.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  735.             return PclZip::errorCode();
  736. }
  737.       }
  738.       // ----- Look if the extracted file is older
  739.       else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
  740.       {
  741.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
  742.         // ----- Change the file status
  743.         if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
  744.     && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
  745.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced");
  746. }
  747. else {
  748.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced");
  749.             $p_entry['status'] = "newer_exist";
  750.             // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  751.             // For historical reason first PclZip implementation does not stop
  752.             // when this kind of error occurs.
  753.             if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  754.         && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  755.                 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  756.                 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  757.              "Newer version of '".$p_entry['filename']."' exists "
  758.     ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
  759.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  760.                 return PclZip::errorCode();
  761.     }
  762. }
  763.       }
  764.       else {
  765.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
  766.       }
  767.     }
  768.     // ----- Check the directory availability and create it if necessary
  769.     else {
  770.       if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
  771.         $v_dir_to_check = $p_entry['filename'];
  772.       else if (!strstr($p_entry['filename'], "/"))
  773.         $v_dir_to_check = "";
  774.       else
  775.         $v_dir_to_check = dirname($p_entry['filename']);
  776.       if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
  777.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
  778.         // ----- Change the file status
  779.         $p_entry['status'] = "path_creation_fail";
  780.         // ----- Return
  781.         ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  782.         //return $v_result;
  783.         $v_result = 1;
  784.       }
  785.     }
  786.     }
  787.     // ----- Look if extraction should be done
  788.     if ($p_entry['status'] == 'ok') {
  789.       // ----- Do the extraction (if not a folder)
  790.       if (!(($p_entry['external']&0x00000010)==0x00000010))
  791.       {
  792.         // ----- Look for not compressed file
  793.         if ($p_entry['compression'] == 0) {
  794.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  795.   // ----- Opening destination file
  796.           if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
  797.           {
  798.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  799.             // ----- Change the file status
  800.             $p_entry['status'] = "write_error";
  801.             // ----- Return
  802.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  803.             return $v_result;
  804.           }
  805.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes");
  806.           // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  807.           $v_size = $p_entry['compressed_size'];
  808.           while ($v_size != 0)
  809.           {
  810.             $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  811.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
  812.             $v_buffer = @fread($this->zip_fd, $v_read_size);
  813.             /* Try to speed up the code
  814.             $v_binary_data = pack('a'.$v_read_size, $v_buffer);
  815.             @fwrite($v_dest_file, $v_binary_data, $v_read_size);
  816.             */
  817.             @fwrite($v_dest_file, $v_buffer, $v_read_size);            
  818.             $v_size -= $v_read_size;
  819.           }
  820.           // ----- Closing the destination file
  821.           fclose($v_dest_file);
  822.           // ----- Change the file mtime
  823.           touch($p_entry['filename'], $p_entry['mtime']);
  824.           
  825.         }
  826.         else {
  827.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")");
  828.           // ----- TBC
  829.           // Need to be finished
  830.           if (($p_entry['flag'] & 1) == 1) {
  831.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted");
  832.             /*
  833.               // ----- Read the encryption header
  834.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes");
  835.               $v_encryption_header = @fread($this->zip_fd, 12);
  836.               
  837.               // ----- Read the encrypted & compressed file in a buffer
  838.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes");
  839.               $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12);
  840.               
  841.               // ----- Decrypt the buffer
  842.               $this->privDecrypt($v_encryption_header, $v_buffer,
  843.                      $p_entry['compressed_size']-12, $p_entry['crc']);
  844.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'");
  845.               */
  846.           }
  847.           else {
  848.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes");
  849.               // ----- Read the compressed file in a buffer (one shot)
  850.               $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  851.           }
  852.           
  853.           // ----- Decompress the file
  854.           $v_file_content = @gzinflate($v_buffer);
  855.           unset($v_buffer);
  856.           if ($v_file_content === FALSE) {
  857.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file");
  858.             // ----- Change the file status
  859.             // TBC
  860.             $p_entry['status'] = "error";
  861.             
  862.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  863.             return $v_result;
  864.           }
  865.           
  866.           // ----- Opening destination file
  867.           if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  868.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  869.             // ----- Change the file status
  870.             $p_entry['status'] = "write_error";
  871.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  872.             return $v_result;
  873.           }
  874.           // ----- Write the uncompressed data
  875.           @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
  876.           unset($v_file_content);
  877.           // ----- Closing the destination file
  878.           @fclose($v_dest_file);
  879.           // ----- Change the file mtime
  880.           @touch($p_entry['filename'], $p_entry['mtime']);
  881.         }
  882.         // ----- Look for chmod option
  883.         if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
  884.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
  885.           // ----- Change the mode of the file
  886.           @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
  887.         }
  888.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  889.       }
  890.     }
  891. // ----- Change abort status
  892. if ($p_entry['status'] == "aborted") {
  893.       $p_entry['status'] = "skipped";
  894. }
  895.     // ----- Look for post-extract callback
  896.     elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  897.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
  898.       // ----- Generate a local information
  899.       $v_local_header = array();
  900.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  901.       // ----- Call the callback
  902.       // Here I do not use call_user_func() because I need to send a reference to the
  903.       // header.
  904.       eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  905.       // ----- Look for abort result
  906.       if ($v_result == 2) {
  907.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  908.        $v_result = PCLZIP_ERR_USER_ABORTED;
  909.       }
  910.     }
  911.     // ----- Return
  912.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  913.     return $v_result;
  914.   }
  915.   // --------------------------------------------------------------------------------
  916.   // --------------------------------------------------------------------------------
  917.   // Function : privExtractFileInOutput()
  918.   // Description :
  919.   // Parameters :
  920.   // Return Values :
  921.   // --------------------------------------------------------------------------------
  922.   function privExtractFileInOutput(&$p_entry, &$p_options)
  923.   {
  924.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', "");
  925.     $v_result=1;
  926.     // ----- Read the file header
  927.     if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
  928.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  929.       return $v_result;
  930.     }
  931.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  932.     // ----- Check that the file header is coherent with $p_entry info
  933.     if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  934.         // TBC
  935.     }
  936.     // ----- Look for pre-extract callback
  937.     if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  938.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
  939.       // ----- Generate a local information
  940.       $v_local_header = array();
  941.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  942.       // ----- Call the callback
  943.       // Here I do not use call_user_func() because I need to send a reference to the
  944.       // header.
  945.       eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  946.       if ($v_result == 0) {
  947.         // ----- Change the file status
  948.         $p_entry['status'] = "skipped";
  949.         $v_result = 1;
  950.       }
  951.       // ----- Look for abort result
  952.       if ($v_result == 2) {
  953.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  954.         // ----- This status is internal and will be changed in 'skipped'
  955.         $p_entry['status'] = "aborted";
  956.        $v_result = PCLZIP_ERR_USER_ABORTED;
  957.       }
  958.       // ----- Update the informations
  959.       // Only some fields can be modified
  960.       $p_entry['filename'] = $v_local_header['filename'];
  961.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
  962.     }
  963.     // ----- Trace
  964.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  965.     // ----- Look if extraction should be done
  966.     if ($p_entry['status'] == 'ok') {
  967.       // ----- Do the extraction (if not a folder)
  968.       if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  969.         // ----- Look for not compressed file
  970.         if ($p_entry['compressed_size'] == $p_entry['size']) {
  971.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  972.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  973.           // ----- Read the file in a buffer (one shot)
  974.           $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  975.           // ----- Send the file to the output
  976.           echo $v_buffer;
  977.           unset($v_buffer);
  978.         }
  979.         else {
  980.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
  981.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
  982.           // ----- Read the compressed file in a buffer (one shot)
  983.           $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  984.           
  985.           // ----- Decompress the file
  986.           $v_file_content = gzinflate($v_buffer);
  987.           unset($v_buffer);
  988.           // ----- Send the file to the output
  989.           echo $v_file_content;
  990.           unset($v_file_content);
  991.         }
  992.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  993.       }
  994.     }
  995. // ----- Change abort status
  996. if ($p_entry['status'] == "aborted") {
  997.       $p_entry['status'] = "skipped";
  998. }
  999.     // ----- Look for post-extract callback
  1000.     elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  1001.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
  1002.       // ----- Generate a local information
  1003.       $v_local_header = array();
  1004.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  1005.       // ----- Call the callback
  1006.       // Here I do not use call_user_func() because I need to send a reference to the
  1007.       // header.
  1008.       eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  1009.       // ----- Look for abort result
  1010.       if ($v_result == 2) {
  1011.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  1012.        $v_result = PCLZIP_ERR_USER_ABORTED;
  1013.       }
  1014.     }
  1015.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1016.     return $v_result;
  1017.   }
  1018.   // --------------------------------------------------------------------------------
  1019.   // --------------------------------------------------------------------------------
  1020.   // Function : privExtractFileAsString()
  1021.   // Description :
  1022.   // Parameters :
  1023.   // Return Values :
  1024.   // --------------------------------------------------------------------------------
  1025.   function privExtractFileAsString(&$p_entry, &$p_string)
  1026.   {
  1027.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
  1028.     $v_result=1;
  1029.     // ----- Read the file header
  1030.     $v_header = array();
  1031.     if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  1032.     {
  1033.       // ----- Return
  1034.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1035.       return $v_result;
  1036.     }
  1037.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  1038.     // ----- Check that the file header is coherent with $p_entry info
  1039.     if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  1040.         // TBC
  1041.     }
  1042.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  1043.     // ----- Do the extraction (if not a folder)
  1044.     if (!(($p_entry['external']&0x00000010)==0x00000010))
  1045.     {
  1046.       // ----- Look for not compressed file
  1047. //      if ($p_entry['compressed_size'] == $p_entry['size'])
  1048.       if ($p_entry['compression'] == 0) {
  1049.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  1050.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  1051.         // ----- Reading the file
  1052.         $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
  1053.       }
  1054.       else {
  1055.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')");
  1056.         // ----- Reading the file
  1057.         $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
  1058.         
  1059.         // ----- Decompress the file
  1060.         if (($p_string = @gzinflate($v_data)) === FALSE) {
  1061.             // TBC
  1062.         }
  1063.       }
  1064.       // ----- Trace
  1065.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  1066.     }
  1067.     else {
  1068.         // TBC : error : can not extract a folder in a string
  1069.     }
  1070.     // ----- Return
  1071.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1072.     return $v_result;
  1073.   }
  1074.   // --------------------------------------------------------------------------------
  1075.   // --------------------------------------------------------------------------------
  1076.   // Function : privReadFileHeader()
  1077.   // Description :
  1078.   // Parameters :
  1079.   // Return Values :
  1080.   // --------------------------------------------------------------------------------
  1081.   function privReadFileHeader(&$p_header)
  1082.   {
  1083.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
  1084.     $v_result=1;
  1085.     // ----- Read the 4 bytes signature
  1086.     $v_binary_data = @fread($this->zip_fd, 4);
  1087.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  1088.     $v_data = unpack('Vid', $v_binary_data);
  1089.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  1090.     // ----- Check signature
  1091.     if ($v_data['id'] != 0x04034b50)
  1092.     {
  1093.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
  1094.       // ----- Error log
  1095.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  1096.       // ----- Return
  1097.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1098.       return PclZip::errorCode();
  1099.     }
  1100.     // ----- Read the first 42 bytes of the header
  1101.     $v_binary_data = fread($this->zip_fd, 26);
  1102.     // ----- Look for invalid block size
  1103.     if (strlen($v_binary_data) != 26)
  1104.     {
  1105.       $p_header['filename'] = "";
  1106.       $p_header['status'] = "invalid_header";
  1107.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  1108.       // ----- Error log
  1109.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  1110.       // ----- Return
  1111.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1112.       return PclZip::errorCode();
  1113.     }
  1114.     // ----- Extract the values
  1115.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
  1116.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  1117.     $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
  1118.     // ----- Get filename
  1119.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
  1120.     $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
  1121.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : ''.$p_header['filename'].''');
  1122.     // ----- Get extra_fields
  1123.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
  1124.     if ($v_data['extra_len'] != 0) {
  1125.       $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
  1126.     }
  1127.     else {
  1128.       $p_header['extra'] = '';
  1129.     }
  1130.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : ''.bin2hex($p_header['extra']).''');
  1131.     // ----- Extract properties
  1132.     $p_header['version_extracted'] = $v_data['version'];
  1133.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') ''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).''');
  1134.     $p_header['compression'] = $v_data['compression'];
  1135.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : ''.$p_header['compression'].''');
  1136.     $p_header['size'] = $v_data['size'];
  1137.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : ''.$p_header['size'].''');
  1138.     $p_header['compressed_size'] = $v_data['compressed_size'];
  1139.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : ''.$p_header['compressed_size'].''');
  1140.     $p_header['crc'] = $v_data['crc'];
  1141.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : ''.sprintf("0x%X", $p_header['crc']).''');
  1142.     $p_header['flag'] = $v_data['flag'];
  1143.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : ''.$p_header['flag'].''');
  1144.     $p_header['filename_len'] = $v_data['filename_len'];
  1145.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : ''.$p_header['filename_len'].''');
  1146.     // ----- Recuperate date in UNIX format
  1147.     $p_header['mdate'] = $v_data['mdate'];
  1148.     $p_header['mtime'] = $v_data['mtime'];
  1149.     if ($p_header['mdate'] && $p_header['mtime'])
  1150.     {
  1151.       // ----- Extract time
  1152.       $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  1153.       $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  1154.       $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  1155.       // ----- Extract date
  1156.       $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  1157.       $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  1158.       $v_day = $p_header['mdate'] & 0x001F;
  1159.       // ----- Get UNIX date format
  1160.       $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  1161.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  1162.     }
  1163.     else
  1164.     {
  1165.       $p_header['mtime'] = time();
  1166.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  1167.     }
  1168.     // TBC
  1169.     //for(reset($v_data); $key = key($v_data); next($v_data)) {
  1170.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
  1171.     //}
  1172.     // ----- Set the stored filename
  1173.     $p_header['stored_filename'] = $p_header['filename'];
  1174.     // ----- Set the status field
  1175.     $p_header['status'] = "ok";
  1176.     // ----- Return
  1177.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1178.     return $v_result;
  1179.   }
  1180.   // --------------------------------------------------------------------------------
  1181.   // --------------------------------------------------------------------------------
  1182.   // Function : privReadCentralFileHeader()
  1183.   // Description :
  1184.   // Parameters :
  1185.   // Return Values :
  1186.   // --------------------------------------------------------------------------------
  1187.   function privReadCentralFileHeader(&$p_header)
  1188.   {
  1189.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
  1190.     $v_result=1;
  1191.     // ----- Read the 4 bytes signature
  1192.     $v_binary_data = @fread($this->zip_fd, 4);
  1193.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  1194.     $v_data = unpack('Vid', $v_binary_data);
  1195.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  1196.     // ----- Check signature
  1197.     if ($v_data['id'] != 0x02014b50)
  1198.     {
  1199.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
  1200.       // ----- Error log
  1201.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  1202.       // ----- Return
  1203.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1204.       return PclZip::errorCode();
  1205.     }
  1206.     // ----- Read the first 42 bytes of the header
  1207.     $v_binary_data = fread($this->zip_fd, 42);
  1208.     // ----- Look for invalid block size
  1209.     if (strlen($v_binary_data) != 42)
  1210.     {
  1211.       $p_header['filename'] = "";
  1212.       $p_header['status'] = "invalid_header";
  1213.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  1214.       // ----- Error log
  1215.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  1216.       // ----- Return
  1217.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1218.       return PclZip::errorCode();
  1219.     }
  1220.     // ----- Extract the values
  1221.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
  1222.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  1223.     $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
  1224.     // ----- Get filename
  1225.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
  1226.     if ($p_header['filename_len'] != 0)
  1227.       $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
  1228.     else
  1229.       $p_header['filename'] = '';
  1230.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : ''.$p_header['filename'].''');
  1231.     // ----- Get extra
  1232.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
  1233.     if ($p_header['extra_len'] != 0)
  1234.       $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
  1235.     else
  1236.       $p_header['extra'] = '';
  1237.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : ''.$p_header['extra'].''');
  1238.     // ----- Get comment
  1239.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
  1240.     if ($p_header['comment_len'] != 0)
  1241.       $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
  1242.     else
  1243.       $p_header['comment'] = '';
  1244.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : ''.$p_header['comment'].''');
  1245.     // ----- Extract properties
  1246.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : ''.($p_header['version']/10).'.'.($p_header['version']%10).''');
  1247.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).''');
  1248.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : ''.$p_header['size'].''');
  1249.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : ''.$p_header['compressed_size'].''');
  1250.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : ''.sprintf("0x%X", $p_header['crc']).''');
  1251.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : ''.$p_header['flag'].''');
  1252.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : ''.$p_header['offset'].''');
  1253.     // ----- Recuperate date in UNIX format
  1254.     //if ($p_header['mdate'] && $p_header['mtime'])
  1255.     // TBC : bug : this was ignoring time with 0/0/0
  1256.     if (1)
  1257.     {
  1258.       // ----- Extract time
  1259.       $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  1260.       $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  1261.       $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  1262.       // ----- Extract date
  1263.       $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  1264.       $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  1265.       $v_day = $p_header['mdate'] & 0x001F;
  1266.       // ----- Get UNIX date format
  1267.       $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  1268.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  1269.     }
  1270.     else
  1271.     {
  1272.       $p_header['mtime'] = time();
  1273.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : ''.date("d/m/y H:i:s", $p_header['mtime']).''');
  1274.     }
  1275.     // ----- Set the stored filename
  1276.     $p_header['stored_filename'] = $p_header['filename'];
  1277.     // ----- Set default status to ok
  1278.     $p_header['status'] = 'ok';
  1279.     // ----- Look if it is a directory
  1280.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
  1281.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')');
  1282.     if (substr($p_header['filename'], -1) == '/') {
  1283.       //$p_header['external'] = 0x41FF0010;
  1284.       $p_header['external'] = 0x00000010;
  1285.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : ''.sprintf("Ox%04X", $p_header['external']).''');
  1286.     }
  1287.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : ''.$p_header['filename'].''');
  1288.     // ----- Return
  1289.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1290.     return $v_result;
  1291.   }
  1292.   // --------------------------------------------------------------------------------
  1293.   // --------------------------------------------------------------------------------
  1294.   // Function : privCheckFileHeaders()
  1295.   // Description :
  1296.   // Parameters :
  1297.   // Return Values :
  1298.   //   1 on success,
  1299.   //   0 on error;
  1300.   // --------------------------------------------------------------------------------
  1301.   function privCheckFileHeaders(&$p_local_header, &$p_central_header)
  1302.   {
  1303.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", "");
  1304.     $v_result=1;
  1305. // ----- Check the static values
  1306. // TBC
  1307. if ($p_local_header['filename'] != $p_central_header['filename']) {
  1308.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed');
  1309. }
  1310. if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
  1311.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed');
  1312. }
  1313. if ($p_local_header['flag'] != $p_central_header['flag']) {
  1314.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed');
  1315. }
  1316. if ($p_local_header['compression'] != $p_central_header['compression']) {
  1317.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed');
  1318. }
  1319. if ($p_local_header['mtime'] != $p_central_header['mtime']) {
  1320.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed');
  1321. }
  1322. if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
  1323.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed');
  1324. }
  1325. // ----- Look for flag bit 3
  1326. if (($p_local_header['flag'] & 8) == 8) {
  1327.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !');
  1328.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header');
  1329.         $p_local_header['size'] = $p_central_header['size'];
  1330.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : ''.$p_local_header['size'].''');
  1331.         $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
  1332.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : ''.$p_local_header['compressed_size'].''');
  1333.         $p_local_header['crc'] = $p_central_header['crc'];
  1334.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : ''.sprintf("0x%X", $p_local_header['crc']).''');
  1335. }
  1336.     // ----- Return
  1337.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1338.     return $v_result;
  1339.   }
  1340.   // --------------------------------------------------------------------------------
  1341.   // --------------------------------------------------------------------------------
  1342.   // Function : privReadEndCentralDir()
  1343.   // Description :
  1344.   // Parameters :
  1345.   // Return Values :
  1346.   // --------------------------------------------------------------------------------
  1347.   function privReadEndCentralDir(&$p_central_dir)
  1348.   {
  1349.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
  1350.     $v_result=1;
  1351.     // ----- Go to the end of the zip file
  1352.     $v_size = filesize($this->zipname);
  1353.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
  1354.     @fseek($this->zip_fd, $v_size);
  1355.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : ''.ftell($this->zip_fd).''');
  1356.     if (@ftell($this->zip_fd) != $v_size)
  1357.     {
  1358.       // ----- Error log
  1359.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive ''.$this->zipname.''');
  1360.       // ----- Return
  1361.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1362.       return PclZip::errorCode();
  1363.     }
  1364.     // ----- First try : look if this is an archive with no commentaries (most of the time)
  1365.     // in this case the end of central dir is at 22 bytes of the file end
  1366.     $v_found = 0;
  1367.     if ($v_size > 26) {
  1368.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
  1369.       @fseek($this->zip_fd, $v_size-22);
  1370.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : ''.ftell($this->zip_fd).''');
  1371.       if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
  1372.       {
  1373.         // ----- Error log
  1374.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive ''.$this->zipname.''');
  1375.         // ----- Return
  1376.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1377.         return PclZip::errorCode();
  1378.       }
  1379.       // ----- Read for bytes
  1380.       $v_binary_data = @fread($this->zip_fd, 4);
  1381.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  1382.       $v_data = @unpack('Vid', $v_binary_data);
  1383.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  1384.       // ----- Check signature
  1385.       if ($v_data['id'] == 0x06054b50) {
  1386.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
  1387.         $v_found = 1;
  1388.       }
  1389.       $v_pos = ftell($this->zip_fd);
  1390.     }
  1391.     // ----- Go back to the maximum possible size of the Central Dir End Record
  1392.     if (!$v_found) {
  1393.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
  1394.       $v_maximum_size = 65557; // 0xFFFF + 22;
  1395.       if ($v_maximum_size > $v_size)
  1396.         $v_maximum_size = $v_size;
  1397.       @fseek($this->zip_fd, $v_size-$v_maximum_size);
  1398.       if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
  1399.       {
  1400.         // ----- Error log
  1401.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive ''.$this->zipname.''');
  1402.         // ----- Return
  1403.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1404.         return PclZip::errorCode();
  1405.       }
  1406.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : ''.ftell($this->zip_fd).''');
  1407.       // ----- Read byte per byte in order to find the signature
  1408.       $v_pos = ftell($this->zip_fd);
  1409.       $v_bytes = 0x00000000;
  1410.       while ($v_pos < $v_size)
  1411.       {
  1412.         // ----- Read a byte
  1413.         $v_byte = @fread($this->zip_fd, 1);
  1414.         // -----  Add the byte
  1415.         $v_bytes = ($v_bytes << 8) | Ord($v_byte);
  1416.         // ----- Compare the bytes
  1417.         if ($v_bytes == 0x504b0506)
  1418.         {
  1419.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : ''.ftell($this->zip_fd).''');
  1420.           $v_pos++;
  1421.           break;
  1422.         }
  1423.         $v_pos++;
  1424.       }
  1425.       // ----- Look if not found end of central dir
  1426.       if ($v_pos == $v_size)
  1427.       {
  1428.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
  1429.         // ----- Error log
  1430.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
  1431.         // ----- Return
  1432.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1433.         return PclZip::errorCode();
  1434.       }
  1435.     }
  1436.     // ----- Read the first 18 bytes of the header
  1437.     $v_binary_data = fread($this->zip_fd, 18);
  1438.     // ----- Look for invalid block size
  1439.     if (strlen($v_binary_data) != 18)
  1440.     {
  1441.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  1442.       // ----- Error log
  1443.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  1444.       // ----- Return
  1445.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1446.       return PclZip::errorCode();
  1447.     }
  1448.     // ----- Extract the values
  1449.     ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
  1450.     ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
  1451.     $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
  1452.     // ----- Check the global size
  1453.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
  1454.     if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
  1455.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
  1456.   // ----- Removed in release 2.2 see readme file
  1457.   // The check of the file size is a little too strict.
  1458.   // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
  1459.   // While decrypted, zip has training 0 bytes
  1460.   if (0) {
  1461.       // ----- Error log
  1462.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
  1463.                        'The central dir is not at the end of the archive.'
  1464.    .' Some trailing bytes exists after the archive.');
  1465.       // ----- Return
  1466.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1467.       return PclZip::errorCode();
  1468.   }
  1469.     }
  1470.     // ----- Get comment
  1471.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment size : ''.$v_data['comment_size'].''');
  1472.     if ($v_data['comment_size'] != 0) {
  1473.       $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
  1474.     }
  1475.     else
  1476.       $p_central_dir['comment'] = '';
  1477.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : ''.$p_central_dir['comment'].''');
  1478.     $p_central_dir['entries'] = $v_data['entries'];
  1479.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : ''.$p_central_dir['entries'].''');
  1480.     $p_central_dir['disk_entries'] = $v_data['disk_entries'];
  1481.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : ''.$p_central_dir['disk_entries'].''');
  1482.     $p_central_dir['offset'] = $v_data['offset'];
  1483.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : ''.$p_central_dir['offset'].''');
  1484.     $p_central_dir['size'] = $v_data['size'];
  1485.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : ''.$p_central_dir['size'].''');
  1486.     $p_central_dir['disk'] = $v_data['disk'];
  1487.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : ''.$p_central_dir['disk'].''');
  1488.     $p_central_dir['disk_start'] = $v_data['disk_start'];
  1489.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : ''.$p_central_dir['disk_start'].''');
  1490.     // TBC
  1491.     //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
  1492.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
  1493.     //}
  1494.     // ----- Return
  1495.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1496.     return $v_result;
  1497.   }
  1498.   // --------------------------------------------------------------------------------
  1499.   // --------------------------------------------------------------------------------
  1500.   // Function : privDeleteByRule()
  1501.   // Description :
  1502.   // Parameters :
  1503.   // Return Values :
  1504.   // --------------------------------------------------------------------------------
  1505.   function privDeleteByRule(&$p_result_list, &$p_options)
  1506.   {
  1507.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
  1508.     $v_result=1;
  1509.     $v_list_detail = array();
  1510.     // ----- Open the zip file
  1511.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1512.     if (($v_result=$this->privOpenFd('rb')) != 1)
  1513.     {
  1514.       // ----- Return
  1515.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1516.       return $v_result;
  1517.     }
  1518.     // ----- Read the central directory informations
  1519.     $v_central_dir = array();
  1520.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1521.     {
  1522.       $this->privCloseFd();
  1523.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1524.       return $v_result;
  1525.     }
  1526.     // ----- Go to beginning of File
  1527.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  1528.     @rewind($this->zip_fd);
  1529.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  1530.     // ----- Scan all the files
  1531.     // ----- Start at beginning of Central Dir
  1532.     $v_pos_entry = $v_central_dir['offset'];
  1533.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  1534.     @rewind($this->zip_fd);
  1535.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  1536.     if (@fseek($this->zip_fd, $v_pos_entry))
  1537.     {
  1538.       // ----- Close the zip file
  1539.       $this->privCloseFd();
  1540.       // ----- Error log
  1541.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  1542.       // ----- Return
  1543.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1544.       return PclZip::errorCode();
  1545.     }
  1546.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  1547.     // ----- Read each entry
  1548.     $v_header_list = array();
  1549.     $j_start = 0;
  1550.     for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  1551.     {
  1552.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
  1553.       // ----- Read the file header
  1554.       $v_header_list[$v_nb_extracted] = array();
  1555.       if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
  1556.       {
  1557.         // ----- Close the zip file
  1558.         $this->privCloseFd();
  1559.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1560.         return $v_result;
  1561.       }
  1562.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
  1563.       // ----- Store the index
  1564.       $v_header_list[$v_nb_extracted]['index'] = $i;
  1565.       // ----- Look for the specific extract rules
  1566.       $v_found = false;
  1567.       // ----- Look for extract by name rule
  1568.       if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
  1569.           && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  1570.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  1571.           // ----- Look if the filename is in the list
  1572.           for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
  1573.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  1574.               // ----- Look for a directory
  1575.               if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  1576.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  1577.                   // ----- Look if the directory is in the filename path
  1578.                   if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  1579.                       && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  1580.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  1581.                       $v_found = true;
  1582.                   }
  1583.                   elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
  1584.                           && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  1585.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
  1586.                       $v_found = true;
  1587.                   }
  1588.               }
  1589.               // ----- Look for a filename
  1590.               elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  1591.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  1592.                   $v_found = true;
  1593.               }
  1594.           }
  1595.       }
  1596.       // ----- Look for extract by ereg rule
  1597.       else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
  1598.                && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  1599.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  1600.           if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  1601.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  1602.               $v_found = true;
  1603.           }
  1604.       }
  1605.       // ----- Look for extract by preg rule
  1606.       else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
  1607.                && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  1608.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  1609.           if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  1610.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  1611.               $v_found = true;
  1612.           }
  1613.       }
  1614.       // ----- Look for extract by index rule
  1615.       else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  1616.                && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  1617.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  1618.           // ----- Look if the index is in the list
  1619.           for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
  1620.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
  1621.               if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  1622.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  1623.                   $v_found = true;
  1624.               }
  1625.               if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  1626.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  1627.                   $j_start = $j+1;
  1628.               }
  1629.               if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  1630.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  1631.                   break;
  1632.               }
  1633.           }
  1634.       }
  1635.       else {
  1636.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file");
  1637.        $v_found = true;
  1638.       }
  1639.       // ----- Look for deletion
  1640.       if ($v_found)
  1641.       {
  1642.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
  1643.         unset($v_header_list[$v_nb_extracted]);
  1644.       }
  1645.       else
  1646.       {
  1647.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
  1648.         $v_nb_extracted++;
  1649.       }
  1650.     }
  1651.     // ----- Look if something need to be deleted
  1652.     if ($v_nb_extracted > 0) {
  1653.         // ----- Creates a temporay file
  1654.         $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  1655.         // ----- Creates a temporary zip archive
  1656.         $v_temp_zip = new PclZip($v_zip_temp_name);
  1657.         // ----- Open the temporary zip file in write mode
  1658.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
  1659.         if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
  1660.             $this->privCloseFd();
  1661.             // ----- Return
  1662.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1663.             return $v_result;
  1664.         }
  1665.         // ----- Look which file need to be kept
  1666.         for ($i=0; $i<sizeof($v_header_list); $i++) {
  1667.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
  1668.             // ----- Calculate the position of the header
  1669.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
  1670.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  1671.             @rewind($this->zip_fd);
  1672.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  1673.             if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
  1674.                 // ----- Close the zip file
  1675.                 $this->privCloseFd();
  1676.                 $v_temp_zip->privCloseFd();
  1677.                 @unlink($v_zip_temp_name);
  1678.                 // ----- Error log
  1679.                 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  1680.                 // ----- Return
  1681.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1682.                 return PclZip::errorCode();
  1683.             }
  1684.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  1685.             // ----- Read the file header
  1686.             $v_local_header = array();
  1687.             if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
  1688.                 // ----- Close the zip file
  1689.                 $this->privCloseFd();
  1690.                 $v_temp_zip->privCloseFd();
  1691.                 @unlink($v_zip_temp_name);
  1692.                 // ----- Return
  1693.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1694.                 return $v_result;
  1695.             }
  1696.             
  1697.             // ----- Check that local file header is same as central file header
  1698.             if ($this->privCheckFileHeaders($v_local_header,
  1699.                                 $v_header_list[$i]) != 1) {
  1700.                 // TBC
  1701.             }
  1702.             unset($v_local_header);
  1703.             // ----- Write the file header
  1704.             if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
  1705.                 // ----- Close the zip file
  1706.                 $this->privCloseFd();
  1707.                 $v_temp_zip->privCloseFd();
  1708.                 @unlink($v_zip_temp_name);
  1709.                 // ----- Return
  1710.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1711.                 return $v_result;
  1712.             }
  1713.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
  1714.             // ----- Read/write the data block
  1715.             if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
  1716.                 // ----- Close the zip file
  1717.                 $this->privCloseFd();
  1718.                 $v_temp_zip->privCloseFd();
  1719.                 @unlink($v_zip_temp_name);
  1720.                 // ----- Return
  1721.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1722.                 return $v_result;
  1723.             }
  1724.         }
  1725.         // ----- Store the offset of the central dir
  1726.         $v_offset = @ftell($v_temp_zip->zip_fd);
  1727.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
  1728.         // ----- Re-Create the Central Dir files header
  1729.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
  1730.         for ($i=0; $i<sizeof($v_header_list); $i++) {
  1731.             // ----- Create the file header
  1732.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
  1733.             if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  1734.                 $v_temp_zip->privCloseFd();
  1735.                 $this->privCloseFd();
  1736.                 @unlink($v_zip_temp_name);
  1737.                 // ----- Return
  1738.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1739.                 return $v_result;
  1740.             }
  1741.             // ----- Transform the header to a 'usable' info
  1742.             $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  1743.         }
  1744.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
  1745.         // ----- Zip file comment
  1746.         $v_comment = '';
  1747.         if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  1748.           $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  1749.         }
  1750.         // ----- Calculate the size of the central header
  1751.         $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
  1752.         // ----- Create the central dir footer
  1753.         if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
  1754.             // ----- Reset the file list
  1755.             unset($v_header_list);
  1756.             $v_temp_zip->privCloseFd();
  1757.             $this->privCloseFd();
  1758.             @unlink($v_zip_temp_name);
  1759.             // ----- Return
  1760.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1761.             return $v_result;
  1762.         }
  1763.         // ----- Close
  1764.         $v_temp_zip->privCloseFd();
  1765.         $this->privCloseFd();
  1766.         // ----- Delete the zip file
  1767.         // TBC : I should test the result ...
  1768.         @unlink($this->zipname);
  1769.         // ----- Rename the temporary file
  1770.         // TBC : I should test the result ...
  1771.         //@rename($v_zip_temp_name, $this->zipname);
  1772.         PclZipUtilRename($v_zip_temp_name, $this->zipname);
  1773.     
  1774.         // ----- Destroy the temporary archive
  1775.         unset($v_temp_zip);
  1776.     }
  1777.     
  1778.     // ----- Remove every files : reset the file
  1779.     else if ($v_central_dir['entries'] != 0) {
  1780.         $this->privCloseFd();
  1781.         if (($v_result = $this->privOpenFd('wb')) != 1) {
  1782.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1783.           return $v_result;
  1784.         }
  1785.         if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
  1786.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1787.           return $v_result;
  1788.         }
  1789.         $this->privCloseFd();
  1790.     }
  1791.     // ----- Return
  1792.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1793.     return $v_result;
  1794.   }
  1795.   // --------------------------------------------------------------------------------
  1796.   // --------------------------------------------------------------------------------
  1797.   // Function : privDirCheck()
  1798.   // Description :
  1799.   //   Check if a directory exists, if not it creates it and all the parents directory
  1800.   //   which may be useful.
  1801.   // Parameters :
  1802.   //   $p_dir : Directory path to check.
  1803.   // Return Values :
  1804.   //    1 : OK
  1805.   //   -1 : Unable to create directory
  1806.   // --------------------------------------------------------------------------------
  1807.   function privDirCheck($p_dir, $p_is_dir=false)
  1808.   {
  1809.     $v_result = 1;
  1810.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
  1811.     // ----- Remove the final '/'
  1812.     if (($p_is_dir) && (substr($p_dir, -1)=='/'))
  1813.     {
  1814.       $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
  1815.     }
  1816.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
  1817.     // ----- Check the directory availability
  1818.     if ((is_dir($p_dir)) || ($p_dir == ""))
  1819.     {
  1820.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
  1821.       return 1;
  1822.     }
  1823.     // ----- Extract parent directory
  1824.     $p_parent_dir = dirname($p_dir);
  1825.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
  1826.     // ----- Just a check
  1827.     if ($p_parent_dir != $p_dir)
  1828.     {
  1829.       // ----- Look for parent directory
  1830.       if ($p_parent_dir != "")
  1831.       {
  1832.         if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
  1833.         {
  1834.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1835.           return $v_result;
  1836.         }
  1837.       }
  1838.     }
  1839.     // ----- Create the directory
  1840.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
  1841.     if (!@mkdir($p_dir, 0777))
  1842.     {
  1843.       // ----- Error log
  1844.       PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
  1845.       // ----- Return
  1846.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1847.       return PclZip::errorCode();
  1848.     }
  1849.     // ----- Return
  1850.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
  1851.     return $v_result;
  1852.   }
  1853.   // --------------------------------------------------------------------------------
  1854.   // --------------------------------------------------------------------------------
  1855.   // Function : privMerge()
  1856.   // Description :
  1857.   //   If $p_archive_to_add does not exist, the function exit with a success result.
  1858.   // Parameters :
  1859.   // Return Values :
  1860.   // --------------------------------------------------------------------------------
  1861.   function privMerge(&$p_archive_to_add)
  1862.   {
  1863.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
  1864.     $v_result=1;
  1865.     // ----- Look if the archive_to_add exists
  1866.     if (!is_file($p_archive_to_add->zipname))
  1867.     {
  1868.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
  1869.       // ----- Nothing to merge, so merge is a success
  1870.       $v_result = 1;
  1871.       // ----- Return
  1872.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1873.       return $v_result;
  1874.     }
  1875.     // ----- Look if the archive exists
  1876.     if (!is_file($this->zipname))
  1877.     {
  1878.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
  1879.       // ----- Do a duplicate
  1880.       $v_result = $this->privDuplicate($p_archive_to_add->zipname);
  1881.       // ----- Return
  1882.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1883.       return $v_result;
  1884.     }
  1885.     // ----- Open the zip file
  1886.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1887.     if (($v_result=$this->privOpenFd('rb')) != 1)
  1888.     {
  1889.       // ----- Return
  1890.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1891.       return $v_result;
  1892.     }
  1893.     // ----- Read the central directory informations
  1894.     $v_central_dir = array();
  1895.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1896.     {
  1897.       $this->privCloseFd();
  1898.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1899.       return $v_result;
  1900.     }
  1901.     // ----- Go to beginning of File
  1902.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  1903.     @rewind($this->zip_fd);
  1904.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  1905.     // ----- Open the archive_to_add file
  1906.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
  1907.     if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
  1908.     {
  1909.       $this->privCloseFd();
  1910.       // ----- Return
  1911.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1912.       return $v_result;
  1913.     }
  1914.     // ----- Read the central directory informations
  1915.     $v_central_dir_to_add = array();
  1916.     if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
  1917.     {
  1918.       $this->privCloseFd();
  1919.       $p_archive_to_add->privCloseFd();
  1920.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1921.       return $v_result;
  1922.     }
  1923.     // ----- Go to beginning of File
  1924.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  1925.     @rewind($p_archive_to_add->zip_fd);
  1926.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  1927.     // ----- Creates a temporay file
  1928.     $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  1929.     // ----- Open the temporary file in write mode
  1930.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1931.     if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  1932.     {
  1933.       $this->privCloseFd();
  1934.       $p_archive_to_add->privCloseFd();
  1935.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file ''.$v_zip_temp_name.'' in binary write mode');
  1936.       // ----- Return
  1937.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1938.       return PclZip::errorCode();
  1939.     }
  1940.     // ----- Copy the files from the archive to the temporary file
  1941.     // TBC : Here I should better append the file and go back to erase the central dir
  1942.     $v_size = $v_central_dir['offset'];
  1943.     while ($v_size != 0)
  1944.     {
  1945.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1946.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1947.       $v_buffer = fread($this->zip_fd, $v_read_size);
  1948.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  1949.       $v_size -= $v_read_size;
  1950.     }
  1951.     // ----- Copy the files from the archive_to_add into the temporary file
  1952.     $v_size = $v_central_dir_to_add['offset'];
  1953.     while ($v_size != 0)
  1954.     {
  1955.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1956.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1957.       $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
  1958.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  1959.       $v_size -= $v_read_size;
  1960.     }
  1961.     // ----- Store the offset of the central dir
  1962.     $v_offset = @ftell($v_zip_temp_fd);
  1963.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
  1964.     // ----- Copy the block of file headers from the old archive
  1965.     $v_size = $v_central_dir['size'];
  1966.     while ($v_size != 0)
  1967.     {
  1968.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1969.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1970.       $v_buffer = @fread($this->zip_fd, $v_read_size);
  1971.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  1972.       $v_size -= $v_read_size;
  1973.     }
  1974.     // ----- Copy the block of file headers from the archive_to_add
  1975.     $v_size = $v_central_dir_to_add['size'];
  1976.     while ($v_size != 0)
  1977.     {
  1978.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1979.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1980.       $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
  1981.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  1982.       $v_size -= $v_read_size;
  1983.     }
  1984.     // ----- Merge the file comments
  1985.     $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
  1986.     // ----- Calculate the size of the (new) central header
  1987.     $v_size = @ftell($v_zip_temp_fd)-$v_offset;
  1988.     // ----- Swap the file descriptor
  1989.     // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  1990.     // the following methods on the temporary fil and not the real archive fd
  1991.     $v_swap = $this->zip_fd;
  1992.     $this->zip_fd = $v_zip_temp_fd;
  1993.     $v_zip_temp_fd = $v_swap;
  1994.     // ----- Create the central dir footer
  1995.     if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
  1996.     {
  1997.       $this->privCloseFd();
  1998.       $p_archive_to_add->privCloseFd();
  1999.       @fclose($v_zip_temp_fd);
  2000.       $this->zip_fd = null;
  2001.       // ----- Reset the file list
  2002.       unset($v_header_list);
  2003.       // ----- Return
  2004.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2005.       return $v_result;
  2006.     }
  2007.     // ----- Swap back the file descriptor
  2008.     $v_swap = $this->zip_fd;
  2009.     $this->zip_fd = $v_zip_temp_fd;
  2010.     $v_zip_temp_fd = $v_swap;
  2011.     // ----- Close
  2012.     $this->privCloseFd();
  2013.     $p_archive_to_add->privCloseFd();
  2014.     // ----- Close the temporary file
  2015.     @fclose($v_zip_temp_fd);
  2016.     // ----- Delete the zip file
  2017.     // TBC : I should test the result ...
  2018.     @unlink($this->zipname);
  2019.     // ----- Rename the temporary file
  2020.     // TBC : I should test the result ...
  2021.     //@rename($v_zip_temp_name, $this->zipname);
  2022.     PclZipUtilRename($v_zip_temp_name, $this->zipname);
  2023.     // ----- Return
  2024.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2025.     return $v_result;
  2026.   }
  2027.   // --------------------------------------------------------------------------------
  2028.   // --------------------------------------------------------------------------------
  2029.   // Function : privDuplicate()
  2030.   // Description :
  2031.   // Parameters :
  2032.   // Return Values :
  2033.   // --------------------------------------------------------------------------------
  2034.   function privDuplicate($p_archive_filename)
  2035.   {
  2036.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
  2037.     $v_result=1;
  2038.     // ----- Look if the $p_archive_filename exists
  2039.     if (!is_file($p_archive_filename))
  2040.     {
  2041.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
  2042.       // ----- Nothing to duplicate, so duplicate is a success.
  2043.       $v_result = 1;
  2044.       // ----- Return
  2045.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2046.       return $v_result;
  2047.     }
  2048.     // ----- Open the zip file
  2049.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2050.     if (($v_result=$this->privOpenFd('wb')) != 1)
  2051.     {
  2052.       // ----- Return
  2053.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2054.       return $v_result;
  2055.     }
  2056.     // ----- Open the temporary file in write mode
  2057.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2058.     if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
  2059.     {
  2060.       $this->privCloseFd();
  2061.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file ''.$p_archive_filename.'' in binary write mode');
  2062.       // ----- Return
  2063.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2064.       return PclZip::errorCode();
  2065.     }
  2066.     // ----- Copy the files from the archive to the temporary file
  2067.     // TBC : Here I should better append the file and go back to erase the central dir
  2068.     $v_size = filesize($p_archive_filename);
  2069.     while ($v_size != 0)
  2070.     {
  2071.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2072.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
  2073.       $v_buffer = fread($v_zip_temp_fd, $v_read_size);
  2074.       @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2075.       $v_size -= $v_read_size;
  2076.     }
  2077.     // ----- Close
  2078.     $this->privCloseFd();
  2079.     // ----- Close the temporary file
  2080.     @fclose($v_zip_temp_fd);
  2081.     // ----- Return
  2082.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2083.     return $v_result;
  2084.   }
  2085.   // --------------------------------------------------------------------------------
  2086.   // --------------------------------------------------------------------------------
  2087.   // Function : privErrorLog()
  2088.   // Description :
  2089.   // Parameters :
  2090.   // --------------------------------------------------------------------------------
  2091.   function privErrorLog($p_error_code=0, $p_error_string='')
  2092.   {
  2093.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  2094.       PclError($p_error_code, $p_error_string);
  2095.     }
  2096.     else {
  2097.       $this->error_code = $p_error_code;
  2098.       $this->error_string = $p_error_string;
  2099.     }
  2100.   }
  2101.   // --------------------------------------------------------------------------------
  2102.   // --------------------------------------------------------------------------------
  2103.   // Function : privErrorReset()
  2104.   // Description :
  2105.   // Parameters :
  2106.   // --------------------------------------------------------------------------------
  2107.   function privErrorReset()
  2108.   {
  2109.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  2110.       PclErrorReset();
  2111.     }
  2112.     else {
  2113.       $this->error_code = 0;
  2114.       $this->error_string = '';
  2115.     }
  2116.   }
  2117.   // --------------------------------------------------------------------------------
  2118.   // --------------------------------------------------------------------------------
  2119.   // Function : privDecrypt()
  2120.   // Description :
  2121.   // Parameters :
  2122.   // Return Values :
  2123.   // --------------------------------------------------------------------------------
  2124.   function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
  2125.   {
  2126.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size."");
  2127.     $v_result=1;
  2128.     
  2129.     // ----- To Be Modified ;-)
  2130.     $v_pwd = "test";
  2131.     
  2132.     $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
  2133.                                  $p_crc, $v_pwd);
  2134.     
  2135.     // ----- Return
  2136.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2137.     return $v_result;
  2138.   }
  2139.   // --------------------------------------------------------------------------------
  2140.   // --------------------------------------------------------------------------------
  2141.   // Function : privDisableMagicQuotes()
  2142.   // Description :
  2143.   // Parameters :
  2144.   // Return Values :
  2145.   // --------------------------------------------------------------------------------
  2146.   function privDisableMagicQuotes()
  2147.   {
  2148.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', "");
  2149.     $v_result=1;
  2150.     // ----- Look if function exists
  2151.     if (   (!function_exists("get_magic_quotes_runtime"))
  2152.     || (!function_exists("set_magic_quotes_runtime"))) {
  2153.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
  2154.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2155.       return $v_result;
  2156. }
  2157.     // ----- Look if already done
  2158.     if ($this->magic_quotes_status != -1) {
  2159.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled");
  2160.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2161.       return $v_result;
  2162. }
  2163. // ----- Get and memorize the magic_quote value
  2164. $this->magic_quotes_status = @get_magic_quotes_runtime();
  2165.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'");
  2166. // ----- Disable magic_quotes
  2167. if ($this->magic_quotes_status == 1) {
  2168.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes");
  2169.   @set_magic_quotes_runtime(0);
  2170. }
  2171.     // ----- Return
  2172.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2173.     return $v_result;
  2174.   }
  2175.   // --------------------------------------------------------------------------------
  2176.   // --------------------------------------------------------------------------------
  2177.   // Function : privSwapBackMagicQuotes()
  2178.   // Description :
  2179.   // Parameters :
  2180.   // Return Values :
  2181.   // --------------------------------------------------------------------------------
  2182.   function privSwapBackMagicQuotes()
  2183.   {
  2184.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', "");
  2185.     $v_result=1;
  2186.     // ----- Look if function exists
  2187.     if (   (!function_exists("get_magic_quotes_runtime"))
  2188.     || (!function_exists("set_magic_quotes_runtime"))) {
  2189.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
  2190.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2191.       return $v_result;
  2192. }
  2193.     // ----- Look if something to do
  2194.     if ($this->magic_quotes_status != -1) {
  2195.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified");
  2196.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2197.       return $v_result;
  2198. }
  2199. // ----- Swap back magic_quotes
  2200. if ($this->magic_quotes_status == 1) {
  2201.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes");
  2202.      @set_magic_quotes_runtime($this->magic_quotes_status);
  2203. }
  2204.     // ----- Return
  2205.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2206.     return $v_result;
  2207.   }
  2208.   // --------------------------------------------------------------------------------
  2209.   }
  2210.   // End of class
  2211.   // --------------------------------------------------------------------------------
  2212.   // --------------------------------------------------------------------------------
  2213.   // Function : PclZipUtilPathReduction()
  2214.   // Description :
  2215.   // Parameters :
  2216.   // Return Values :
  2217.   // --------------------------------------------------------------------------------
  2218.   function PclZipUtilPathReduction($p_dir)
  2219.   {
  2220.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
  2221.     $v_result = "";
  2222.     // ----- Look for not empty path
  2223.     if ($p_dir != "") {
  2224.       // ----- Explode path by directory names
  2225.       $v_list = explode("/", $p_dir);
  2226.       // ----- Study directories from last to first
  2227.       $v_skip = 0;
  2228.       for ($i=sizeof($v_list)-1; $i>=0; $i--) {
  2229.         // ----- Look for current path
  2230.         if ($v_list[$i] == ".") {
  2231.           // ----- Ignore this directory
  2232.           // Should be the first $i=0, but no check is done
  2233.         }
  2234.         else if ($v_list[$i] == "..") {
  2235.   $v_skip++;
  2236.         }
  2237.         else if ($v_list[$i] == "") {
  2238.   // ----- First '/' i.e. root slash
  2239.   if ($i == 0) {
  2240.             $v_result = "/".$v_result;
  2241.     if ($v_skip > 0) {
  2242.         // ----- It is an invalid path, so the path is not modified
  2243.         // TBC
  2244.         $v_result = $p_dir;
  2245.                 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged");
  2246.                 $v_skip = 0;
  2247.     }
  2248.   }
  2249.   // ----- Last '/' i.e. indicates a directory
  2250.   else if ($i == (sizeof($v_list)-1)) {
  2251.             $v_result = $v_list[$i];
  2252.   }
  2253.   // ----- Double '/' inside the path
  2254.   else {
  2255.             // ----- Ignore only the double '//' in path,
  2256.             // but not the first and last '/'
  2257.   }
  2258.         }
  2259.         else {
  2260.   // ----- Look for item to skip
  2261.   if ($v_skip > 0) {
  2262.     $v_skip--;
  2263.   }
  2264.   else {
  2265.             $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  2266.   }
  2267.         }
  2268.       }
  2269.       
  2270.       // ----- Look for skip
  2271.       if ($v_skip > 0) {
  2272.         while ($v_skip > 0) {
  2273.             $v_result = '../'.$v_result;
  2274.             $v_skip--;
  2275.         }
  2276.       }
  2277.     }
  2278.     // ----- Return
  2279.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2280.     return $v_result;
  2281.   }
  2282.   // --------------------------------------------------------------------------------
  2283.   // --------------------------------------------------------------------------------
  2284.   // Function : PclZipUtilPathInclusion()
  2285.   // Description :
  2286.   //   This function indicates if the path $p_path is under the $p_dir tree. Or,
  2287.   //   said in an other way, if the file or sub-dir $p_path is inside the dir
  2288.   //   $p_dir.
  2289.   //   The function indicates also if the path is exactly the same as the dir.
  2290.   //   This function supports path with duplicated '/' like '//', but does not
  2291.   //   support '.' or '..' statements.
  2292.   // Parameters :
  2293.   // Return Values :
  2294.   //   0 if $p_path is not inside directory $p_dir
  2295.   //   1 if $p_path is inside directory $p_dir
  2296.   //   2 if $p_path is exactly the same as $p_dir
  2297.   // --------------------------------------------------------------------------------
  2298.   function PclZipUtilPathInclusion($p_dir, $p_path)
  2299.   {
  2300.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
  2301.     $v_result = 1;
  2302.     
  2303.     // ----- Look for path beginning by ./
  2304.     if (   ($p_dir == '.')
  2305.         || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
  2306.       $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
  2307.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'");
  2308.     }
  2309.     if (   ($p_path == '.')
  2310.         || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
  2311.       $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
  2312.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'");
  2313.     }
  2314.     // ----- Explode dir and path by directory separator
  2315.     $v_list_dir = explode("/", $p_dir);
  2316.     $v_list_dir_size = sizeof($v_list_dir);
  2317.     $v_list_path = explode("/", $p_path);
  2318.     $v_list_path_size = sizeof($v_list_path);
  2319.     // ----- Study directories paths
  2320.     $i = 0;
  2321.     $j = 0;
  2322.     while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
  2323.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
  2324.       // ----- Look for empty dir (path reduction)
  2325.       if ($v_list_dir[$i] == '') {
  2326.         $i++;
  2327.         continue;
  2328.       }
  2329.       if ($v_list_path[$j] == '') {
  2330.         $j++;
  2331.         continue;
  2332.       }
  2333.       // ----- Compare the items
  2334.       if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
  2335.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
  2336.         $v_result = 0;
  2337.       }
  2338.       // ----- Next items
  2339.       $i++;
  2340.       $j++;
  2341.     }
  2342.     // ----- Look if everything seems to be the same
  2343.     if ($v_result) {
  2344.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
  2345.       // ----- Skip all the empty items
  2346.       while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
  2347.       while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
  2348.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'");
  2349.       if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
  2350.         // ----- There are exactly the same
  2351.         $v_result = 2;
  2352.       }
  2353.       else if ($i < $v_list_dir_size) {
  2354.         // ----- The path is shorter than the dir
  2355.         $v_result = 0;
  2356.       }
  2357.     }
  2358.     // ----- Return
  2359.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2360.     return $v_result;
  2361.   }
  2362.   // --------------------------------------------------------------------------------
  2363.   // --------------------------------------------------------------------------------
  2364.   // Function : PclZipUtilCopyBlock()
  2365.   // Description :
  2366.   // Parameters :
  2367.   //   $p_mode : read/write compression mode
  2368.   //             0 : src & dest normal
  2369.   //             1 : src gzip, dest normal
  2370.   //             2 : src normal, dest gzip
  2371.   //             3 : src & dest gzip
  2372.   // Return Values :
  2373.   // --------------------------------------------------------------------------------
  2374.   function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
  2375.   {
  2376.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
  2377.     $v_result = 1;
  2378.     if ($p_mode==0)
  2379.     {
  2380.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
  2381.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
  2382.       while ($p_size != 0)
  2383.       {
  2384.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  2385.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2386.         $v_buffer = @fread($p_src, $v_read_size);
  2387.         @fwrite($p_dest, $v_buffer, $v_read_size);
  2388.         $p_size -= $v_read_size;
  2389.       }
  2390.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
  2391.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
  2392.     }
  2393.     else if ($p_mode==1)
  2394.     {
  2395.       while ($p_size != 0)
  2396.       {
  2397.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  2398.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2399.         $v_buffer = @gzread($p_src, $v_read_size);
  2400.         @fwrite($p_dest, $v_buffer, $v_read_size);
  2401.         $p_size -= $v_read_size;
  2402.       }
  2403.     }
  2404.     else if ($p_mode==2)
  2405.     {
  2406.       while ($p_size != 0)
  2407.       {
  2408.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  2409.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2410.         $v_buffer = @fread($p_src, $v_read_size);
  2411.         @gzwrite($p_dest, $v_buffer, $v_read_size);
  2412.         $p_size -= $v_read_size;
  2413.       }
  2414.     }
  2415.     else if ($p_mode==3)
  2416.     {
  2417.       while ($p_size != 0)
  2418.       {
  2419.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  2420.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2421.         $v_buffer = @gzread($p_src, $v_read_size);
  2422.         @gzwrite($p_dest, $v_buffer, $v_read_size);
  2423.         $p_size -= $v_read_size;
  2424.       }
  2425.     }
  2426.     // ----- Return
  2427.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2428.     return $v_result;
  2429.   }
  2430.   // --------------------------------------------------------------------------------
  2431.   // --------------------------------------------------------------------------------
  2432.   // Function : PclZipUtilRename()
  2433.   // Description :
  2434.   //   This function tries to do a simple rename() function. If it fails, it
  2435.   //   tries to copy the $p_src file in a new $p_dest file and then unlink the
  2436.   //   first one.
  2437.   // Parameters :
  2438.   //   $p_src : Old filename
  2439.   //   $p_dest : New filename
  2440.   // Return Values :
  2441.   //   1 on success, 0 on failure.
  2442.   // --------------------------------------------------------------------------------
  2443.   function PclZipUtilRename($p_src, $p_dest)
  2444.   {
  2445.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
  2446.     $v_result = 1;
  2447.     // ----- Try to rename the files
  2448.     if (!@rename($p_src, $p_dest)) {
  2449.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
  2450.       // ----- Try to copy & unlink the src
  2451.       if (!@copy($p_src, $p_dest)) {
  2452.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
  2453.         $v_result = 0;
  2454.       }
  2455.       else if (!@unlink($p_src)) {
  2456.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
  2457.         $v_result = 0;
  2458.       }
  2459.     }
  2460.     // ----- Return
  2461.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2462.     return $v_result;
  2463.   }
  2464.   // --------------------------------------------------------------------------------
  2465.   // --------------------------------------------------------------------------------
  2466.   // Function : PclZipUtilOptionText()
  2467.   // Description :
  2468.   //   Translate option value in text. Mainly for debug purpose.
  2469.   // Parameters :
  2470.   //   $p_option : the option value.
  2471.   // Return Values :
  2472.   //   The option text value.
  2473.   // --------------------------------------------------------------------------------
  2474.   function PclZipUtilOptionText($p_option)
  2475.   {
  2476.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
  2477.     
  2478.     $v_list = get_defined_constants();
  2479.     for (reset($v_list); $v_key = key($v_list); next($v_list)) {
  2480.   $v_prefix = substr($v_key, 0, 10);
  2481.   if ((   ($v_prefix == 'PCLZIP_OPT')
  2482.          || ($v_prefix == 'PCLZIP_CB_')
  2483.          || ($v_prefix == 'PCLZIP_ATT'))
  2484.       && ($v_list[$v_key] == $p_option)) {
  2485.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key);
  2486.           return $v_key;
  2487.     }
  2488.     }
  2489.     
  2490.     $v_result = 'Unknown';
  2491.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2492.     return $v_result;
  2493.   }
  2494.   // --------------------------------------------------------------------------------
  2495.   // --------------------------------------------------------------------------------
  2496.   // Function : PclZipUtilTranslateWinPath()
  2497.   // Description :
  2498.   //   Translate windows path by replacing '' by '/' and optionally removing
  2499.   //   drive letter.
  2500.   // Parameters :
  2501.   //   $p_path : path to translate.
  2502.   //   $p_remove_disk_letter : true | false
  2503.   // Return Values :
  2504.   //   The path translated.
  2505.   // --------------------------------------------------------------------------------
  2506.   function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
  2507.   {
  2508.     if (stristr(php_uname(), 'windows')) {
  2509.       // ----- Look for potential disk letter
  2510.       if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
  2511.           $p_path = substr($p_path, $v_position+1);
  2512.       }
  2513.       // ----- Change potential windows directory separator
  2514.       if ((strpos($p_path, '\') > 0) || (substr($p_path, 0,1) == '\')) {
  2515.           $p_path = strtr($p_path, '\', '/');
  2516.       }
  2517.     }
  2518.     return $p_path;
  2519.   }
  2520.   // --------------------------------------------------------------------------------
  2521. ?>