package com.it_jaros.jscanner; import java.io.IOException; import java.util.concurrent.CountDownLatch; public class App { private static Thread shutdownHook; private static final CountDownLatch shutdownLatch = new CountDownLatch(1); private static int exitCode = 0; public static void main(String[] args) { try { run(args); } catch (HelpRequested e) { // Do nothing } catch (Exception e) { System.err.println(e.getMessage()); } finally { shutdownLatch.countDown(); removeShutdownHook(); } System.exit(exitCode); } private static void run(String[] args) throws Exception { ScanOptions options = parseOptions(args); try (Scanner scanner = new Scanner(options)) { runScan(scanner, options); } } private static void runScan(Scanner scanner, ScanOptions options) throws IOException { addShutdownHook(scanner); Scan scan = Scan.create(options); ProgressBar progressBar = new ProgressBar(scan, options.quiet()); progressBar.start(); scanner.runScan(scan, result -> progressBar.printResult(result, options.showFilteredPorts())); progressBar.stop(); } private static ScanOptions parseOptions(String[] args) { CliParser cliParser = new CliParser(); try { return cliParser.parseArgs(args); } catch (IllegalArgumentException e) { cliParser.printUsageHelp(); exitCode = 1; throw e; } } /** * Notice user that the signal was received * Start shutdown of scanner * * @param scanner */ private static void addShutdownHook(Scanner scanner) { shutdownHook = new Thread(() -> { System.err.printf("%nCtrl-C received. Shutting down...%n"); shutdown(scanner); }); Runtime.getRuntime().addShutdownHook(shutdownHook); } /** * Try to gracefully shutdown scanner * and wait * * @param scanner */ private static void shutdown(Scanner scanner) { try { scanner.cancel(); shutdownLatch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (Exception e) { // Time ran out } } private static void removeShutdownHook() { if (shutdownHook == null) { return; } try { Runtime.getRuntime().removeShutdownHook(shutdownHook); } catch (IllegalStateException ignored) { // JVM is already shutting down } } }