-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmd.go
127 lines (111 loc) · 2.6 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"flag"
"fmt"
"github.com/pkg/errors"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"roob.re/omemo-wget/aesgcm"
"strings"
)
func main() {
outfile := flag.String("o", "", "out file. Use '-' for stdout. Defaults to guess from input uri/path")
xdgopen := flag.Bool("x", false, "Open resulting file with xdg-open")
flag.Parse()
if flag.NArg() < 1 {
stderrExit(errors.New(fmt.Sprintf("Usage: %s <path/to/file|uri#hash> [hash] [-o out]\n", os.Args[0])), 1)
return
}
uri := flag.Args()[0]
var hash string
parts := strings.Split(uri, "#")
path := parts[0]
if len(parts) >= 2 {
hash = parts[1]
} else if flag.NArg() >= 2 {
hash = flag.Args()[1]
} else {
stderrExit(errors.New("hash must be either included in the url (after the # character) or provided as a second argument"), 2)
return
}
in, err := open(path)
if err != nil {
stderrExit(err, 3)
return
}
fileContents, err := ioutil.ReadAll(in)
if err != nil {
stderrExit(err, 4)
return
}
_ = in.Close()
decryptedContents, err := aesgcm.Decrypt(fileContents, hash)
if err != nil {
panic(err)
}
var out io.WriteCloser
switch *outfile {
case "-":
out = os.Stdout
*xdgopen = false
case "":
// Generate a suitable name
basename := filepath.Base(path)
ext := filepath.Ext(basename)
for _, err := os.Stat(basename); err == nil; _, err = os.Stat(basename) {
basename = strings.Replace(basename, ext, "_decrypted"+ext, 1)
}
*outfile = basename
fallthrough
default:
f, err := os.Create(*outfile)
if err != nil {
stderrExit(errors.New("error creating output file: "+err.Error()), 6)
return
}
out = f
}
_, err = out.Write(decryptedContents)
if err != nil {
stderrExit(errors.New("error writing to output file: "+err.Error()), 6)
return
}
_ = out.Close()
if *xdgopen {
cmd := exec.Command("xdg-open", *outfile)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
log.Println(err)
}
}
}
func open(uri string) (io.ReadCloser, error) {
switch true {
case strings.HasPrefix(uri, "aesgcm"):
uri = strings.Replace(uri, "aesgcm", "https", 1)
fallthrough
case strings.HasPrefix(uri, "https"):
resp, err := http.Get(uri)
if err != nil {
return nil, errors.New(fmt.Sprintf("error fetching '%s': %s", uri, err.Error()))
}
return resp.Body, nil
default:
file, err := os.Open(uri)
if err != nil {
return nil, errors.New(fmt.Sprintf("could not open file '%s': %s", uri, err.Error()))
}
return file, nil
}
}
func stderrExit(e error, code int) {
_, _ = fmt.Fprint(os.Stderr, e.Error()+"\n")
os.Exit(code)
}