master
go 74 lines 2.18 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build windows
4
5 package nagios
6
7 import (
8 "fmt"
9 "os"
10 "path/filepath"
11 "strings"
12 )
13
14 // rewriteScriptCommand detects Windows script files (.ps1, .bat, .cmd)
15 // and rewrites the command to invoke them through the appropriate interpreter.
16 // This allows users to set plugin directly to a script path without manually
17 // configuring the interpreter.
18 func rewriteScriptCommand(pluginPath string, args []string) (string, []string, error) {
19 lower := strings.ToLower(pluginPath)
20
21 switch {
22 case strings.HasSuffix(lower, ".ps1"):
23 psPath, err := findPowerShell()
24 if err != nil {
25 return "", nil, fmt.Errorf("plugin '%s' is a PowerShell script but powershell.exe was not found: %w", pluginPath, err)
26 }
27 newArgs := make([]string, 0, 5+len(args))
28 newArgs = append(newArgs, "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", pluginPath)
29 newArgs = append(newArgs, args...)
30 return psPath, newArgs, nil
31
32 case strings.HasSuffix(lower, ".bat"), strings.HasSuffix(lower, ".cmd"):
33 cmdPath, err := findCmd()
34 if err != nil {
35 return "", nil, fmt.Errorf("plugin '%s' is a batch script but cmd.exe was not found: %w", pluginPath, err)
36 }
37 newArgs := make([]string, 0, 2+len(args))
38 newArgs = append(newArgs, "/c", pluginPath)
39 newArgs = append(newArgs, args...)
40 return cmdPath, newArgs, nil
41 }
42
43 return pluginPath, args, nil
44 }
45
46 func findPowerShell() (string, error) {
47 sysRoot := os.Getenv("SystemRoot")
48 if sysRoot == "" {
49 sysRoot = `C:\Windows`
50 }
51 path := filepath.Join(sysRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
52 if _, err := os.Stat(path); err != nil {
53 return "", fmt.Errorf("powershell.exe not found at %s: %w", path, err)
54 }
55 return path, nil
56 }
57
58 func findCmd() (string, error) {
59 // ComSpec is the standard Windows env var pointing to cmd.exe.
60 if comSpec := os.Getenv("ComSpec"); comSpec != "" {
61 if _, err := os.Stat(comSpec); err == nil {
62 return comSpec, nil
63 }
64 }
65 sysRoot := os.Getenv("SystemRoot")
66 if sysRoot == "" {
67 sysRoot = `C:\Windows`
68 }
69 path := filepath.Join(sysRoot, "System32", "cmd.exe")
70 if _, err := os.Stat(path); err != nil {
71 return "", fmt.Errorf("cmd.exe not found at %s: %w", path, err)
72 }
73 return path, nil
74 }