-
Notifications
You must be signed in to change notification settings - Fork 41
/
ncdt.go
151 lines (126 loc) · 3.69 KB
/
ncdt.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import "github.com/namecoin/ncdns/ncdomain"
import "github.com/namecoin/ncdns/namecoin"
import "flag"
import "fmt"
import "os"
import "strconv"
import "io/ioutil"
import "github.com/namecoin/btcd/rpcclient"
import "github.com/namecoin/ncdns/util"
var rpchost = flag.String("rpchost", "", "Namecoin RPC host:port")
var rpcuser = flag.String("rpcuser", "", "Namecoin RPC username")
var rpcpass = flag.String("rpcpass", "", "Namecoin RPC password")
var rpccookiepath = flag.String("rpccookiepath", "", "Namecoin RPC cookie path (used if password is unspecified)")
var conn *namecoin.Client
func usage() {
fmt.Fprintf(os.Stderr, "Usage: ncdt [options] <d/example> <JSON value> [<d/imported-example> <JSON value> ...]\n")
fmt.Fprintf(os.Stderr, "Specify @filename for JSON value to read file, @N to read fd N (@0: stdin), @ to get via RPC\n")
fmt.Fprintf(os.Stderr, "Options:\n")
fmt.Fprintf(os.Stderr, " -rpchost=host:port Namecoin RPC server address } only required for RPC retrieval\n")
fmt.Fprintf(os.Stderr, " -rpcuser=username Namecoin RPC username }\n")
fmt.Fprintf(os.Stderr, " -rpcpass=password Namecoin RPC password }\n")
fmt.Fprintf(os.Stderr, " -rpccookiepath=path Namecoin RPC cookie path }\n")
os.Exit(2)
}
func translateValue(k, v string) (string, error) {
if len(v) == 0 || v[0] != '@' {
return v, nil
}
v = v[1:]
var f *os.File
var err error
if v[0] >= '0' && v[0] < '9' {
var n uint64
n, err = strconv.ParseUint(v, 10, 31)
if err != nil {
return "", err
}
f = os.NewFile(uintptr(n), "-")
} else if len(v) == 1 {
return conn.NameQuery(k, "")
} else {
f, err = os.Open(v)
}
if err != nil {
return "", err
}
defer f.Close()
contents, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
return string(contents), nil
}
func main() {
flag.CommandLine.Usage = usage
flag.Parse()
args := flag.Args()
names := map[string]string{}
var primaryK, primaryV string
if len(args)%2 != 0 || len(args) < 2 {
usage()
}
// Connect to local namecoin core RPC server using HTTP POST mode.
connCfg := &rpcclient.ConnConfig{
Host: *rpchost,
User: *rpcuser,
Pass: *rpcpass,
CookiePath *rpccookiepath,
HTTPPostMode: true, // Namecoin core only supports HTTP POST mode
DisableTLS: true, // Namecoin core does not provide TLS by default
}
var err error
// Notice the notification parameter is nil since notifications are
// not supported in HTTP POST mode.
conn, err = namecoin.New(connCfg, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating RPC client: %v\n", err)
os.Exit(1)
}
defer conn.Shutdown()
for i := 0; i+1 < len(args); i += 2 {
k := args[i]
v := args[i+1]
if _, ok := names[k]; ok {
fmt.Fprintf(os.Stderr, "duplicate name specified: %s\n", k)
os.Exit(1)
}
v, err := translateValue(k, v)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to translate value: %v\n", err)
os.Exit(1)
}
if i == 0 {
primaryK, primaryV = k, v
}
names[k] = v
}
value := ncdomain.ParseValue(primaryK, primaryV, func(k string) (string, error) {
v, ok := names[k]
if !ok {
return "", fmt.Errorf("reference to unknown name")
}
return v, nil
}, func(err error, isWarning bool) {
if isWarning {
fmt.Fprintf(os.Stderr, "Warning: %v\n", err)
} else {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
})
suffix, err := util.NamecoinKeyToBasename(primaryK)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid key: %s\n", primaryK)
os.Exit(1)
}
suffix += ".bit."
rrs, err := value.RRsRecursive(nil, suffix, suffix)
if err != nil {
fmt.Printf("Error generating RRs: %v\n", err)
os.Exit(1)
}
for _, rr := range rrs {
fmt.Println(rr.String())
}
}