/** * * @param <string> $file */ public function read_archive($file) { $this->unpacker->archivePath = $file; $error = false; $this->unpacker->unpack(); if ($this->unpacker->hadError()) { $e = $this->unpacker->getError(); ALogger::error('Unpacker: ' . $e[0] . ':' . $e[1]); $this->last_error = 'Unpacker: ' . $e[0] . ':' . $e[1]; SystemHelper::emptyDir($this->unpacker->outputDir); if ($errorCode) { ALogger::error('Error cleaning extract folder ' . implode('|', $output), true); } return false; } $ok = true; foreach ($this->unpacker->getFiles() as $f) { if (!$this->check_file($f['path'], $f['mime'])) { $ok = false; break; } } if (!$ok) { foreach ($this->unpacker->getFiles() as $f) { unlink($f['path']); } // clean folder SystemHelper::emptyDir($this->unpacker->outputDir); if ($errorCode) { ALogger::error('Error cleaning extract folder ' . implode('|', $output), true); } } else { foreach ($this->unpacker->getFiles() as $f) { $this->read_file($f['path'], $f['mime']); } SystemHelper::emptyDir($this->unpacker->outputDir); if ($errorCode) { ALogger::error('Error cleaning extract folder ' . implode('|', $output), true); } } //perform cleanup: SystemHelper::emptyDir($this->unpacker->outputDir); if (count(scandir($this->unpacker->outputDir)) > 2) { ALogger::error('Error cleaning extract folder' . implode('|', $output), true); } return $ok; }
public function unpack($justReturnList = false) { if ($this->debug) { if (!$justReturnList) { echo "\n\nWill unpack archive {$this->archivePath}!\n"; } else { echo "\n\nWill return listing for archive {$this->archivePath}!\n"; } } if (!$justReturnList) { if (!$this->init()) { return false; } if (!$this->r_levels) { return true; } } if ($this->debug) { echo 'Getting file type for: ' . $this->archivePath . "\n"; } if (false == ($fileType = $this->getArchiveType($this->archivePath))) { return false; } $fullOutputPath = ''; if (!$justReturnList) { $md5 = md5(uniqid()); $this->subfolder = $md5; $fullOutputPath = $this->outputDir . '/' . $md5; if (!mkdir($fullOutputPath)) { $this->errorCode = '103'; $this->errorOutput = "Can't mkdir " . $fullOutputPath . '!'; return false; } } switch ($fileType) { case "7z": case "zip": case "gzip": case "tar": $statFunction = 'get7zStat'; if (!empty($this->archive_password)) { $password_command = '-p' . $this->archive_password . ' '; } else { $password_command = '-p'; } $unpackCommand = "7z e -o" . escapeshellarg($fullOutputPath) . " {$password_command} -aou " . self::escapeFilePath($this->archivePath); //self::escapeFilePath(); break; case "rar": $statFunction = 'getRarStat'; if (!empty($this->archive_password)) { $password_command = '-p' . $this->archive_password . ' '; } else { $password_command = '-p-'; } $unpackCommand = "unrar e -or {$password_command} " . escapeshellarg($this->archivePath) . " " . self::escapeFilePath($fullOutputPath); break; default: $this->errorCode = '203'; if (isset($gpg_command)) { $this->errorOutput = "Can not determine archive type correctly! Possible GPG fault! GPG output has size:" . filesize($this->archivePath); } else { $this->errorOutput = "Can not determine archive type correctly!"; } return false; } //end::switch($fileType) if ($justReturnList) { return call_user_func(array($this, $statFunction), $this->archivePath, $this->archive_password, true); } if (false !== ($stat = call_user_func(array($this, $statFunction), $this->archivePath, $this->archive_password))) { list($nr_files, $unpacked_size) = $stat; } else { return false; } if ($nr_files > $this->max_files) { $this->errorCode = '301'; $this->errorOutput = "Too many files! ({$nr_files} vs {$this->max_files})"; return false; } $unpacked_size = $unpacked_size / (1024 * 1024); if ($unpacked_size > $this->max_size) { $this->errorCode = '302'; $this->errorOutput = "Size exceeded! ({$unpacked_size} vs {$this->max_size})"; return false; } if ($this->debug) { echo "Found {$unpacked_size} smaller then {$this->max_size}\n"; } if ($this->debug) { echo $unpackCommand . "\n"; } exec($unpackCommand . ' 2>&1', $output, $errorCode); if ($errorCode) { $this->errorCode = "{$fileType}:{$errorCode}"; $this->errorOutput = substr(implode(" ", $output), -200); if ($this->debug) { echo "Emptying " . $fullOutputPath . "\n"; } SystemHelper::emptyDir($fullOutputPath); return false; } // $command = "find {$fullOutputPath} -print -exec chmod -R 0755 '{}' \;"; // if ($this->debug) // echo($command . "\n"); // exec($command, $output, $errorCode); $recurse = $nr_files < self::MAX_RECURSE_FILES && $this->r_levels > 1; $d = dir($fullOutputPath); while (false !== ($entry = $d->read())) { if ($entry != "." && $entry != "..") { $curFile = $fullOutputPath . '/' . $entry; if ($this->debug) { echo '--->' . $curFile . "\n"; } // fwrite(STDOUT, "Press any key to continue..."); // $junk = trim(fgets(STDIN)); if (is_dir($curFile)) { @rmdir($curFile); continue; } //this is because 7z also creates the folders.... $add_file = true; $is_archive = false; if ($this->getArchiveType($curFile, $this->handle_recursive_gpg, false)) { $is_archive = true; if ($recurse) { $up = new AUnpacker($this, $unpacked_size - filesize($curFile) / (1024 * 1024), $nr_files - 1); $up->build_files_array = $this->build_files_array; $up->archivePath = $curFile; $up->unpack(); if ($up->hadError()) { list($errorCode, $errorOutput) = $up->getError(); if ($this->debug) { echo "\nUnpacker for {$curFile} finished with error code {$errorCode} : {$errorOutput}\n"; } $up_full_path = $up->outputDir . '/' . $up->getSubfolder(); unset($output); if ($this->debug) { echo "Emptying " . $up_full_path . "\n"; } SystemHelper::emptyDir($up_full_path); } else { $this->files = array_merge($this->files, $up->getFiles()); $add_file = false; } } //if recurse } if ($add_file && $this->build_files_array) { $nr_files = count($this->files); $this->files[$nr_files]['path'] = $curFile; $this->files[$nr_files]['mime'] = FileHelper::fileMime($curFile); $this->files[$nr_files]['is_archive'] = $is_archive; } } } $d->close(); if (!$this->hadError() && $this->delete_archive) { if ($this->debug) { echo "Deleting {$this->archivePath}...\n"; } if (!@unlink($this->archivePath)) { trigger_error("Unable to delete file {$this->archivePath} !"); } } return true; }
public function extract_file($fname, $detection, $type, $nobogus = false, $bogus_id = null) { SystemHelper::emptyDir($this->unpacker->outputDir); $this->unpacker->reInit(); $this->unpacker->archivePath = $fname; $this->unpacker->unpack(); if (!$this->unpacker->hadError()) { $qstat = "INSERT INTO permanent_statistics_ftp_psf (date_psf, hour_psf, archives_number_psf)\r\n VALUES (CURDATE(), HOUR(NOW()), 1) ON DUPLICATE KEY UPDATE archives_number_psf = archives_number_psf + 1"; Yii::app()->db->createCommand($qstat)->execute(); foreach ($this->unpacker->getFiles() as $f) { $fName = $f['path']; if (!file_exists($fName)) { continue; } $md5 = md5_file($fName); $file = $this->ascii2hex($md5); $dir = $this->makedir($file, VIREX_STORAGE_PATH . DIRECTORY_SEPARATOR . $detection . DIRECTORY_SEPARATOR); if (rename($fName, $dir . $file)) { // if error occurs is capture by main method ( scan_archives ) $this->save_to_db($detection, $type, $md5, filesize($dir . $file)); } } } else { $this->error_count++; // increase error count $e = $this->unpacker->getError(); ALogger::error('Unpacker:' . $e[0] . ':' . $e[1]); // logging error if (!$nobogus) { // if I have to move file to bogus $this->move_file_to_bogus($detection, $type, $fname, $e[0] . ':' . $e[1]); } else { $this->move_file_to_bogus($detection, $type, $fname, $e[0] . ':' . $e[1], $bogus_id); } SystemHelper::emptyDir($this->unpacker->outputDir); return false; } SystemHelper::emptyDir($this->unpacker->outputDir); return true; }