You are here

function _clamav_scan_via_daemon_handler in ClamAV 7

Scan a single file via ClamAV daemon.

Parameters

resource $handler: An opened connection to a daemon socket resource.

String $filepath: Full filepath to the file which is to be scanned. This must be a file which is readable by the web server.

String $filename: Filename of the uploaded file (used for logging).

Return value

int one of:

2 calls to _clamav_scan_via_daemon_handler()
_clamav_scan_via_daemon in ./clamav.inc
Scan a single file using a daemon.
_clamav_scan_via_unix_socket in ./clamav.inc
Scan a single file by connecting to ClamAV over a unix socket.

File

./clamav.inc, line 148
clamav.inc API and helper functions for the ClamAV module.

Code

function _clamav_scan_via_daemon_handler($handler, $filepath, $filename) {

  // Request a scan from the daemon.
  $filehandler = fopen($filepath, 'r');
  if ($filehandler) {

    // Open a request with the daemon to stream file data.
    fwrite($handler, "zINSTREAM\0");
    $bytes = filesize($filepath);
    if ($bytes > 0) {

      // Tell the daemon how many bytes of data we're sending.
      fwrite($handler, pack("N", $bytes));

      // Send the file data.
      stream_copy_to_stream($filehandler, $handler);
    }

    // Send a zero-length block to indicate that we're done sending file data.
    fwrite($handler, pack("N", 0));
    $response = fgets($handler);
    fclose($filehandler);
    fclose($handler);
    $response = trim($response);
  }
  else {
    watchdog('clamav', 'Uploaded file %filename could not be scanned: failed to open file handle.', array(
      '%filename' => $filename,
    ), WATCHDOG_WARNING);
    return CLAMAV_SCANRESULT_UNCHECKED;
  }

  // clamd returns a string response in the format:
  // stream: OK
  // stream: <name of virus> FOUND
  // stream: <error string> ERROR
  if (preg_match('/^stream: OK$/', $response)) {

    // Log the message to watchdog, if verbose mode is used.
    if (variable_get('clamav_verbose', CLAMAV_VERBOSE_DEFAULT)) {
      watchdog('clamav', 'File %filename scanned by ClamAV and found clean.', array(
        '%filename' => $filename,
      ), WATCHDOG_INFO);
    }
    return CLAMAV_SCANRESULT_CLEAN;
  }
  elseif (preg_match('/^stream: (.*) FOUND$/', $response, $matches)) {
    $virus_name = $matches[1];
    watchdog('clamav', 'Virus detected in uploaded file %filename.  Clamav-daemon reported the virus:<br />@virus_name', array(
      '%filename' => $filename,
      '@virus_name' => $virus_name,
    ), WATCHDOG_CRITICAL);
    return CLAMAV_SCANRESULT_INFECTED;
  }
  else {

    // try to extract the error message from the response.
    preg_match('/^stream: (.*) ERROR$/', $response, $matches);
    $error_string = $matches[1];

    // the error message given by the daemon
    watchdog('clamav', 'Uploaded file %filename could not be scanned.  Clamscan reported:<br />@error_string', array(
      '%filename' => $filename,
      '@error_string' => $error_string,
    ), WATCHDOG_WARNING);
    return CLAMAV_SCANRESULT_UNCHECKED;
  }
}