From ce9289140ad4c63181576dd3cdfa41fced32c098 Mon Sep 17 00:00:00 2001 From: James Hillyerd Date: Sat, 20 Oct 2012 19:20:42 -0700 Subject: [PATCH] Config file loading/validation implemented. Builds, does not run! --- config.go | 69 ++++++++++++++++++++++++++++++++++++++++++ inbucketd/inbucketd.go | 52 +++++++++++++++++++++++++++++++ smtpd/handler.go | 2 +- smtpd/listener.go | 2 +- 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 config.go create mode 100644 inbucketd/inbucketd.go diff --git a/config.go b/config.go new file mode 100644 index 0000000..08ef716 --- /dev/null +++ b/config.go @@ -0,0 +1,69 @@ +package inbucket + +import ( + "container/list" + "fmt" + "github.com/robfig/goconfig/config" + "os" +) + +var Config *config.Config + +// LoadConfig loads the specified configuration file into inbucket.Config +// and performs validations on it. +func LoadConfig(filename string) error { + var err error + Config, err = config.ReadDefault(filename) + if err != nil { + return err + } + + messages := list.New() + + // Validate sections + requireSection(messages, "smtp") + requireSection(messages, "web") + requireSection(messages, "datastore") + if messages.Len() > 0 { + fmt.Fprintln(os.Stderr, "Error(s) validating configuration:") + for e := messages.Front(); e != nil; e = e.Next() { + fmt.Fprintln(os.Stderr, " -", e.Value.(string)) + } + return fmt.Errorf("Failed to validate configuration") + } + + // Validate options + requireOption(messages, "smtp", "ip4.address") + requireOption(messages, "smtp", "ip4.port") + requireOption(messages, "smtp", "domain") + requireOption(messages, "web", "ip4.address") + requireOption(messages, "web", "ip4.port") + requireOption(messages, "web", "templates.dir") + requireOption(messages, "web", "public.dir") + requireOption(messages, "datastore", "path") + if messages.Len() > 0 { + fmt.Fprintln(os.Stderr, "Error(s) validating configuration:") + for e := messages.Front(); e != nil; e = e.Next() { + fmt.Fprintln(os.Stderr, " -", e.Value.(string)) + } + return fmt.Errorf("Failed to validate configuration") + } + + return nil +} + +// requireSection checks that a [section] is defined in the configuration file, +// appending a message if not. +func requireSection(messages *list.List, section string) { + if !Config.HasSection(section) { + messages.PushBack(fmt.Sprintf("Config section [%v] is required", section)) + } +} + +// requireOption checks that 'option' is defined in [section] of the config file, +// appending a message if not. +func requireOption(messages *list.List, section string, option string) { + if !Config.HasOption(section, option) { + messages.PushBack(fmt.Sprintf("Config option '%v' is required in section [%v]", option, section)) + } +} diff --git a/inbucketd/inbucketd.go b/inbucketd/inbucketd.go new file mode 100644 index 0000000..875547e --- /dev/null +++ b/inbucketd/inbucketd.go @@ -0,0 +1,52 @@ +/* + This is the inbucket daemon launcher +*/ +package main + +import ( + "flag" + "fmt" + "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/smtpd" + "os" +) + +var help = flag.Bool("help", false, "Displays this help") + +func main() { + flag.Parse() + if *help { + flag.Usage() + return + } + + // Load & Parse config + if flag.NArg() != 1 { + flag.Usage() + os.Exit(1) + } + err := inbucket.LoadConfig(flag.Arg(0)) + configError(err) + + // Startup SMTP server + domain, err := inbucket.Config.String("smtp", "domain") + configError(err) + port, err := inbucket.Config.Int("smtp", "ip4.port") + configError(err) + server := smtpd.New(domain, port) + go server.Start() +} + +func init() { + flag.Usage = func() { + fmt.Fprintln(os.Stderr, "Usage of inbucketd [options] :") + flag.PrintDefaults() + } +} + +func configError(err error) { + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing config file: %v\n", err) + os.Exit(1) + } +} diff --git a/smtpd/handler.go b/smtpd/handler.go index 91a9256..03fafcb 100644 --- a/smtpd/handler.go +++ b/smtpd/handler.go @@ -5,7 +5,7 @@ import ( "bytes" "container/list" "fmt" - "github.com/jhillyerd/inbucket/app/inbucket" + "github.com/jhillyerd/inbucket" "net" "regexp" "strconv" diff --git a/smtpd/listener.go b/smtpd/listener.go index 1fa8351..a249ca6 100644 --- a/smtpd/listener.go +++ b/smtpd/listener.go @@ -2,7 +2,7 @@ package smtpd import ( "fmt" - "github.com/jhillyerd/inbucket/app/inbucket" + "github.com/jhillyerd/inbucket" "github.com/robfig/revel" "net" )