package com.gilazaria.subsearch.core.subdomainscanner import com.gilazaria.subsearch.core.subdomainscanner.DispatcherMessage.{PauseScanning, ResumeScanning} import com.gilazaria.subsearch.output.Logger import com.gilazaria.subsearch.utils.TimeUtils import akka.actor.ActorRef import akka.pattern.ask import scala.concurrent.ExecutionContext.Implicits.global import sun.misc.{Signal, SignalHandler} import scala.concurrent.Await /** * I'll admit, this isn't exactly kosher. Apparently this can't be done in Java 9. That should be fun. * How to do this in Java was found here: http://twit88.com/blog/2008/02/06/java-signal-handling/ */ object PauseHandler { def create(dispatcher: ActorRef, logger: Logger): PauseHandler = new PauseHandler(List("INT"), dispatcher, logger) case class InterruptException(msg: String) extends Exception(msg) case class ContinueException(msg: String) extends Exception(msg) } class PauseHandler(signalNames: List[String], dispatcher: ActorRef, logger: Logger) extends SignalHandler { import PauseHandler.{InterruptException, ContinueException} private val signalMap = signalNames.map(name => (name, Signal.handle(new Signal(name), this))).toMap private var pausingCalled: Boolean = false override def handle(signal: Signal) = { if (pausingCalled) forceExit() else pausingCalled = true implicit val timeout = TimeUtils.akkaAskTimeout Await.result(dispatcher ? PauseScanning, TimeUtils.awaitDuration) try { while (true) { logger.logPauseOptions() val option: String = System.console.readLine().toLowerCase if (option == "e") throw new InterruptException("Exited the program.") else if (option == "c") throw new ContinueException("Continuing the scan.") else logger.logInvalidPauseOption() } } catch { case InterruptException(msg) => exit() case ContinueException(msg) => resume() } } private def forceExit() = { logger.logScanForceCancelled() System.exit(0) } private def exit() = { logger.logScanCancelled() logger.completedLoggingFuture.andThen { case _ => System.exit(0) } } private def resume() = { dispatcher ! ResumeScanning pausingCalled = false } }