Allow the binary to be symlinked to its toolnames 'ctfetch' and 'ctail'

This commit is contained in:
2026-04-06 01:40:52 +02:00
parent ba7f0dcb9f
commit 097c33b478
4 changed files with 34 additions and 7 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
/ctool /ctool
/ctfetch
/ctail

View File

@@ -18,12 +18,13 @@ func runFetch(args []string) {
logsListURL := fs.String("logs-list-url", "https://www.gstatic.com/ct/log_list/v3/all_logs_list.json", "URL of the CT log list JSON") logsListURL := fs.String("logs-list-url", "https://www.gstatic.com/ct/log_list/v3/all_logs_list.json", "URL of the CT log list JSON")
monitoringURL := fs.String("monitoring-url", "", "log root URL for issuer lookups when input is a file") monitoringURL := fs.String("monitoring-url", "", "log root URL for issuer lookups when input is a file")
fs.Usage = func() { fs.Usage = func() {
n := cmdName("fetch")
fmt.Fprintf(os.Stderr, "Usage:\n") fmt.Fprintf(os.Stderr, "Usage:\n")
fmt.Fprintf(os.Stderr, " ctool fetch [flags] <log-url> <leaf-index> [+sct] [+issuer] [+ctlog] [+all] fetch one entry\n") fmt.Fprintf(os.Stderr, " %s [flags] <log-url> <leaf-index> [+sct] [+issuer] [+ctlog] [+all] fetch one entry\n", n)
fmt.Fprintf(os.Stderr, " ctool fetch [flags] <tile-url-or-file> [+sct] [+issuer] [+ctlog] [+all] dump all entries in a tile\n") fmt.Fprintf(os.Stderr, " %s [flags] <tile-url-or-file> [+sct] [+issuer] [+ctlog] [+all] dump all entries in a tile\n", n)
fmt.Fprintf(os.Stderr, "\nExamples:\n") fmt.Fprintf(os.Stderr, "\nExamples:\n")
fmt.Fprintf(os.Stderr, " ctool fetch https://halloumi2026h1.mon.ct.ipng.ch 629794635 +all\n") fmt.Fprintf(os.Stderr, " %s https://halloumi2026h1.mon.ct.ipng.ch 629794635 +all\n", n)
fmt.Fprintf(os.Stderr, " ctool fetch https://halloumi2026h1.mon.ct.ipng.ch/tile/data/x002/x460/135 +sct\n") fmt.Fprintf(os.Stderr, " %s https://halloumi2026h1.mon.ct.ipng.ch/tile/data/x002/x460/135 +sct\n", n)
fmt.Fprintf(os.Stderr, "\nFlags:\n") fmt.Fprintf(os.Stderr, "\nFlags:\n")
fs.PrintDefaults() fs.PrintDefaults()
} }

View File

@@ -31,11 +31,12 @@ func runTail(args []string) {
rateLimitFlag := fs.Duration("rate-limit", 2*time.Second, "minimum time between HTTP requests (minimum 100ms)") rateLimitFlag := fs.Duration("rate-limit", 2*time.Second, "minimum time between HTTP requests (minimum 100ms)")
fs.StringVar(&userAgent, "user-agent", "ctool/"+version+" (https://git.ipng.ch/certificate-transparency/)", "User-Agent header for HTTP requests") fs.StringVar(&userAgent, "user-agent", "ctool/"+version+" (https://git.ipng.ch/certificate-transparency/)", "User-Agent header for HTTP requests")
fs.Usage = func() { fs.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: ctool tail [flags] <log-url>\n") n := cmdName("tail")
fmt.Fprintf(os.Stderr, "Usage: %s [flags] <log-url>\n", n)
fmt.Fprintf(os.Stderr, "\nPrints a one-liner per cert/pre-cert as new entries arrive in a Static CT log.\n") fmt.Fprintf(os.Stderr, "\nPrints a one-liner per cert/pre-cert as new entries arrive in a Static CT log.\n")
fmt.Fprintf(os.Stderr, "\nExamples:\n") fmt.Fprintf(os.Stderr, "\nExamples:\n")
fmt.Fprintf(os.Stderr, " ctool tail https://halloumi2026h2.mon.ct.ipng.ch\n") fmt.Fprintf(os.Stderr, " %s https://halloumi2026h2.mon.ct.ipng.ch\n", n)
fmt.Fprintf(os.Stderr, " ctool tail --from-leaf 0 --interval 10s https://halloumi2026h2.mon.ct.ipng.ch\n") fmt.Fprintf(os.Stderr, " %s --from-leaf 0 --interval 10s https://halloumi2026h2.mon.ct.ipng.ch\n", n)
fmt.Fprintf(os.Stderr, "\nFlags:\n") fmt.Fprintf(os.Stderr, "\nFlags:\n")
fs.PrintDefaults() fs.PrintDefaults()
} }

View File

@@ -8,11 +8,23 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings"
) )
const version = "0.1.0" const version = "0.1.0"
func main() { func main() {
// Busybox-style: if invoked as "ctfetch" or "ctail", shortcut to that command.
switch strings.TrimSuffix(filepath.Base(os.Args[0]), filepath.Ext(os.Args[0])) {
case "ctfetch":
runFetch(os.Args[1:])
return
case "ctail":
runTail(os.Args[1:])
return
}
if len(os.Args) < 2 { if len(os.Args) < 2 {
usage() usage()
os.Exit(1) os.Exit(1)
@@ -42,3 +54,14 @@ func fatal(format string, args ...any) {
fmt.Fprintf(os.Stderr, "Error: "+format+"\n", args...) fmt.Fprintf(os.Stderr, "Error: "+format+"\n", args...)
os.Exit(1) os.Exit(1)
} }
// cmdName returns the effective command name for usage messages.
// When invoked via a symlink (e.g. "ctfetch"), it returns that name directly.
// Otherwise it returns "ctool <sub>" (e.g. "ctool fetch").
func cmdName(sub string) string {
base := strings.TrimSuffix(filepath.Base(os.Args[0]), filepath.Ext(os.Args[0]))
if base == "ctool" {
return "ctool " + sub
}
return base
}