/** * 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! }
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; }