package er.extensions.virus;
import java.io.File;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import er.extensions.foundation.ERXFileUtilities;
import er.extensions.foundation.ERXProperties;
/**
* Virus scanner that uses ClamAV to check files and streams. Be sure that
* ClamAV is installed on the system.
*
* @property er.extensions.virus.ERXClamAvVirusScanner set this property to
* the path of the <code>clamscan</code> executable. Defaults to
* <code>/usr/bin/clamscan</code>
*
* @author darkv
*/
public class ERXClamAvVirusScanner extends ERXVirusScanner {
private static final Logger log = LoggerFactory.getLogger(ERXClamAvVirusScanner.class);
private static final String clamscan = ERXProperties.stringForKeyWithDefault(
"er.extensions.virus.ERXClamAvVirusScanner", "/usr/bin/clamscan");
private int status = -1;
public ERXClamAvVirusScanner() {
super();
}
public ERXClamAvVirusScanner(File file) {
scan(file);
}
public ERXClamAvVirusScanner(InputStream inputStream) {
scan(inputStream);
}
@Override
public void scan(File file) {
status = -1;
if (file == null || !file.exists()) {
return;
}
try {
Process process = new ProcessBuilder(clamscan, file.getAbsolutePath()).start();
status = process.waitFor();
if (status > 1) {
log.warn("Unexpected return code from ClamAV");
}
} catch (Exception e) {
log.error("Could not check file {}.", file, e);
}
}
@Override
public void scan(InputStream inputStream) {
status = -1;
if (inputStream == null) {
return;
}
try {
Process process = new ProcessBuilder(clamscan, "-").start();
ERXFileUtilities.writeInputStreamToOutputStream(inputStream, process.getOutputStream());
status = process.waitFor();
if (status > 1) {
log.warn("Unexpected return code from ClamAV");
}
} catch (Exception e) {
log.error("Could not scan input stream.", e);
}
}
@Override
public boolean isOk() {
if (status == -1) {
throw new IllegalStateException("No file nor stream was scanned yet!");
}
return status == 0;
}
}