forked from aler9/dctk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
various.go
133 lines (111 loc) · 2.94 KB
/
various.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
package dctoolkit
import (
"encoding/base32"
"fmt"
"io"
"math/rand"
"net"
"regexp"
"strconv"
"strings"
"time"
)
const reStrNick = "[^\\$ \\|\n]+"
const reStrAddress = "[a-z0-9\\.-_]+"
const reStrIp = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"
const reStrPort = "[0-9]{1,5}"
const reStrTTH = "[A-Z0-9]{39}"
var reSharedCmdAdcGet = regexp.MustCompile("^((file|tthl) TTH/(" + reStrTTH + ")|file files.xml.bz2) ([0-9]+) (-1|[0-9]+)( ZL1)?$")
var reSharedCmdAdcSnd = regexp.MustCompile("^((file|tthl) TTH/(" + reStrTTH + ")|file files.xml.bz2) ([0-9]+) ([0-9]+)( ZL1)?$")
const dirTTH = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
var errorTerminated = fmt.Errorf("terminated")
var errorArgsFormat = fmt.Errorf("not formatted correctly")
// base32 without padding, which can be one or multiple =
func dcBase32Encode(in []byte) string {
return strings.TrimRight(base32.StdEncoding.EncodeToString(in), "=")
}
// base32 without padding, which can be one or multiple =
func dcBase32Decode(in string) []byte {
// add missing padding
if (len(in) % 8) != 0 {
mlen := (8 - (len(in) % 8))
for n := 0; n < mlen; n++ {
in += "="
}
}
out, _ := base32.StdEncoding.DecodeString(in)
return out
}
func dcReadableQuery(request string) string {
if strings.HasPrefix(request, "tthl TTH/") {
return "tthl/" + strings.TrimPrefix(request, "tthl TTH/")
}
if strings.HasPrefix(request, "file TTH/") {
return "tth/" + strings.TrimPrefix(request, "file TTH/")
}
return "filelist"
}
func randomInt(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max-min) + min
}
func numtoa(num interface{}) string {
return fmt.Sprintf("%d", num)
}
func atoi(s string) int {
ret, _ := strconv.Atoi(s)
return ret
}
func atoui(s string) uint {
ret, _ := strconv.ParseUint(s, 10, 64)
return uint(ret)
}
func atoui64(s string) uint64 {
ret, _ := strconv.ParseUint(s, 10, 64)
return ret
}
func atoi64(s string) int64 {
ret, _ := strconv.ParseInt(s, 10, 64)
return ret
}
type connEstablisher struct {
Wait chan struct{}
Conn net.Conn
Error error
}
func newConnEstablisher(address string, timeout time.Duration, retries uint) *connEstablisher {
ce := &connEstablisher{
Wait: make(chan struct{}, 1),
}
go func() {
ce.Conn, ce.Error = connWithTimeoutAndRetries(address, timeout, retries)
ce.Wait <- struct{}{}
}()
return ce
}
func connWithTimeoutAndRetries(address string, timeout time.Duration, retries uint) (net.Conn, error) {
var err error
for i := uint(0); i < retries; i++ {
var conn net.Conn
conn, err = net.DialTimeout("tcp4", address, timeout)
if err == nil {
return conn, nil
}
}
return nil, err
}
type bytesWriteCloser struct {
buf []byte
offset int
}
func newBytesWriteCloser(buf []byte) io.WriteCloser {
return &bytesWriteCloser{buf: buf}
}
func (rc *bytesWriteCloser) Write(in []byte) (int, error) {
n := copy(rc.buf[rc.offset:], in)
rc.offset += n
return n, nil
}
func (rc *bytesWriteCloser) Close() error {
return nil
}