/** * Finalises the archive by compressing it. Overrides parent's method * @return boolean TRUE on success, FALSE on failure */ function finalize() { // Get gzip's binary location $registry = JoomlapackModelRegistry::getInstance(); $gzip = escapeshellcmd($registry->get('gzipbinary')); // Construct and run command line $command = "{$gzip} " . escapeshellcmd($this->_tempFilename); JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "JoomlapackPackerTARGZ :: Calling gzip. The command line is:"); JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, $command); $result = shell_exec($command); // Normally, gzip should be silent as a fish. If anything was sput out, // there must have been an error. if (strlen(trim($result)) > 0) { $errorMessage = "Error calling gzip: " . $result . " \n Command line was: \n " . $command . " \n Please check file permissions and examine the result message for any hints regarding the problem tar faced archiving your files."; $this->setError($errorMessage); return false; } // Now, unregister the temp file (which no longer exists), register the gzipped file as // a new temp file and try to move it JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($this->_tempFilename); $this->_tempFilename = JoomlapackCUBETempfiles::registerTempFile(basename($this->_archiveFilename)); copy($this->_tempFilename, $this->_archiveFilename); JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($this->_tempFilename); // If no errors occured, return true return true; }
/** * Creates the ZIP file out of its pieces. * Official ZIP file format: http://www.pkware.com/appnote.txt * * @return boolean TRUE on success, FALSE on failure */ function finalize() { // 1. Get size of central directory clearstatcache(); $cdSize = @filesize($this->_ctrlDirFileName); // 2. Append Central Directory to data file and remove the CD temp file afterwards $dataFP = fopen($this->_dataFileName, "ab"); $cdFP = fopen($this->_ctrlDirFileName, "rb"); if ($dataFP === false) { $this->setError('Could not open ZIP data file ' . $this->_dataFileName . ' for reading'); return false; } if ($cdFP === false) { // Already glued, return fclose($dataFP); return false; } if (!$this->_useSplitZIP) { while (!feof($cdFP)) { $chunk = fread($cdFP, _JoomlapackPackerZIP_DIRECTORY_READ_CHUNK); $this->_fwrite($dataFP, $chunk); if ($this->getError()) { return; } } unset($chunk); fclose($cdFP); } else { // Calcuate size of Central Directory + EOCD records $total_cd_eocd_size = $cdSize + 22 + strlen($this->_comment); // Free space on the part clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); if ($free_space < $total_cd_eocd_size && $total_cd_eocd_size > 65536) { // Not enough space on archive for CD + EOCD, will go on separate part // Create new final part if (!$this->_createNewPart(true)) { // Die if we couldn't create the new part $this->setError('Could not create new ZIP part file ' . basename($this->_dataFileName)); return false; } else { // Close the old data file fclose($dataFP); // Open data file for output $dataFP = @fopen($this->_dataFileName, "ab"); if ($dataFP === false) { $this->setError("Could not open archive file {$this->_dataFileName} for append!"); return false; } // Write the CD record while (!feof($cdFP)) { $chunk = fread($cdFP, _JoomlapackPackerZIP_DIRECTORY_READ_CHUNK); $this->_fwrite($dataFP, $chunk); if ($this->getError()) { return; } } unset($chunk); fclose($cdFP); } } else { // Glue the CD + EOCD on the same part if they fit, or anyway if they are less than 64Kb. // NOTE: WE *MUST NOT* CREATE FRAGMENTS SMALLER THAN 64Kb!!!! while (!feof($cdFP)) { $chunk = fread($cdFP, _JoomlapackPackerZIP_DIRECTORY_READ_CHUNK); $this->_fwrite($dataFP, $chunk); if ($this->getError()) { return; } } unset($chunk); fclose($cdFP); } } JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($this->_ctrlDirFileName); // 3. Write the rest of headers to the end of the ZIP file fclose($dataFP); clearstatcache(); $dataSize = @filesize($this->_dataFileName) - $cdSize; $dataFP = fopen($this->_dataFileName, "ab"); if ($dataFP === false) { $this->setError('Could not open ' . $this->_dataFileName . ' for append'); return false; } $this->_fwrite($dataFP, $this->_ctrlDirEnd); if ($this->getError()) { return; } if ($this->_useSplitZIP) { // Split ZIP files, enter relevant disk number information $this->_fwrite($dataFP, pack('v', $this->_totalFragments - 1)); /* Number of this disk. */ $this->_fwrite($dataFP, pack('v', $this->_totalFragments - 1)); /* Disk with central directory start. */ } else { // Non-split ZIP files, the disk numbers MUST be 0 $this->_fwrite($dataFP, pack('V', 0)); } $this->_fwrite($dataFP, pack('v', $this->_totalFileEntries)); /* Total # of entries "on this disk". */ $this->_fwrite($dataFP, pack('v', $this->_totalFileEntries)); /* Total # of entries overall. */ $this->_fwrite($dataFP, pack('V', $cdSize)); /* Size of central directory. */ $this->_fwrite($dataFP, pack('V', $dataSize)); /* Offset to start of central dir. */ $sizeOfComment = strlen($this->_comment); // 2.0.b2 -- Write a ZIP file comment $this->_fwrite($dataFP, pack('v', $sizeOfComment)); /* ZIP file comment length. */ $this->_fwrite($dataFP, $this->_comment); fclose($dataFP); //sleep(2); // If Split ZIP and there is no .zip file, rename the last fragment to .ZIP if ($this->_useSplitZIP) { $extension = substr($this->_dataFileName, -3); if ($extension != '.zip') { JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, 'Renaming last ZIP part to .ZIP extension'); $newName = $this->_dataFileNameBase . '.zip'; if (!@rename($this->_dataFileName, $newName)) { $this->setError('Could not rename last ZIP part to .ZIP extension.'); return false; } $this->_dataFileName = $newName; } } // If Split ZIP and only one fragment, change the signature if ($this->_useSplitZIP && $this->_totalFragments == 1) { $fp = fopen($this->_dataFileName, 'r+b'); $this->_fwrite($fp, "PK00"); } // @todo If Split ZIP, update CUBE with total number of fragments if (function_exists('chmod')) { @chmod($this->_dataFileName, 0755); } return true; }
/** * 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 2.1 * @access protected * @abstract */ function _addFile($isVirtual, &$sourceNameOrData, $targetName) { if ($isVirtual) { // VIRTUAL FILES // Create and register temp file with the virtual contents $tempFileName = JoomlapackCUBETempfiles::registerTempFile(basename($targetName)); if (function_exists('file_put_contents')) { file_put_contents($tempFileName, $sourceNameOrData); } else { $tempHandler = fopen($tempFileName, 'wb'); $this->_fwrite($tempHandler, $sourceNameOrData); fclose($tempHandler); } // Calculate add / remove paths $removePath = dirname($tempFileName); $addPath = dirname($targetName); // Add the file $this->_tarObject->addModify($tempFileName, $addPath, $removePath, $tempFileName); // Remove the temporary file JoomlapackCUBETempfiles::unregisterAndDeleteTempFile(basename($targetName)); } else { // REGULAR FILES if ($targetName == '') { $targetName = $sourceNameOrData; } $this->_tarObject->addModify($sourceNameOrData, '', JPATH_SITE, $targetName); } }
/** * Implements the _finalize() abstract method * */ function _finalize() { // Add Extension Filter SQL statements (if any), only for the MAIN DATABASE!!! if ($this->_isJoomla) { jpimport('models.extfilter', true); $extModel = new JoomlapackModelExtfilter(); $extraSQL =& $extModel->getExtraSQL(); $this->_writeline($extraSQL); unset($extraSQL); unset($extModel); } // If we are not just doing a main db only backup, add the SQL file to the archive $configuration =& JoomlapackModelRegistry::getInstance(); if ($configuration->get('BackupType') != 'dbonly') { JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "Adding the SQL dump to the archive"); $cube =& JoomlapackCUBE::getInstance(); $provisioning =& $cube->getProvisioning(); $archiver =& $provisioning->getArchiverEngine(); $archiver->addFileRenamed($this->_tempFile, $this->_saveAsName); unset($archiver); if ($this->getError()) { return; } JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "Removing temporary file"); JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($this->_tempFile, true); if ($this->getError()) { return; } } $this->_isFinished = true; }
/** * 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 */ function _addFile($isVirtual, &$sourceNameOrData, $targetName) { // Are we connected to a server? if (!is_resource($this->_ftphandle)) { if (!$this->_connectFTP()) { return false; } } // See if it's a directory $isDir = $isVirtual ? false : is_dir($sourceNameOrData); if ($isDir) { // Just try to create the remote directory return $this->_makeDirectory($targetName); } else { // We have a file we need to upload if ($isVirtual) { // Create a temporary file, upload, rename it $tempFileName = JoomlapackCUBETempfiles::createRegisterTempFile(); if (function_exists('file_put_contents')) { if (@file_put_contents($tempFileName, $sourceNameOrData) === false) { $this->setError('Could not upload virtual file ' . $targetName); return false; } $res = $this->_upload($tempFileName, $targetName); JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($tempFileName, true); return $res; } } else { // Upload a file return $this->_upload($sourceNameOrData, $targetName); } } }
/** * Creates the ZIP file out of its pieces. * Official ZIP file format: http://www.pkware.com/appnote.txt * * @return boolean TRUE on success, FALSE on failure */ function finalize() { // 1. Get size of central directory clearstatcache(); $cdSize = filesize($this->_ctrlDirFileName); // 2. Append Central Directory to data file and remove the CD temp file afterwards $dataFP = fopen($this->_dataFileName, "ab"); $cdFP = fopen($this->_ctrlDirFileName, "rb"); if ($dataFP === false) { $this->setError('Could not open ZIP data file ' . $this->_dataFileName . ' for reading'); return false; } if ($cdFP === false) { // Already glued, return fclose($dataFP); return false; } while (!feof($cdFP)) { $chunk = fread($cdFP, _JoomlapackPackerZIP_DIRECTORY_READ_CHUNK); $this->_fwrite($dataFP, $chunk); if ($this->getError()) { return; } } unset($chunk); fclose($cdFP); JoomlapackCUBETempfiles::unregisterAndDeleteTempFile($this->_ctrlDirFileName); // 3. Write the rest of headers to the end of the ZIP file fclose($dataFP); clearstatcache(); $dataSize = filesize($this->_dataFileName) - $cdSize; $dataFP = fopen($this->_dataFileName, "ab"); if ($dataFP === false) { $this->setError('Could not open ' . $this->_dataFileName . ' for append'); return false; } $this->_fwrite($dataFP, $this->_ctrlDirEnd); if ($this->getError()) { return; } $this->_fwrite($dataFP, pack('v', $this->_totalFileEntries)); /* Total # of entries "on this disk". */ $this->_fwrite($dataFP, pack('v', $this->_totalFileEntries)); /* Total # of entries overall. */ $this->_fwrite($dataFP, pack('V', $cdSize)); /* Size of central directory. */ $this->_fwrite($dataFP, pack('V', $dataSize)); /* Offset to start of central dir. */ $sizeOfComment = strlen($this->_comment); // 2.0.b2 -- Write a ZIP file comment $this->_fwrite($dataFP, pack('v', $sizeOfComment)); /* ZIP file comment length. */ $this->_fwrite($dataFP, $this->_comment); fclose($dataFP); //sleep(2); if (function_exists('chmod')) { @chmod($this->_dataFileName, 0755); } return true; }