From 743502a8ecec439e1fbf9a8f05f8d9e4d95c8b43 Mon Sep 17 00:00:00 2001 From: rsteube Date: Thu, 19 Oct 2023 15:40:54 +0200 Subject: [PATCH] ActionUsedPorts: support windows --- pkg/actions/net/port.go | 72 ++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/pkg/actions/net/port.go b/pkg/actions/net/port.go index 2791583924..01b9fc61b9 100644 --- a/pkg/actions/net/port.go +++ b/pkg/actions/net/port.go @@ -1,7 +1,7 @@ package net import ( - "os/exec" + "runtime" "strings" "github.com/rsteube/carapace" @@ -52,26 +52,62 @@ func ActionKnownPorts() carapace.Action { // 8000 (used by: python) func ActionUsedPorts() carapace.Action { return carapace.ActionCallback(func(c carapace.Context) carapace.Action { - // TODO support other tools - if _, err := exec.LookPath("lsof"); err == nil { - return carapace.ActionExecCommand("lsof", "-i", "-P", "-n")(func(output []byte) carapace.Action { - lines := strings.Split(string(output), "\n") + switch runtime.GOOS { + case "darwin", "linux": + return actionUsedPortsLsof() + case "windows": + return actionUsedPortsNetstat() + default: + return carapace.ActionValues() + } + }).Tag("used ports") +} + +func actionUsedPortsLsof() carapace.Action { + return carapace.ActionExecCommand("lsof", "-i", "-P", "-n")(func(output []byte) carapace.Action { + lines := strings.Split(string(output), "\n") + + vals := make([]string, 0) + for _, line := range lines { + if fields := strings.Fields(line); len(fields) > 9 { + if fields[len(fields)-1] != "(LISTEN)" { + continue + } - vals := make([]string, 0) - for _, line := range lines { - if fields := strings.Fields(line); len(fields) > 9 { - if fields[len(fields)-1] != "(LISTEN)" { - continue - } + if splitted := strings.Split(fields[len(fields)-2], ":"); len(splitted) > 1 { + vals = append(vals, splitted[len(splitted)-1], "used by: "+fields[0]) + } + } + } + return carapace.ActionValuesDescribed(vals...).Style(style.Carapace.KeywordNegative) + }) +} - if splitted := strings.Split(fields[len(fields)-2], ":"); len(splitted) > 1 { - vals = append(vals, splitted[len(splitted)-1], "used by: "+fields[0]) - } +func actionUsedPortsNetstat() carapace.Action { + return carapace.ActionExecCommand("netstat", "-abon")(func(output []byte) carapace.Action { + lines := strings.Split(string(output), "\n") + vals := make([]string, 0) + for index, line := range lines { + if fields := strings.Fields(line); len(fields) > 3 { + switch { + case fields[3] != "LISTENING": + continue + case fields[0] != "TCP" && fields[0] != "UDP": + continue + } + + if splitted := strings.Split(fields[1], ":"); len(splitted) > 1 { + executable := lines[index-1] + switch { + case strings.HasPrefix(executable, "["): + executable = executable[1 : len(executable)-1] + default: + executable = "unknown" } + vals = append(vals, splitted[1], "used by: "+executable) } - return carapace.ActionValuesDescribed(vals...).Style(style.Carapace.KeywordNegative) - }) + } } - return carapace.ActionValues() - }).Tag("used ports") + return carapace.ActionValuesDescribed(vals...).Style(style.Carapace.KeywordNegative) + }) }