summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/CliPrinter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/CliPrinter.java')
-rw-r--r--src/main/java/com/it_jaros/jscanner/CliPrinter.java258
1 files changed, 0 insertions, 258 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/CliPrinter.java b/src/main/java/com/it_jaros/jscanner/CliPrinter.java
deleted file mode 100644
index 709c3dd..0000000
--- a/src/main/java/com/it_jaros/jscanner/CliPrinter.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package com.it_jaros.jscanner;
-
-import com.it_jaros.jscanner.scan.Scan;
-import com.it_jaros.jscanner.scan.domain.ScanFailure;
-import com.it_jaros.jscanner.scan.domain.ScanResult;
-import com.it_jaros.jscanner.scan.service.ServiceType;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-public class CliPrinter {
-
- private final ScheduledExecutorService ui = Executors.newSingleThreadScheduledExecutor();
- private final Scan scan;
- private final boolean quiet;
- private final Object outputLock = new Object();
-
- public CliPrinter(Scan scan, boolean quiet) {
- this.scan = scan;
- this.quiet = quiet;
- }
-
- private void clearStatusLine() {
- System.err.print("\r\033[2K");
- System.err.flush();
- }
-
- public void printResult(ScanResult result, boolean showFilteredPorts) {
- synchronized (outputLock) {
- if (result.openPorts().isEmpty()
- && (!showFilteredPorts || result.filteredPorts().isEmpty())
- && result.errors().isEmpty()) {
- return;
- }
-
- clearStatusLine();
- printErrors(result);
- printPortsResults(result, showFilteredPorts);
- printStatusLine();
- }
- }
-
- private void printErrors(ScanResult result) {
- if (result.errors().isEmpty()) return;
-
- StringBuilder sb = new StringBuilder();
- sb.append(String.format(
- "%s | errors: %d%n",
- result.host(),
- result.errors().size()
- ));
- String errors = result.errors().stream().map((ScanFailure error) -> String.format(
- "\t%s: %s, %s",
- error.port(),
- error.exception().type(),
- error.exception().message()
- )).collect(Collectors.joining("\n"));
- sb.append(errors);
- sb.append("\n");
-
- System.err.println(sb);
- System.err.flush();
- }
-
- private void printPortsResults(ScanResult result, boolean showFilteredPorts) {
- if (result.openPorts().isEmpty() && (!showFilteredPorts || result.filteredPorts().isEmpty())) {
- return;
- }
-
- StringBuilder sb = new StringBuilder();
- sb.append(result.host());
- sb.append("\n");
- if (!result.openPorts().isEmpty()) {
- sb.append(
- String.format("\t (%d) open:\t%s%n", result.openPorts().size(), map(result.openPorts().getPorts(), result.bannerRecognition()))
- );
- }
- if (showFilteredPorts && !result.filteredPorts().isEmpty()) {
- sb.append(
- String.format("\t (%d) filtered:\t%s%n", result.filteredPorts().size(), map(result.filteredPorts().getPorts()))
- );
- }
- sb.append("\n");
- System.out.println(sb);
- System.out.flush();
- }
-
- private static String map(List<Integer> ports) {
- return ports.stream().map(String::valueOf).collect(Collectors.joining(","));
- }
-
- private static String map(List<Integer> ports, Map<Integer, ServiceType> bannerRecognition) {
- return ports.stream().map(port -> {
- ServiceType serviceType = bannerRecognition.getOrDefault(port, ServiceType.UNKNOWN);
-
- if (serviceType == ServiceType.UNKNOWN) {
- return String.valueOf(port);
- }
-
- return port + "/" + serviceType.name().toLowerCase();
- }).collect(Collectors.joining(","));
- }
-
- private static int getColumnWidth() {
- try {
- Process process = new ProcessBuilder("sh", "-c", "stty size < /dev/tty").start();
-
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(process.getInputStream()))) {
- String line = reader.readLine();
- if (line != null && !line.isBlank()) {
- Matcher matcher = Pattern.compile("^\\d+\\s+(\\d+)").matcher(line.trim());
- if (matcher.matches()) {
- return Integer.parseInt(matcher.group(1));
- }
- }
- }
- } catch (Exception ignored) {
- // does not matter why it did not work
- }
-
- return 120;
- }
-
- public void start() {
- if (quiet) {
- return;
- }
-
- // although we don't print anything, we still need to
- // gc all the done hosts
- System.err.print("Scanning targets...\n\n");
- ui.scheduleAtFixedRate(() -> {
- synchronized (outputLock) {
- printStatusLine();
- }
- }, 1, 1000, TimeUnit.MILLISECONDS);
- }
-
- public void stop() {
- ui.shutdownNow();
- try {
- ui.awaitTermination(1, TimeUnit.SECONDS);
- } catch (InterruptedException ignored) {
- Thread.currentThread().interrupt();
- }
- clearStatusLine();
- printStats();
- }
-
- private void printStats() {
- Scan.Statistics stats = scan.getStatistics();
- System.err.println("\n--------------------");
- System.err.println("Stats:");
- System.err.println("Total hosts: " + stats.hostTotal());
- System.err.println("Total ports: " + stats.portTotal());
- System.err.println("Duration: " + formatDuration(stats.durationInMillis()));
- System.err.println("Peak concurrent hosts: " + stats.hostMaxConcurrent());
- System.err.println("Peak concurrent sockets: " + stats.socketMaxConcurrent());
- System.err.println("Peak concurrent workers: " + stats.threadMaxConcurrent());
- System.err.println("--------------------\n");
- }
-
- private static String formatDuration(long millis) {
- if (millis <= 0) return "";
- long seconds = millis / 1000 % 60;
- long minutes = millis / 60000 % 60;
- long hours = millis / 3600000 % 24;
- long days = millis / 86400000;
-
- if (days > 0) return String.format("%dd %dh:%dm:%ds", days, hours, minutes, seconds);
- if (hours > 0) return String.format("%dh:%dm:%ds", hours, minutes, seconds);
- if (minutes > 0) return String.format("%dm:%ds", minutes, seconds);
- return String.format("%ds", seconds);
- }
-
-
- private void printStatusLine() {
- Scan.Statistics stats = scan.getStatistics();
- int total = stats.hostTotal();
- int running = stats.hostCurrent();
- int done = total - running;
- long percent = total == 0 ? 100 : done * 100L / total;
-
- String hostStat = String.format(
- "hosts: %d running, %d done",
- running,
- done
- );
- String portStat = String.format(
- " | ports: %d total",
- stats.portTotal()
- );
- String durationStat = String.format(
- " | %s",
- formatDuration(stats.durationInMillis())
- );
- String socketStat = String.format(
- " | sockets: %d active, %d peak",
- stats.socketCurrent(),
- stats.socketMaxConcurrent()
- );
- String workerStat = String.format(
- " | workers: %d active, %d peak",
- stats.threadCurrent(),
- stats.threadMaxConcurrent()
- );
-
- int availableWidth = CliPrinter.getColumnWidth();
- String statusLine = appendIfEnoughSpace("", availableWidth, hostStat, portStat, durationStat, socketStat, workerStat);
-
- String barFormat = " [%s] %3d%%";
- int remainingWidth = availableWidth - statusLine.length() - barFormat.length();
- if (remainingWidth > 0) {
- String progressBar = String.format(
- barFormat,
- progressBar(percent, remainingWidth),
- percent
- );
- statusLine = appendIfEnoughSpace(statusLine, availableWidth, progressBar);
- }
-
- remainingWidth = availableWidth - statusLine.length();
- if (remainingWidth > 0) {
- statusLine += " ".repeat(remainingWidth);
- }
- System.err.print("\r" + statusLine);
- System.err.flush();
- }
-
- private String appendIfEnoughSpace(String current, int availableSize, String... additional) {
- StringBuilder builder = new StringBuilder(current);
- for (String add : additional) {
- if ((builder.length() + add.length()) <= availableSize) {
- builder.append(add);
- }
- }
-
- return builder.toString();
- }
-
- private static String progressBar(long percent, int width) {
- if (width <= 0) {
- return "";
- }
-
- int filled = (int) (percent * width / 100);
- return "#".repeat(filled) + "-".repeat(width - filled);
- }
-}