-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathutil.go
155 lines (127 loc) · 3.32 KB
/
util.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
152
153
154
155
// util provides a number of utility functions.
package main
import (
"fmt"
"io/ioutil"
"log"
"sort"
"time"
tor "git.torproject.org/user/phw/zoossh.git"
)
// RouterStatusSorter implements the sort interface to sort router statuses by
// different criteria.
type RouterStatusSorter struct {
RouterStatuses []tor.GetStatus
By func(i, j tor.GetStatus) bool
}
type By func(i, j tor.GetStatus) bool
// Sort sorts by the criteria of the given method receiver.
func (by By) Sort(statuses []tor.GetStatus) {
rss := &RouterStatusSorter{
RouterStatuses: statuses,
By: by,
}
sort.Sort(rss)
}
// Implement the sort interface (1/3).
func (rss *RouterStatusSorter) Len() int {
return len(rss.RouterStatuses)
}
// Implement the sort interface (2/3).
func (rss *RouterStatusSorter) Swap(i int, j int) {
rss.RouterStatuses[i], rss.RouterStatuses[j] = rss.RouterStatuses[j], rss.RouterStatuses[i]
}
// Implement the sort interface (3/3).
func (rss *RouterStatusSorter) Less(i int, j int) bool {
return rss.By(rss.RouterStatuses[i], rss.RouterStatuses[j])
}
// getOutputDir returns the directory to which files can be written to. If it
// is not set by the user, we randomly generate a new one in /tmp/.
func getOutputDir() (string, error) {
var err error
// The user did not point us to a directory, so we have to create a new
// one.
if outputDir == "" {
fileName := fmt.Sprintf("sybilhunter_%s_", time.Now().Format(timeLayout))
outputDir, err = ioutil.TempDir("/tmp/", fileName)
if err != nil {
return "", err
}
log.Printf("Created output directory \"%s\".\n", outputDir)
}
return outputDir, nil
}
// writeStringToFile writes the given string blurb to a randomly generated file
// with the given string prefix. The file is placed in the output directory
// which can bet set by the user.
func writeStringToFile(fileName string, content string) error {
directory, err := getOutputDir()
if err != nil {
return err
}
fd, err := ioutil.TempFile(directory, fmt.Sprintf("%s_", fileName))
if err != nil {
return err
}
fmt.Fprint(fd, content)
log.Printf("Wrote %d-byte string to \"%s\".\n", len(content), fd.Name())
return nil
}
// MaxUInt64 returns the larger of the two given integers.
func MaxUInt64(a, b uint64) uint64 {
if a > b {
return a
} else {
return b
}
}
// MinUInt64 returns the smaller of the two given integers.
func MinUInt64(a, b uint64) uint64 {
if a < b {
return a
} else {
return b
}
}
// MaxUInt16 returns the larger of the two given integers.
func MaxUInt16(a, b uint16) uint16 {
if a > b {
return a
} else {
return b
}
}
// MinUInt16 returns the smaller of the two given integers.
func MinUInt16(a, b uint16) uint16 {
if a < b {
return a
} else {
return b
}
}
// RouterFlagsToString converts a RouterFlags struct to a constant-size string
// containing a series of bits.
func RouterFlagsToString(flags *tor.RouterFlags) string {
// Convert a boolean value to 1 or 0.
b2i := func(flag bool) int {
if flag == true {
return 1
} else {
return 0
}
}
return fmt.Sprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d",
b2i(flags.Authority),
b2i(flags.BadExit),
b2i(flags.Exit),
b2i(flags.Fast),
b2i(flags.Guard),
b2i(flags.HSDir),
b2i(flags.Named),
b2i(flags.Stable),
b2i(flags.Running),
b2i(flags.Unnamed),
b2i(flags.Valid),
b2i(flags.V2Dir),
b2i(flags.Authority))
}