class Clamby::Command

Interface with the system. Builds and runs the command.

Constants

EXECUTABLES

Attributes

command[RW]

Array containing the complete command line.

Public Class Methods

clamscan_version() click to toggle source

Show the ClamAV version. Also acts as a quick check if ClamAV functions.

# File lib/clamby/command.rb, line 58
def self.clamscan_version
  new.run scan_executable, '--version'
end
freshclam() click to toggle source

Update the virus definitions.

# File lib/clamby/command.rb, line 51
def self.freshclam
  args = []
  args << "--datadir=#{Clamby.config[:datadir]}" if Clamby.config[:datadir]
  new.run 'freshclam', *args
end
scan(path) click to toggle source

Perform a ClamAV scan on the given path.

# File lib/clamby/command.rb, line 16
def self.scan(path)
  return nil unless file_exists?(path)

  args = [path, '--no-summary']

  if Clamby.config[:daemonize]
    args << '--fdpass' if Clamby.config[:fdpass]
    args << '--stream' if Clamby.config[:stream]
  end

  args << "-d #{Clamby.config[:datadir]}" if Clamby.config[:datadir]

  new.run scan_executable, *args

  # $CHILD_STATUS maybe nil if the execution itself (not the client process)
  # fails
  case $CHILD_STATUS && $CHILD_STATUS.exitstatus
  when 0
    return false
  when nil, 2
    # clamdscan returns 2 whenever error other than a detection happens
    if Clamby.config[:error_clamscan_client_error] && Clamby.config[:daemonize]
      raise Clamby::ClamscanClientError.new("Clamscan client error")
    end
 
    # returns true to maintain legacy behavior
    return true
  else
    return true unless Clamby.config[:error_file_virus]

    raise Clamby::VirusDetected.new("VIRUS DETECTED on #{Time.now}: #{path}")
  end
end
scan_executable() click to toggle source

Returns the appropriate scan executable, based on clamd being used.

# File lib/clamby/command.rb, line 10
def self.scan_executable
  return 'clamdscan' if Clamby.config[:daemonize]
  return 'clamscan'
end

Private Class Methods

file_exists?(path) click to toggle source
# File lib/clamby/command.rb, line 102
def self.file_exists?(path)
  return true if File.file?(path)

  if Clamby.config[:error_file_missing]
    raise Clamby::FileNotFound.new("File not found: #{path}")
  else
    puts "FILE NOT FOUND on #{Time.now}: #{path}"
    return false
  end
end

Public Instance Methods

run(executable, *args) click to toggle source

Run the given commands via a system call. The executable must be one of the permitted ClamAV executables. The arguments will be combined with default arguments if needed. The arguments are sorted alphabetically before being passed to the system.

Examples:

run('clamscan', file, '--verbose')
run('clamscan', '-V')
# File lib/clamby/command.rb, line 70
def run(executable, *args)
  executable_full = executable_path(executable)
  self.command = args | default_args
  self.command = command.sort.unshift(executable_full)

  system(self.command.join(' '), system_options)
end

Private Instance Methods

default_args() click to toggle source
# File lib/clamby/command.rb, line 80
def default_args
  args = []
  args << "--config-file=#{Clamby.config[:config_file]}" if Clamby.config[:daemonize] && Clamby.config[:config_file]
  args << '--quiet' if Clamby.config[:output_level] == 'low'
  args << '--verbose' if Clamby.config[:output_level] == 'high'
  args
end
executable_path(executable) click to toggle source
# File lib/clamby/command.rb, line 97
def executable_path(executable)
  raise "`#{executable}` is not permitted" unless EXECUTABLES.include?(executable)
  Clamby.config[:"executable_path_#{executable}"]
end
system_options() click to toggle source

This applies to the `system` call itself; does not end up in the command.

# File lib/clamby/command.rb, line 89
def system_options
  if Clamby.config[:output_level] == 'off'
    { out: File::NULL }
  else
    {}
  end
end