summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/App.java
blob: fdb9ce6888569736623fb36ce8a6c1a51ea1480d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.it_jaros.jscanner;

import com.it_jaros.jscanner.scan.Scan;
import com.it_jaros.jscanner.scan.ScanOptions;
import com.it_jaros.jscanner.scan.Scanner;

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);
        CliPrinter progressBar = new CliPrinter(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
        }
    }
}