package main import ( "errors" "fmt" "log" "os" "regexp" "time" "github.com/urfave/cli" ) const ( zoneFilePath = "/var/bind/pri/localhost.zone" ) var re = regexp.MustCompile(`^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$`) func main() { app := cli.NewApp() app.Name = "spamip" app.Version = "0.1" app.Compiled = time.Now() app.Authors = []cli.Author{ { Name: "Darko Luketic", Email: "info@icod.de", }, } app.Usage = "spamip is a tool that adds an IP to a bind zone file in DNSBL format" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "file, f", Usage: "path/filename of the zone file", EnvVar: "SPAMIP_FILE", Required: false, Hidden: false, TakesFile: false, Value: zoneFilePath, }, } app.Commands = []cli.Command{ { Name: "add", Aliases: []string{"a"}, Usage: "add an IP address to the zone file", Action: func(c *cli.Context) error { if len(c.Args()) != 1 { return errors.New("add takes exactly 1 argument, an IPv4 address") } if !re.MatchString(c.Args().First()) { return errors.New(c.Args().First() + "is not an IPv4 address") } s := re.FindStringSubmatch(c.Args().First()) text := fmt.Sprintf("%s.%s.%s.%s\tIN\tA\t127.0.0.3\n", s[4], s[3], s[2], s[1]) return appendText(text, c.GlobalString("file")) }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } func appendText(text, file string) error { f, e := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if e != nil { return e } if n, e := f.WriteString(text); e != nil { return e } else if n != len(text) { return errors.New("did not write all the text") } return f.Close() }