diff --git a/cmd/pemit/README b/cmd/pemit/README new file mode 100644 index 0000000..bc9eb84 --- /dev/null +++ b/cmd/pemit/README @@ -0,0 +1,41 @@ +pemit + +This is a utility to pem-encode data. It requires a PEM type to be +specified via the `-t` flag. Any number of files may be specified on +the command line; alternatively, if no arguments are provided or the +only argument is "-", pemit will read from standard input. + +Example of standard input: + $ dd if=/dev/zero bs=32 count=1 | pemit -t "NULL DATA" + 1+0 records in + 1+0 records out + 32 bytes (32 B) copied, 8.8908e-05 s, 360 kB/s + -----BEGIN NULL DATA----- + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + -----END NULL DATA----- + $ dd if=/dev/zero bs=32 count=1 | pemit -t "NULL DATA" - + 1+0 records in + 1+0 records out + 32 bytes (32 B) copied, 3.1041e-05 s, 1.0 MB/s + -----BEGIN NULL DATA----- + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + -----END NULL DATA----- + +Using files: + $ dd if=/dev/zero of=fileA bs=32 count=1 + 1+0 records in + 1+0 records out + 32 bytes (32 B) copied, 9.0908e-05 s, 352 kB/s + $ dd if=/dev/zero of=fileB bs=32 count=1 + 1+0 records in + 1+0 records out + 32 bytes (32 B) copied, 9.0908e-05 s, 352 kB/s + $ pemit -t NULL\ DATA fileA + -----BEGIN NULL DATA----- + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + -----END NULL DATA----- + $ pemit -t NULL\ DATA fileA fileB + -----BEGIN NULL DATA----- + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAA== + -----END NULL DATA----- diff --git a/cmd/pemit/main.go b/cmd/pemit/main.go new file mode 100644 index 0000000..267e712 --- /dev/null +++ b/cmd/pemit/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "bytes" + "encoding/pem" + "flag" + "fmt" + "io" + "os" + + "github.com/kisom/goutils/assert" + "github.com/kisom/goutils/die" + "github.com/kisom/goutils/lib" +) + +func usage(w io.Writer) { + fmt.Fprintf(w, `Usage: %s [-h] -t type sources + + Flags: + -h Display this help message. + -t type Set the PEM type. This is required. + + Sources may be a list of files or a single '-'. A single dash + (or no arguments) will cause %s to use standard input. +`, lib.ProgName(), lib.ProgName()) +} + +func init() { + flag.Usage = func() { usage(os.Stderr) } +} + +func copyFile(path string, buf *bytes.Buffer) error { + assert.Bool(buf != nil, "buffer should not be nil") + file, err := os.Open(path) + if err != nil { + return err + } + + _, err = io.Copy(buf, file) + file.Close() + return err +} + +func main() { + var pemType string + flag.StringVar(&pemType, "t", "", "Specify the `PEM type`.") + flag.Parse() + + die.When(len(pemType) == 0, "no PEM type specified.") + + buf := &bytes.Buffer{} + argc := flag.NArg() + var err error + + switch { + case argc == 0: + _, err = io.Copy(buf, os.Stdin) + if err != nil { + lib.Err(lib.ExitFailure, err, "failed to read input") + } + case argc == 1: + path := flag.Arg(0) + if path == "-" { + _, err = io.Copy(buf, os.Stdin) + } else { + err = copyFile(path, buf) + } + + if err != nil { + lib.Err(lib.ExitFailure, err, "failed to read input") + } + case argc > 1: + for i := 0; i < argc; i++ { + path := flag.Arg(i) + err = copyFile(path, buf) + if err != nil { + lib.Err(lib.ExitFailure, err, "reading file failed") + } + } + default: + panic("shouldn't be here") + } + + p := &pem.Block{ + Type: pemType, + Bytes: buf.Bytes(), + } + + encoded := string(pem.EncodeToMemory(p)) + fmt.Print(encoded) +}