You are here

public function DaemonTCPIP::scan in ClamAV 8

Same name and namespace in other branches
  1. 2.x src/Scanner/DaemonTCPIP.php \Drupal\clamav\Scanner\DaemonTCPIP::scan()

Scan a file.

Parameters

Drupal\file\FileInterface $file: The file to scan for viruses.

Return value

int

Overrides ScannerInterface::scan

File

src/Scanner/DaemonTCPIP.php, line 27

Class

DaemonTCPIP

Namespace

Drupal\clamav\Scanner

Code

public function scan(FileInterface $file) {

  // Attempt to open a socket to the ClamAV host.
  $scanner_handler = @fsockopen($this->_hostname, $this->_port);

  // Abort if the ClamAV server is unavailable.
  if (!$scanner_handler) {
    \Drupal::logger('Clam AV')
      ->warning('Unable to connect to ClamAV TCP/IP daemon on @hostname:@port', array(
      '@hostname' => $this->_hostname,
      '@port' => $this->_port,
    ));
    return Scanner::FILE_IS_UNCHECKED;
  }

  // Push to the ClamAV socket.
  $bytes = $file
    ->getSize();
  fwrite($scanner_handler, "zINSTREAM\0");
  fwrite($scanner_handler, pack("N", $bytes));

  // Open the file and push to the TCP/IP connection.
  $file_handler = fopen($file
    ->getFileUri(), 'r');
  stream_copy_to_stream($file_handler, $scanner_handler);

  // Send a zero-length block to indicate that we're done sending file data.
  fwrite($scanner_handler, pack("N", 0));

  // Request a response from the service.
  $response = trim(fgets($scanner_handler));

  // Close both handlers.
  fclose($scanner_handler);
  fclose($file_handler);

  // Process the output from the stream.
  if (preg_match('/^stream: OK$/', $response)) {
    $result = Scanner::FILE_IS_CLEAN;
  }
  elseif (preg_match('/^stream: (.*) FOUND$/', $response, $matches)) {
    $this->_virus_name = $matches[1];
    $result = Scanner::FILE_IS_INFECTED;
  }
  else {
    preg_match('/^stream: (.*) ERROR$/', $response, $matches);
    $result = Scanner::FILE_IS_UNCHECKED;
  }
  return $result;
}