package com.ibm.jactors.test; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import com.ibm.jactors.ActorManager; import com.ibm.jactors.DefaultActorManager; import com.ibm.jactors.DefaultMessage; import com.ibm.jactors.Message; /** * An actor that does a simplified "Virus" (actually files withmultiple text lines) * scan of a directory tree. * * @author BFEIGENB * */ public class VirusScanActor extends TestableActor { @Override protected void runBody() { // logger.trace("TestActor:%s runBody: %s", getName(), this); DefaultActorTest.sleeper(1); DefaultMessage m = new DefaultMessage("init", null); getManager().send(m, null, this); } @Override protected void loopBody(Message m) { try { // logger.trace("TestActor:%s loopBody %s: %s", getName(), m, this); DefaultActorTest.sleeper(1); String subject = m.getSubject(); DefaultActorManager manager = (DefaultActorManager) getManager(); if ("scanDir".equals(subject)) { String dir = (String) m.getData(); File[] list = new File(dir).listFiles(); logger.trace("Scanning directory %s...", dir); if (manager.getCategorySize(getCategory()) < 50) { createVirusScanActor(manager); } for (File file : list) { if (file.isDirectory()) { DefaultMessage dm = new DefaultMessage("scanDir", file.getCanonicalPath()); manager.send(dm, this, this.getClass().getSimpleName()); } else if (file.isFile() && file.getName().toLowerCase().endsWith(".txt")) { DefaultMessage dm = new DefaultMessage("scanFile", file.getCanonicalPath()); manager.send(dm, this, getCategoryName()); } } } else if ("scanFile".equals(subject)) { String file = (String) m.getData(); File xfile = new File(file); String xpath = xfile.getCanonicalPath(); logger.trace("Scaning file %s...", xpath); byte[] ba = readBinaryFileContents(xfile); // TODO: check contents here is real app DefaultActorTest.sleeper(1); //logger.trace("**** Size %s: %d", xpath, ba.length); int count = 0; for(byte b: ba) { if(b == (byte)'\n') { count ++; } } if (count > 10) { DefaultMessage dm = new DefaultMessage("virusFound", new Object[] {xpath, "more than 10 returns found"}); manager.send(dm, this, getCategoryName()); } ba = null; } else if ("virusFound".equals(subject)) { Object[] params = (Object[]) m.getData(); String file = params.length > 0 ? (String) params[0] : null; String message = params.length > 1 ? (String) params[1] : null; if (file != null) { File xfile = new File(file); String xpath = xfile.getCanonicalPath(); logger.trace("**** suspect file; %s: %s", message, xpath); } } else if ("init".equals(subject)) { String startPath = (String) m.getData(); if (startPath != null) { DefaultMessage dm = new DefaultMessage("scanDir", startPath); manager.send(dm, this, getCategoryName()); } } else { logger.warning("VirusScanActor:%s loopBody unknown subject: %s", getName(), subject); } } catch (IOException e) { logger.error("VirusScanActor exception", e); } } /** Read a file. */ public static byte[] readBinaryFileContents(String fileName) throws IOException { return readBinaryFileContents(new File((fileName))); } /** Read a file. */ public static byte[] readBinaryFileContents(File file) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( file)); try { return readBinaryStreamContents(bis); } finally { bis.close(); } } /** Read a stream. */ public static byte[] readBinaryStreamContents(InputStream is) throws IOException { return streamToByteArray(is); } /** Get the bytes from an input stream. */ public static byte[] streamToByteArray(InputStream is) throws IOException { if (!(is instanceof BufferedInputStream)) { is = new BufferedInputStream(is); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[4 * 1024]; for (int count = is.read(buffer); count >= 0; count = is.read(buffer)) { baos.write(buffer, 0, count); } return baos.toByteArray(); } public static VirusScanActor createVirusScanActor(ActorManager manager) { VirusScanActor res = (VirusScanActor) manager.createAndStartActor(VirusScanActor.class, getActorName()); res.setCategory(getCategoryName()); return res; } public static String getCategoryName() { return VirusScanActor.class.getSimpleName(); } protected static int actorCount; protected static String getActorName() { return getCategoryName() + '_' + actorCount++; } }