/
main.go
149 lines (125 loc) · 2.77 KB
/
main.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
package main
import (
"flag"
"io/ioutil"
"log"
"log/syslog"
"net/http"
"os"
"strings"
)
var (
agent = "gonoip/0.1 costinc@gmail.com"
ipfile = "/var/run/gonoip"
)
var (
infoLog, errLog *log.Logger
forceUpdate bool
addHost bool
)
func init() {
flag.BoolVar(&forceUpdate, "f", false, "update noip even if IP hasn't changed")
flag.BoolVar(&addHost, "a", false, "print config with added host to stdout")
flag.Parse()
if addHost {
infoLog = log.New(os.Stdout, "", 0)
errLog = log.New(os.Stdout, "", 0)
} else {
var err error
infoLog, err = syslog.NewLogger(syslog.LOG_INFO, 0)
checkErr(err)
errLog, err = syslog.NewLogger(syslog.LOG_ERR, 0)
checkErr(err)
}
err := readConfig()
if addHost && os.IsNotExist(err) {
return
}
checkErr(err)
}
func main() {
if addHost {
AddHost()
return
}
if len(hosts) == 0 {
errLog.Fatal("no hosts defined")
}
if forceUpdate {
infoLog.Print("forced update")
for _, h := range hosts {
updateNoIP(h)
}
return
}
ip, oldip := getIP(), getOldIP()
if ip != oldip {
infoLog.Print("IP changed, new IP: " + ip)
for _, h := range hosts {
updateNoIP(h)
}
} else {
infoLog.Print("same IP, no update required")
}
}
func updateNoIP(h *host) {
var client http.Client
req, err := http.NewRequest(
"GET",
"http://dynupdate.no-ip.com/nic/update?hostname="+h.Name,
nil)
checkErr(err)
req.Header.Add("Authorization", "Basic "+h.Auth)
req.Header.Add("User-Agent", agent)
resp, err := client.Do(req)
checkErr(err)
body, err := ioutil.ReadAll(resp.Body)
checkErr(err)
args := strings.Split(string(body), " ")
handleNoIP(h, args)
}
func handleNoIP(h *host, args []string) {
prefix := h.Name + ": noip: "
switch args[0] {
case "good":
infoLog.Print(prefix + "IP changed (" + args[1] + ")")
err := ioutil.WriteFile(ipfile, []byte(args[1]), 0644)
checkErr(err)
case "nochg":
infoLog.Print(prefix + "no change required (" + args[1] + ")")
err := ioutil.WriteFile(ipfile, []byte(args[1]), 0644)
checkErr(err)
case "nohost":
errLog.Fatal(prefix + "host does not exist")
case "badauth":
errLog.Fatal(prefix + "invalid username or password")
case "badagent":
errLog.Fatal(prefix + "bad user agent: client disabled")
case "!donator":
errLog.Fatal(prefix + "feature not available")
case "abuse":
errLog.Fatal(prefix + "user blocked due to abuse")
case "911":
infoLog.Print(prefix + "fatal server error")
}
}
func getIP() string {
resp, err := http.Get("http://automation.whatismyip.com/n09230945.asp")
checkErr(err)
ip, err := ioutil.ReadAll(resp.Body)
checkErr(err)
return string(ip)
}
func getOldIP() string {
ip, err := ioutil.ReadFile(ipfile)
if os.IsNotExist(err) {
return ""
}
checkErr(err)
return string(ip)
}
func checkErr(err error) {
if err != nil {
errLog.Fatal(err)
}
}