blob: 26c662cc321908c7b8656173d677252d2a52defa [file] [log] [blame]
David K. Bainbridgef694f5a2016-06-10 16:21:27 -07001package main
2
3import (
4 "bufio"
5 "fmt"
6 "net/url"
7 "os"
8 "strings"
9)
10
11func NewAddressSource(spec string) (AddressSource, error) {
12 u, err := url.Parse(spec)
13 if err != nil {
14 return nil, err
15 }
16
17 switch u.Scheme {
18 case "file":
19 return NewFileAddressSource(u)
20 default:
21 }
22 return nil, fmt.Errorf("Unknown address source scheme specified '%s'", spec)
23}
24
25type AddressRec struct {
26 Name string
27 IP string
28 MAC string
29}
30
31type AddressSource interface {
32 GetAddresses() ([]AddressRec, error)
33}
34
35type FileAddressSource struct {
36 Path string
37}
38
39func NewFileAddressSource(connect *url.URL) (AddressSource, error) {
40 // Validate file exists before returning a source
41 if _, err := os.Stat(connect.Path); os.IsNotExist(err) {
42 return nil, err
43 }
44 source := FileAddressSource{}
45 source.Path = connect.Path
46 return &source, nil
47}
48
49func (s *FileAddressSource) GetAddresses() ([]AddressRec, error) {
50 // Read the file
51 file, err := os.Open(s.Path)
52 defer file.Close()
53 if err != nil {
54 return nil, err
55 }
56
57 capacity := 20
58 result := make([]AddressRec, capacity)
59 idx := 0
60
61 scanner := bufio.NewScanner(file)
62 for scanner.Scan() {
63 parts := strings.Fields(scanner.Text())
64
65 // Only process lines with the correct number of parts
66 if len(parts) == 6 {
67 result[idx].Name = parts[0]
68 result[idx].IP = parts[3]
69 result[idx].MAC = parts[5]
70 idx += 1
71 if idx >= capacity {
72 capacity += 20
73 tmp, result := result, make([]AddressRec, capacity)
74 copy(result, tmp)
75 }
76 }
77 }
78
79 if err := scanner.Err(); err != nil {
80 return nil, err
81 }
82
83 return result[:idx], nil
84}