mirror of
https://github.com/FiloSottile/age.git
synced 2026-09-20 15:04:26 +00:00
@@ -0,0 +1,125 @@
|
||||
// Copyright 2025 The age Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
|
||||
"filippo.io/age/internal/inspect"
|
||||
)
|
||||
|
||||
const usage = `Usage:
|
||||
age-inspect [--json] [INPUT]
|
||||
|
||||
Options:
|
||||
--json Output machine-readable JSON.
|
||||
|
||||
INPUT defaults to standard input. "-" may be used as INPUT to explicitly
|
||||
read from standard input.`
|
||||
|
||||
func main() {
|
||||
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
|
||||
|
||||
var (
|
||||
versionFlag bool
|
||||
jsonFlag bool
|
||||
)
|
||||
|
||||
flag.BoolVar(&versionFlag, "version", false, "print the version")
|
||||
flag.BoolVar(&jsonFlag, "json", false, "output machine-readable JSON")
|
||||
flag.Parse()
|
||||
|
||||
if versionFlag {
|
||||
if buildInfo, ok := debug.ReadBuildInfo(); ok {
|
||||
fmt.Println(buildInfo.Main.Version)
|
||||
return
|
||||
}
|
||||
fmt.Println("(unknown)")
|
||||
return
|
||||
}
|
||||
|
||||
if flag.NArg() > 1 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
in := os.Stdin
|
||||
var fileSize int64 = -1
|
||||
if name := flag.Arg(0); name != "" && name != "-" {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
errorf("failed to open input file %q: %v", name, err)
|
||||
}
|
||||
defer f.Close()
|
||||
in = f
|
||||
if stat, err := f.Stat(); err == nil && stat.Mode().IsRegular() {
|
||||
fileSize = stat.Size()
|
||||
}
|
||||
}
|
||||
|
||||
data, err := inspect.Inspect(in, fileSize)
|
||||
if err != nil {
|
||||
errorf("inspection failed: %v", err)
|
||||
}
|
||||
|
||||
if jsonFlag {
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
if err := enc.Encode(data); err != nil {
|
||||
errorf("failed to encode JSON output: %v", err)
|
||||
}
|
||||
} else {
|
||||
name := flag.Arg(0)
|
||||
if name == "" {
|
||||
name = "<stdin>"
|
||||
}
|
||||
fmt.Printf("%s is an age file, version %q.\n", name, data.Version)
|
||||
fmt.Printf("\n")
|
||||
if data.Armor {
|
||||
fmt.Printf("This file is ASCII-armored.\n")
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
fmt.Printf("This file is encrypted to the following recipient types:\n")
|
||||
for _, t := range data.StanzaTypes {
|
||||
fmt.Printf(" - %q\n", t)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
switch data.Postquantum {
|
||||
case "yes":
|
||||
fmt.Printf("This file uses post-quantum encryption.\n")
|
||||
fmt.Printf("\n")
|
||||
case "no":
|
||||
fmt.Printf("This file does NOT use post-quantum encryption.\n")
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
fmt.Printf("Size breakdown (assuming it decrypts successfully):\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf(" Header % 12d bytes\n", data.Sizes.Header)
|
||||
if data.Armor {
|
||||
fmt.Printf(" Armor overhead % 12d bytes\n", data.Sizes.Armor)
|
||||
}
|
||||
fmt.Printf(" Encryption overhead % 12d bytes\n", data.Sizes.Overhead)
|
||||
fmt.Printf(" Payload % 12d bytes\n", data.Sizes.MinPayload)
|
||||
fmt.Printf(" -------------------\n")
|
||||
total := data.Sizes.Header + data.Sizes.Overhead + data.Sizes.MinPayload + data.Sizes.Armor
|
||||
fmt.Printf(" Total % 12d bytes\n", total)
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("Tip: for machine-readable output, use --json.\n")
|
||||
}
|
||||
}
|
||||
|
||||
// l is a logger with no prefixes.
|
||||
var l = log.New(os.Stderr, "", 0)
|
||||
|
||||
func errorf(format string, v ...interface{}) {
|
||||
l.Printf("age-inspect: error: "+format, v...)
|
||||
l.Printf("age-inspect: report unexpected or unhelpful errors at https://filippo.io/age/report")
|
||||
os.Exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user