Beispiel #1
0
 /**
  * Writes an encrypted block to the archive
  * @param resource $fp The file pointer resource of the file to write to
  * @param string $data Raw binary data to encrypt and write
  */
 private function _writeEncryptedBlock(&$fp, $data)
 {
     $decryptedSize = akstringlen($data);
     $data = AEUtilEncrypt::AESEncryptCBC($data, $this->password, 128);
     $encryptedSize = akstringlen($data);
     // Do we have enough space to store the 8 byte header?
     if ($this->_useSplitZIP) {
         // Compare to free part space
         clearstatcache();
         $current_part_size = @filesize($this->_dataFileName);
         $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
         if ($free_space <= 8) {
             @fclose($fp);
             // Not enough space on current part, create new part
             if (!$this->_createNewPart()) {
                 $this->setError('Could not create new JPS part file ' . basename($this->_dataFileName));
                 return false;
             }
             // Open data file for output
             $fp = @fopen($this->_dataFileName, "ab");
             if ($fp === false) {
                 $this->setError("Could not open archive file '{$this->_dataFileName}' for append!");
                 return;
             }
         }
     } else {
         $free_space = $encryptedSize + 8;
     }
     // Write the header
     $this->_fwrite($fp, pack('V', $encryptedSize) . pack('V', $decryptedSize));
     if ($this->getError()) {
         return;
     }
     $free_space -= 8;
     // Do we have enough space to write the data in one part?
     if ($free_space >= $encryptedSize) {
         $this->_fwrite($fp, $data);
         if ($this->getError()) {
             return;
         }
     } else {
         // Split between parts - Write first part
         $firstPart = substr($data, 0, $free_space);
         $secondPart = substr($data, $free_space);
         if (md5($firstPart . $secondPart) != md5($data)) {
             die('DEBUG -- Multibyte character problems!');
             die;
         }
         $this->_fwrite($fp, $firstPart, $free_space);
         if ($this->getError()) {
             @fclose($fp);
             return;
         }
         // Create new part
         if (!$this->_createNewPart()) {
             // Die if we couldn't create the new part
             $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
             @fclose($fp);
             return false;
         } else {
             // Close the old data file
             @fclose($fp);
             // Open data file for output
             $fp = @fopen($this->_dataFileName, "ab");
             if ($fp === false) {
                 $this->setError("Could not open archive file {$this->_dataFileName} for append!");
                 return false;
             }
         }
         // Write the rest of the data
         $this->_fwrite($fp, $secondPart, $encryptedSize - $free_space);
     }
 }
Beispiel #2
0
 /**
  * The most basic file transaction: add a single entry (file or directory) to
  * the archive.
  *
  * @param bool $isVirtual If true, the next parameter contains file data instead of a file name
  * @param string $sourceNameOrData Absolute file name to read data from or the file data itself is $isVirtual is true
  * @param string $targetName The (relative) file name under which to store the file in the archive
  * @return True on success, false otherwise
  * @since 1.2.1
  * @access protected
  * @abstract
  */
 protected function _addFile($isVirtual, &$sourceNameOrData, $targetName)
 {
     static $configuration;
     $isDir = false;
     $isSymlink = false;
     if (is_null($isVirtual)) {
         $isVirtual = false;
     }
     $compressionMethod = 0;
     if ($isVirtual) {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "-- Adding {$targetName} to archive (virtual data)");
     } else {
         AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "-- Adding {$targetName} to archive (source: {$sourceNameOrData})");
     }
     if (!$configuration) {
         $configuration =& AEFactory::getConfiguration();
     }
     $timer =& AEFactory::getTimer();
     // Initialize archive file pointer
     $fp = null;
     // Initialize inode change timestamp
     $filectime = 0;
     if (!$configuration->get('volatile.engine.archiver.processingfile', false)) {
         // Uncache data -- WHY DO THAT?!
         /**
         			$configuration->set('volatile.engine.archiver.sourceNameOrData', null);
         			$configuration->set('volatile.engine.archiver.unc_len', null);
         			$configuration->set('volatile.engine.archiver.resume', null);
         			$configuration->set('volatile.engine.archiver.processingfile',false);
         			/**/
         // See if it's a directory
         $isDir = $isVirtual ? false : is_dir($sourceNameOrData);
         // See if it's a symlink (w/out dereference)
         $isSymlink = false;
         if ($this->_symlink_store_target && !$isVirtual) {
             $isSymlink = is_link($sourceNameOrData);
         }
         // Get real size before compression
         if ($isVirtual) {
             $fileSize = akstringlen($sourceNameOrData);
             $filectime = time();
         } else {
             if ($isSymlink) {
                 $fileSize = akstringlen(@readlink($sourceNameOrData));
             } else {
                 // Is the file readable?
                 if (!is_readable($sourceNameOrData) && !$isDir) {
                     // Unreadable files won't be recorded in the archive file
                     $this->setWarning('Unreadable file ' . $sourceNameOrData . '. Check permissions');
                     return false;
                 }
                 // Get the filesize
                 $fileSize = $isDir ? 0 : @filesize($sourceNameOrData);
                 $filectime = $isDir ? 0 : @filemtime($sourceNameOrData);
             }
         }
         // Decide if we will compress
         if ($isDir || $isSymlink) {
             $compressionMethod = 0;
             // don't compress directories...
         } else {
             // Do we have plenty of memory left?
             $memLimit = ini_get("memory_limit");
             if (strstr($memLimit, 'M')) {
                 $memLimit = (int) $memLimit * 1048576;
             } elseif (strstr($totalRAM, 'K')) {
                 $memLimit = (int) $memLimit * 1024;
             } elseif (strstr($memLimit, 'G')) {
                 $memLimit = (int) $memLimit * 1073741824;
             } else {
                 $memLimit = (int) $memLimit;
             }
             if (is_numeric($memLimit) && $memLimit < 0) {
                 $memLimit = "";
             }
             // 1.2a3 -- Rare case with memory_limit < 0, e.g. -1Mb!
             if ($memLimit == "" || $fileSize >= _AKEEBA_COMPRESSION_THRESHOLD) {
                 // No memory limit, or over 1Mb files => always compress up to 1Mb files (otherwise it times out)
                 $compressionMethod = $fileSize <= _AKEEBA_COMPRESSION_THRESHOLD ? 1 : 0;
             } elseif (function_exists("memory_get_usage")) {
                 // PHP can report memory usage, see if there's enough available memory; Joomla! alone eats about 5-6Mb! This code is called on files <= 1Mb
                 $memLimit = $this->_return_bytes($memLimit);
                 $availableRAM = $memLimit - memory_get_usage();
                 $compressionMethod = $availableRAM / 2.5 >= $fileSize ? 1 : 0;
             } else {
                 // PHP can't report memory usage, compress only files up to 512Kb (conservative approach) and hope it doesn't break
                 $compressionMethod = $fileSize <= 524288 ? 1 : 0;
             }
         }
         $compressionMethod = function_exists("gzcompress") ? $compressionMethod : 0;
         $storedName = $targetName;
         /* "Entity Description BLock" segment. */
         $unc_len =& $fileSize;
         // File size
         $storedName .= $isDir ? "/" : "";
         if ($compressionMethod == 1) {
             if ($isVirtual) {
                 $udata =& $sourceNameOrData;
             } else {
                 // Get uncompressed data
                 $udata = @file_get_contents($sourceNameOrData);
                 // PHP > 4.3.0 saves us the trouble
             }
             if ($udata === FALSE) {
                 // Unreadable file, skip it.
                 $this->setWarning('Unreadable file ' . $sourceNameOrData . '. Check permissions');
                 return false;
             } else {
                 // Proceed with compression
                 $zdata = @gzcompress($udata);
                 if ($zdata === false) {
                     // If compression fails, let it behave like no compression was available
                     $c_len =& $unc_len;
                     $compressionMethod = 0;
                 } else {
                     unset($udata);
                     $zdata = substr(substr($zdata, 0, -4), 2);
                     $c_len = akstringlen($zdata);
                 }
             }
         } else {
             $c_len = $unc_len;
             // Test for unreadable files
             if (!$isVirtual && !$isSymlink && !$isDir) {
                 $myfp = @fopen($sourceNameOrData, 'rb');
                 if ($myfp === false) {
                     // Unreadable file, skip it.
                     $this->setWarning('Unreadable file ' . $sourceNameOrData . '. Check permissions');
                     return false;
                 }
                 @fclose($myfp);
             }
         }
         $this->_compressedSize += $c_len;
         // Update global data
         $this->_uncompressedSize += $fileSize;
         // Update global data
         $this->_fileCount++;
         // Get file permissions
         $perms = 0755;
         if (!$isVirtual) {
             if (@file_exists($sourceNameOrData)) {
                 if (@is_file($sourceNameOrData) || @is_link($sourceNameOrData)) {
                     if (@is_readable($sourceNameOrData)) {
                         $perms = @fileperms($sourceNameOrData);
                     }
                 }
             }
         }
         // Calculate Entity Description Block length
         $blockLength = 21 + akstringlen($storedName);
         if ($filectime > 0) {
             $blockLength += 8;
         }
         // If we need to store the file mod date
         // Get file type
         if (!$isDir && !$isSymlink) {
             $fileType = 1;
         } elseif ($isSymlink) {
             $fileType = 2;
         } elseif ($isDir) {
             $fileType = 0;
         }
         // If it's a split ZIP file, we've got to make sure that the header can fit in the part
         if ($this->_useSplitZIP) {
             // Compare to free part space
             clearstatcache();
             $current_part_size = @filesize($this->_dataFileName);
             $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
             if ($free_space <= $blockLength) {
                 // Not enough space on current part, create new part
                 if (!$this->_createNewPart()) {
                     $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
                     return false;
                 }
             }
         }
         // Open data file for output
         $fp = @fopen($this->_dataFileName, "ab");
         if ($fp === false) {
             $this->setError("Could not open archive file '{$this->_dataFileName}' for append!");
             return false;
         }
         $this->_fwrite($fp, $this->_fileHeader);
         // Entity Description Block header
         if ($this->getError()) {
             return false;
         }
         $this->_fwrite($fp, pack('v', $blockLength));
         // Entity Description Block header length
         $this->_fwrite($fp, pack('v', akstringlen($storedName)));
         // Length of entity path
         $this->_fwrite($fp, $storedName);
         // Entity path
         $this->_fwrite($fp, pack('C', $fileType));
         // Entity type
         $this->_fwrite($fp, pack('C', $compressionMethod));
         // Compression method
         $this->_fwrite($fp, pack('V', $c_len));
         // Compressed size
         $this->_fwrite($fp, pack('V', $unc_len));
         // Uncompressed size
         $this->_fwrite($fp, pack('V', $perms));
         // Entity permissions
         // Timestamp Extra Field, only for files
         if ($filectime > 0) {
             $this->_fwrite($fp, "");
             // Extra Field Identifier
             $this->_fwrite($fp, pack('v', 8));
             // Extra Field Length
             $this->_fwrite($fp, pack('V', $filectime));
             // Timestamp
         }
         // Cache useful information about the file
         if (!$isDir && !$isSymlink && !$isVirtual) {
             $configuration->set('volatile.engine.archiver.unc_len', $unc_len);
             $configuration->set('volatile.engine.archiver.sourceNameOrData', $sourceNameOrData);
         }
     } else {
         // If we are continuing file packing we have an uncompressed, non-virtual file.
         // We need to set up these variables so as not to throw any PHP notices.
         $isDir = false;
         $isSymlink = false;
         $isVirtual = false;
         $compressionMethod = 0;
         // Create a file pointer to the archive file
         $fp = @fopen($this->_dataFileName, "ab");
         if ($fp === false) {
             $this->setError("Could not open archive file '{$this->_dataFileName}' for append!");
             return false;
         }
     }
     /* "File data" segment. */
     if ($compressionMethod == 1) {
         if (!$this->_useSplitZIP) {
             // Just dump the compressed data
             $this->_fwrite($fp, $zdata);
             if ($this->getError()) {
                 @fclose($fp);
                 return false;
             }
         } else {
             // Split ZIP. Check if we need to split the part in the middle of the data.
             clearstatcache();
             $current_part_size = @filesize($this->_dataFileName);
             $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
             if ($free_space >= akstringlen($zdata)) {
                 // Write in one part
                 $this->_fwrite($fp, $zdata);
                 if ($this->getError()) {
                     @fclose($fp);
                     return false;
                 }
             } else {
                 $bytes_left = akstringlen($zdata);
                 while ($bytes_left > 0) {
                     clearstatcache();
                     $current_part_size = @filesize($this->_dataFileName);
                     $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
                     // Split between parts - Write first part
                     $this->_fwrite($fp, $zdata, min(akstringlen($zdata), $free_space));
                     if ($this->getError()) {
                         @fclose($fp);
                         return false;
                     }
                     // Get the rest of the data
                     $bytes_left = akstringlen($zdata) - $free_space;
                     if ($bytes_left > 0) {
                         // Create new part
                         @fclose($fp);
                         if (!$this->_createNewPart()) {
                             // Die if we couldn't create the new part
                             $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
                             return false;
                         } else {
                             // Close the old data file
                             @fclose($fp);
                             // Open data file for output
                             $fp = @fopen($this->_dataFileName, "ab");
                             if ($fp === false) {
                                 $this->setError("Could not open archive file {$this->_dataFileName} for append!");
                                 return false;
                             }
                         }
                         $zdata = substr($zdata, -$bytes_left);
                     }
                 }
             }
         }
         unset($zdata);
     } elseif (!$isDir && !$isSymlink) {
         if ($isVirtual) {
             if (!$this->_useSplitZIP) {
                 // Just dump the data
                 $this->_fwrite($fp, $sourceNameOrData);
                 if ($this->getError()) {
                     @fclose($fp);
                     return false;
                 }
             } else {
                 // Split JPA. Check if we need to split the part in the middle of the data.
                 clearstatcache();
                 $current_part_size = @filesize($this->_dataFileName);
                 $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
                 if ($free_space >= akstringlen($sourceNameOrData)) {
                     // Write in one part
                     $this->_fwrite($fp, $sourceNameOrData);
                     if ($this->getError()) {
                         return false;
                     }
                 } else {
                     $bytes_left = akstringlen($sourceNameOrData);
                     while ($bytes_left > 0) {
                         clearstatcache();
                         $current_part_size = @filesize($this->_dataFileName);
                         $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
                         // Split between parts - Write first part
                         $this->_fwrite($fp, $sourceNameOrData, min(akstringlen($sourceNameOrData), $free_space));
                         if ($this->getError()) {
                             @fclose($fp);
                             return false;
                         }
                         // Get the rest of the data
                         $rest_size = akstringlen($sourceNameOrData) - $free_space;
                         if ($rest_size > 0) {
                             // Create new part
                             if (!$this->_createNewPart()) {
                                 // Die if we couldn't create the new part
                                 $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
                                 @fclose($fp);
                                 return false;
                             } else {
                                 // Close the old data file
                                 @fclose($fp);
                                 // Open data file for output
                                 $fp = @fopen($this->_dataFileName, "ab");
                                 if ($fp === false) {
                                     $this->setError("Could not open archive file {$this->_dataFileName} for append!");
                                     return false;
                                 }
                             }
                             $zdata = substr($sourceNameOrData, -$rest_size);
                         }
                         $bytes_left = $rest_size;
                     }
                     // end while
                 }
             }
         } else {
             // IMPORTANT! Only this case can be spanned across steps: uncompressed, non-virtual data
             // Load cached data if we're resumming file packing
             if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
                 $sourceNameOrData = $configuration->get('volatile.engine.archiver.sourceNameOrData', '');
                 $unc_len = $configuration->get('volatile.engine.archiver.unc_len', 0);
                 $resume = $configuration->get('volatile.engine.archiver.resume', 0);
             }
             // Copy the file contents, ignore directories
             $zdatafp = @fopen($sourceNameOrData, "rb");
             if ($zdatafp === FALSE) {
                 $this->setWarning('Unreadable file ' . $sourceNameOrData . '. Check permissions');
                 @fclose($fp);
                 return false;
             } else {
                 // Seek to the resume point if required
                 if ($configuration->get('volatile.engine.archiver.processingfile', false)) {
                     // Seek to new offset
                     $seek_result = @fseek($zdatafp, $resume);
                     if ($seek_result === -1) {
                         // What?! We can't resume!
                         $this->setError(sprintf('Could not resume packing of file %s. Your archive is damaged!', $sourceNameOrData));
                         @fclose($zdatafp);
                         @fclose($fp);
                         return false;
                     }
                     // Doctor the uncompressed size to match the remainder of the data
                     $unc_len = $unc_len - $resume;
                 }
                 if (!$this->_useSplitZIP) {
                     while (!feof($zdatafp) && $timer->getTimeLeft() > 0 && $unc_len > 0) {
                         $zdata = fread($zdatafp, AKEEBA_CHUNK);
                         $this->_fwrite($fp, $zdata, min(akstringlen($zdata), AKEEBA_CHUNK));
                         $unc_len -= min(akstringlen($zdata), AKEEBA_CHUNK);
                         if ($this->getError()) {
                             @fclose($zdatafp);
                             @fclose($fp);
                             return false;
                         }
                     }
                     // WARNING!!! The extra $unc_len != 0 check is necessary as PHP won't reach EOF for 0-byte files.
                     if (!feof($zdatafp) && $unc_len != 0) {
                         // We have to break, or we'll time out!
                         $resume = @ftell($zdatafp);
                         $configuration->set('volatile.engine.archiver.resume', $resume);
                         $configuration->set('volatile.engine.archiver.processingfile', true);
                         @fclose($zdatafp);
                         @fclose($fp);
                         return true;
                     }
                 } else {
                     // Split JPA - Do we have enough space to host the whole file?
                     clearstatcache();
                     $current_part_size = @filesize($this->_dataFileName);
                     $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
                     if ($free_space >= $unc_len) {
                         // Yes, it will fit inside this part, do quick copy
                         while (!feof($zdatafp) && $timer->getTimeLeft() > 0 && $unc_len > 0) {
                             $zdata = fread($zdatafp, AKEEBA_CHUNK);
                             $this->_fwrite($fp, $zdata, min(akstringlen($zdata), AKEEBA_CHUNK));
                             //$unc_len -= min(akstringlen($zdata), AKEEBA_CHUNK);
                             $unc_len -= AKEEBA_CHUNK;
                             if ($this->getError()) {
                                 @fclose($zdatafp);
                                 @fclose($fp);
                                 return false;
                             }
                         }
                         //if(!feof($zdatafp) && ($unc_len != 0))
                         if (!feof($zdatafp) && $unc_len > 0) {
                             // We have to break, or we'll time out!
                             $resume = @ftell($zdatafp);
                             $configuration->set('volatile.engine.archiver.resume', $resume);
                             $configuration->set('volatile.engine.archiver.processingfile', true);
                             @fclose($zdatafp);
                             @fclose($fp);
                             return true;
                         }
                     } else {
                         // No, we'll have to split between parts. We'll loop until we run
                         // out of space.
                         while (!feof($zdatafp) && $timer->getTimeLeft() > 0) {
                             clearstatcache();
                             $current_part_size = @filesize($this->_dataFileName);
                             $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size);
                             // Find optimal chunk size
                             $chunk_size_primary = min(AKEEBA_CHUNK, $free_space);
                             if ($chunk_size_primary <= 0) {
                                 $chunk_size_primary = max(AKEEBA_CHUNK, $free_space);
                             }
                             // Calculate if we have to read some more data (smaller chunk size)
                             // and how many times we must read w/ the primary chunk size
                             $chunk_size_secondary = $free_space % $chunk_size_primary;
                             $loop_times = ($free_space - $chunk_size_secondary) / $chunk_size_primary;
                             // Read and write with the primary chunk size
                             for ($i = 1; $i <= $loop_times; $i++) {
                                 $zdata = fread($zdatafp, $chunk_size_primary);
                                 $this->_fwrite($fp, $zdata, min(akstringlen($zdata), $chunk_size_primary));
                                 //$unc_len -= min(akstringlen($zdata), $chunk_size_primary);
                                 $unc_len -= $chunk_size_primary;
                                 if ($this->getError()) {
                                     @fclose($zdatafp);
                                     @fclose($fp);
                                     return false;
                                 }
                                 // Do we have enough time to proceed?
                                 //if( (!feof($zdatafp)) && ($unc_len != 0) && ($timer->getTimeLeft() <= 0) ) {
                                 if (!feof($zdatafp) && $unc_len >= 0 && $timer->getTimeLeft() <= 0) {
                                     // No, we have to break, or we'll time out!
                                     $resume = @ftell($zdatafp);
                                     $configuration->set('volatile.engine.archiver.resume', $resume);
                                     $configuration->set('volatile.engine.archiver.processingfile', true);
                                     @fclose($zdatafp);
                                     @fclose($fp);
                                     return true;
                                 }
                             }
                             // Read and write w/ secondary chunk size, if non-zero
                             if ($chunk_size_secondary > 0) {
                                 $zdata = fread($zdatafp, $chunk_size_secondary);
                                 $this->_fwrite($fp, $zdata, min(akstringlen($zdata), $chunk_size_secondary));
                                 //$unc_len -= min(akstringlen($zdata), $chunk_size_secondary);
                                 $unc_len -= $chunk_size_secondary;
                                 if ($this->getError()) {
                                     @fclose($zdatafp);
                                     @fclose($fp);
                                     return false;
                                 }
                             }
                             // Do we have enough time to proceed?
                             //if( (!feof($zdatafp)) && ($unc_len != 0) && ($timer->getTimeLeft() <= 0) ) {
                             if (!feof($zdatafp) && $unc_len >= 0 && $timer->getTimeLeft() <= 0) {
                                 // No, we have to break, or we'll time out!
                                 $resume = @ftell($zdatafp);
                                 $configuration->set('volatile.engine.archiver.resume', $resume);
                                 $configuration->set('volatile.engine.archiver.processingfile', true);
                                 // ...and create a new part as well
                                 if (!$this->_createNewPart()) {
                                     // Die if we couldn't create the new part
                                     $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
                                     @fclose($zdatafp);
                                     @fclose($fp);
                                     return false;
                                 }
                                 // ...then, return
                                 @fclose($zdatafp);
                                 @fclose($fp);
                                 return true;
                             }
                             // Create new JPA part, but only if we'll have more data to write
                             //if(!feof($zdatafp) && ($unc_len != 0) && ($unc_len > 0) )
                             if (!feof($zdatafp) && $unc_len > 0) {
                                 if (!$this->_createNewPart()) {
                                     // Die if we couldn't create the new part
                                     $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName));
                                     @fclose($zdatafp);
                                     @fclose($fp);
                                     return false;
                                 } else {
                                     // Close the old data file
                                     fclose($fp);
                                     // We have created the part. If the user asked for immediate post-proc, break step now.
                                     if ($configuration->get('engine.postproc.common.after_part', 0)) {
                                         $resume = @ftell($zdatafp);
                                         $configuration->set('volatile.engine.archiver.resume', $resume);
                                         $configuration->set('volatile.engine.archiver.processingfile', true);
                                         $configuration->set('volatile.breakflag', true);
                                         @fclose($zdatafp);
                                         @fclose($fp);
                                         return true;
                                     }
                                     // Open data file for output
                                     $fp = @fopen($this->_dataFileName, "ab");
                                     if ($fp === false) {
                                         $this->setError("Could not open archive file {$this->_dataFileName} for append!");
                                         @fclose($zdatafp);
                                         return false;
                                     }
                                 }
                             }
                         }
                         // end while
                     }
                 }
                 @fclose($zdatafp);
             }
         }
     } elseif ($isSymlink) {
         $this->_fwrite($fp, @readlink($sourceNameOrData));
     }
     @fclose($fp);
     //AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "DEBUG -- Added $targetName to archive");
     // Uncache data
     $configuration->set('volatile.engine.archiver.sourceNameOrData', null);
     $configuration->set('volatile.engine.archiver.unc_len', null);
     $configuration->set('volatile.engine.archiver.resume', null);
     $configuration->set('volatile.engine.archiver.processingfile', false);
     // ... and return TRUE = success
     return TRUE;
 }
Beispiel #3
0
 /**
  * Process the file data of a link entry
  * @return bool
  */
 private function processTypeLink()
 {
     // Does the file have any data, at all?
     if ($this->fileHeader->uncompressed == 0) {
         // No file data!
         $this->runState = AK_STATE_DATAREAD;
         return true;
     }
     // Read the mini header
     $binMiniHeader = fread($this->fp, 8);
     $reallyReadBytes = akstringlen($binMiniHeader);
     if ($reallyReadBytes < 8) {
         // We read less than requested! Why? Did we hit local EOF?
         if ($this->isEOF(true) && !$this->isEOF(false)) {
             // Yeap. Let's go to the next file
             $this->nextFile();
             // Retry reading the header
             $binMiniHeader = fread($this->fp, 8);
             $reallyReadBytes = akstringlen($binMiniHeader);
             // Still not enough data? If so, the archive is corrupt or missing parts.
             if ($reallyReadBytes < 8) {
                 $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                 return false;
             }
         } else {
             // Nope. The archive is corrupt
             $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
             return false;
         }
     }
     // Read the encrypted data
     $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader);
     $toReadBytes = $miniHeader['encsize'];
     $data = $this->fread($this->fp, $toReadBytes);
     $reallyReadBytes = akstringlen($data);
     if ($reallyReadBytes < $toReadBytes) {
         // We read less than requested! Why? Did we hit local EOF?
         if ($this->isEOF(true) && !$this->isEOF(false)) {
             // Yeap. Let's go to the next file
             $this->nextFile();
             // Read the rest of the data
             $toReadBytes -= $reallyReadBytes;
             $restData = $this->fread($this->fp, $toReadBytes);
             $reallyReadBytes = akstringlen($data);
             if ($reallyReadBytes < $toReadBytes) {
                 $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                 return false;
             }
             $data .= $restData;
         } else {
             // Nope. The archive is corrupt
             $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
             return false;
         }
     }
     // Decrypt the data
     $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128);
     // Is the length of the decrypted data less than expected?
     $data_length = akstringlen($data);
     if ($data_length < $miniHeader['decsize']) {
         $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD'));
         return false;
     }
     // Trim the data
     $data = substr($data, 0, $miniHeader['decsize']);
     // Try to remove an existing file or directory by the same name
     if (file_exists($this->fileHeader->realFile)) {
         @unlink($this->fileHeader->realFile);
         @rmdir($this->fileHeader->realFile);
     }
     // Remove any trailing slash
     if (substr($this->fileHeader->realFile, -1) == '/') {
         $this->fileHeader->realFile = substr($this->fileHeader->realFile, 0, -1);
     }
     // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :(
     if (!AKFactory::get('kickstart.setup.dryrun', '0')) {
         @symlink($data, $this->fileHeader->realFile);
     }
     $this->runState = AK_STATE_DATAREAD;
     return true;
     // No matter if the link was created!
 }
Beispiel #4
0
 private function processTypeFileCompressedSimple()
 {
     $timer = AKFactory::getTimer();
     // Files are being processed in small chunks, to avoid timeouts
     if ($this->dataReadLength == 0 && !AKFactory::get('kickstart.setup.dryrun', '0')) {
         // Before processing file data, ensure permissions are adequate
         $this->setCorrectPermissions($this->fileHeader->file);
     }
     // Open the output file
     if (!AKFactory::get('kickstart.setup.dryrun', '0')) {
         // Open the output file
         $outfp = @fopen($this->fileHeader->realFile, 'wb');
         // Can we write to the file?
         $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file);
         if ($outfp === false && !$ignore) {
             // An error occured
             $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile));
             return false;
         }
     }
     // Does the file have any data, at all?
     if ($this->fileHeader->uncompressed == 0) {
         // No file data!
         if (!AKFactory::get('kickstart.setup.dryrun', '0')) {
             if (is_resource($outfp)) {
                 @fclose($outfp);
             }
         }
         $this->runState = AK_STATE_DATAREAD;
         return true;
     }
     $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength;
     // Loop while there's data to write and enough time to do it
     while ($leftBytes > 0 && $timer->getTimeLeft() > 0) {
         // Read the mini header
         $binMiniHeader = fread($this->fp, 8);
         $reallyReadBytes = akstringlen($binMiniHeader);
         if ($reallyReadBytes < 8) {
             // We read less than requested! Why? Did we hit local EOF?
             if ($this->isEOF(true) && !$this->isEOF(false)) {
                 // Yeap. Let's go to the next file
                 $this->nextFile();
                 // Retry reading the header
                 $binMiniHeader = fread($this->fp, 8);
                 $reallyReadBytes = akstringlen($binMiniHeader);
                 // Still not enough data? If so, the archive is corrupt or missing parts.
                 if ($reallyReadBytes < 8) {
                     $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                     return false;
                 }
             } else {
                 // Nope. The archive is corrupt
                 $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                 return false;
             }
         }
         // Read the encrypted data
         $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader);
         $toReadBytes = $miniHeader['encsize'];
         $data = $this->fread($this->fp, $toReadBytes);
         $reallyReadBytes = akstringlen($data);
         if ($reallyReadBytes < $toReadBytes) {
             // We read less than requested! Why? Did we hit local EOF?
             if ($this->isEOF(true) && !$this->isEOF(false)) {
                 // Yeap. Let's go to the next file
                 $this->nextFile();
                 // Read the rest of the data
                 $toReadBytes -= $reallyReadBytes;
                 $restData = $this->fread($this->fp, $toReadBytes);
                 $reallyReadBytes = akstringlen($restData);
                 if ($reallyReadBytes < $toReadBytes) {
                     $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                     return false;
                 }
                 if (akstringlen($data) == 0) {
                     $data = $restData;
                 } else {
                     $data .= $restData;
                 }
             } else {
                 // Nope. The archive is corrupt
                 $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE'));
                 return false;
             }
         }
         // Decrypt the data
         $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128);
         // Is the length of the decrypted data less than expected?
         $data_length = akstringlen($data);
         if ($data_length < $miniHeader['decsize']) {
             $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD'));
             return false;
         }
         // Trim the data
         $data = substr($data, 0, $miniHeader['decsize']);
         // Decompress
         $data = gzinflate($data);
         $unc_len = akstringlen($data);
         // Write the decrypted data
         if (!AKFactory::get('kickstart.setup.dryrun', '0')) {
             if (is_resource($outfp)) {
                 @fwrite($outfp, $data, akstringlen($data));
             }
         }
         // Update the read length
         $this->dataReadLength += $unc_len;
         $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength;
     }
     // Close the file pointer
     if (!AKFactory::get('kickstart.setup.dryrun', '0')) {
         if (is_resource($outfp)) {
             @fclose($outfp);
         }
     }
     // Was this a pre-timeout bail out?
     if ($leftBytes > 0) {
         $this->runState = AK_STATE_DATA;
     } else {
         // Oh! We just finished!
         $this->runState = AK_STATE_DATAREAD;
         $this->dataReadLength = 0;
     }
     return true;
 }