summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..a4f31c3
--- /dev/null
+++ b/main.go
@@ -0,0 +1,75 @@
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+)
+
+var wg sync.WaitGroup
+
+func Emit(pt Point) {
+ if pt == nil {
+ return
+ }
+ fmt.Println(pt)
+}
+
+func DoHostfile(fname string) {
+ defer wg.Done()
+ hostname := filepath.Base(fname)
+ cfg, err := readConfigFile(fname)
+ if err != nil {
+ Emit(NewPoint("public", map[string]string{"host":hostname}, map[string]interface{}{"error": err.Error()}))
+ return
+ }
+ for _, address := range getAddresses(cfg) {
+ wg.Add(2)
+ go Emit(DoAddress(hostname, "tcp4", address))
+ go Emit(DoAddress(hostname, "tcp6", address))
+ }
+}
+
+func DoAddress(host, network, address string) Point {
+ defer wg.Done()
+ tags := map[string]string{
+ "host": host,
+ "network": network,
+ "address": address,
+ }
+
+ addr, err := net.ResolveTCPAddr(network, address)
+ if err != nil {
+ if ae, ok := err.(*net.AddrError); ok && ae.Err == "no suitable address found" {
+ return nil
+ }
+ return NewPoint("public", tags, map[string]interface{}{"error": err.Error()})
+ }
+ conn, err := net.DialTCP(network, nil, addr)
+ if err != nil {
+ return NewPoint("public", tags, map[string]interface{}{"error": err.Error()})
+ }
+ conn.CloseWrite()
+ all, _ := ioutil.ReadAll(conn)
+ line := strings.TrimRight(string(all), "\n")
+ parts := strings.Split(line, " ")
+ if len(parts) != 3 {
+ return NewPoint("public", tags, map[string]interface{}{"error": fmt.Sprintf("malformed ID line: %q", line)})
+ }
+ return NewPoint("public", tags, map[string]interface{}{
+ "name": parts[1],
+ "version": parts[2],
+ })
+}
+
+func main() {
+ for _, fname := range os.Args[1:] {
+ wg.Add(1)
+ go DoHostfile(fname)
+ }
+ wg.Wait()
+}