summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2013-08-28 15:53:04 +0200
committerKevin Chabowski <kevin@kch42.de>2013-08-28 15:53:04 +0200
commit3e52620c29e6893ce1cf5e45ec4e00a37184edd6 (patch)
tree9ebcd2df2d97f8ea2303065ca9cecbebf84a83ce
parentbf12e35ec9f3976bbe85561e60c8b2ee08988226 (diff)
downloadmailremind-3e52620c29e6893ce1cf5e45ec4e00a37184edd6.tar.gz
mailremind-3e52620c29e6893ce1cf5e45ec4e00a37184edd6.tar.bz2
mailremind-3e52620c29e6893ce1cf5e45ec4e00a37184edd6.zip
Added mailing interface (from other project)
-rw-r--r--mailing/mailer.go13
-rw-r--r--mailing/mailers.go5
-rw-r--r--mailing/sendmail_mailer.go73
-rw-r--r--mailing/smtp_mailer.go60
4 files changed, 151 insertions, 0 deletions
diff --git a/mailing/mailer.go b/mailing/mailer.go
new file mode 100644
index 0000000..c9ab8d0
--- /dev/null
+++ b/mailing/mailer.go
@@ -0,0 +1,13 @@
+package mailing
+
+import (
+ "github.com/kch42/simpleconf"
+)
+
+// Mailer is a interface that defines the Mail function.
+type Mailer interface {
+ Mail(to, from string, msg []byte) error
+}
+
+// MailerCreator is a function that creates a Mailer instance from config values.
+type MailerCreator func(conf simpleconf.Config) (Mailer, error)
diff --git a/mailing/mailers.go b/mailing/mailers.go
new file mode 100644
index 0000000..7f550c5
--- /dev/null
+++ b/mailing/mailers.go
@@ -0,0 +1,5 @@
+package mailing
+
+var MailersByName = map[string]MailerCreator{
+ "smtp": SMTPMailerCreator,
+ "sendmail": SendmailMailerCreator}
diff --git a/mailing/sendmail_mailer.go b/mailing/sendmail_mailer.go
new file mode 100644
index 0000000..ad864fb
--- /dev/null
+++ b/mailing/sendmail_mailer.go
@@ -0,0 +1,73 @@
+package mailing
+
+import (
+ "errors"
+ "fmt"
+ "github.com/kch42/simpleconf"
+ "os/exec"
+)
+
+// SendmailMailer is a Mailer implementation that sends mail using a sendmail-ish executable.
+//
+// Sendmail-ish in this context means:
+//
+// * The executable must accept the from address using the `-f <addr>` switch
+// * The executable must accept the to address as a parameter
+// * The executable expects a mail (including all headers) on stdin that is terminated by EOF
+type SendmailMailer struct {
+ Exec string
+ Args []string
+}
+
+func (sm SendmailMailer) Mail(to, from string, msg []byte) (outerr error) {
+ off := len(sm.Args)
+ args := make([]string, off+3)
+ copy(args, sm.Args)
+ args[off] = "-f"
+ args[off+1] = from
+ args[off+2] = to
+
+ cmd := exec.Command(sm.Exec, args...)
+ pipe, err := cmd.StdinPipe()
+ if err != nil {
+ return err
+ }
+
+ if err = cmd.Start(); err != nil {
+ return err
+ }
+ defer func() {
+ pipe.Close()
+ err := cmd.Wait()
+ if outerr == nil {
+ outerr = err
+ }
+ }()
+
+ _, err = pipe.Write(msg)
+ return err
+}
+
+// SendmailMailerCreator creates an SendmailMailer using configuration values in the [mail] section.
+//
+// exec - The name of the executable
+// argX - (optional) Additional arguments for the executable. X is a ascending number starting with 1
+func SendmailMailerCreator(conf simpleconf.Config) (Mailer, error) {
+ rv := SendmailMailer{}
+ var err error
+
+ if rv.Exec, err = conf.GetString("mail", "exec"); err != nil {
+ return rv, errors.New("Missing [mail] exec config")
+ }
+
+ for i := 1; ; i++ {
+ arg, err := conf.GetString("mail", fmt.Sprintf("arg%d", i))
+ if err != nil {
+ break
+ }
+
+ rv.Args = append(rv.Args, arg)
+ }
+
+ return rv, nil
+}
diff --git a/mailing/smtp_mailer.go b/mailing/smtp_mailer.go
new file mode 100644
index 0000000..2a90173
--- /dev/null
+++ b/mailing/smtp_mailer.go
@@ -0,0 +1,60 @@
+package mailing
+
+import (
+ "errors"
+ "github.com/kch42/simpleconf"
+ "net/smtp"
+)
+
+// SMTPMailer is a Mailer implementation that sends mail via an smtp server.
+type SMTPMailer struct {
+ Host string // Host is the expected hostname of the server
+ Addr string // Addr is the address of the server
+ UseCRAMMD5 bool
+ Username string
+ Password string
+}
+
+func (sm SMTPMailer) Mail(to, from string, msg []byte) error {
+ var auth smtp.Auth
+ if sm.UseCRAMMD5 {
+ auth = smtp.CRAMMD5Auth(sm.Username, sm.Password)
+ } else {
+ auth = smtp.PlainAuth("", sm.Username, sm.Password, sm.Host)
+ }
+
+ return smtp.SendMail(sm.Addr, auth, from, []string{to}, msg)
+}
+
+// SMTPMailerCreator creates an SMTPMailer using configuration values in the [mail] section.
+//
+// addr - The address of the smtp server (go notation)
+// user - Username
+// passwd - Password
+// crammd5 - Should CRAMMD5 (on) or PLAIN (off) be used?
+// host - The expected hostname of the mailserver (can be left out, if crammd5 is on)
+//
+func SMTPMailerCreator(conf simpleconf.Config) (Mailer, error) {
+ rv := SMTPMailer{}
+ var err error
+
+ if rv.Addr, err = conf.GetString("mail", "addr"); err != nil {
+ return rv, errors.New("Missing [mail] addr config")
+ }
+ if rv.UseCRAMMD5, err = conf.GetBool("mail", "crammd5"); err != nil {
+ return rv, errors.New("Missing [mail] crammd5 config")
+ }
+ if rv.Username, err = conf.GetString("mail", "user"); err != nil {
+ return rv, errors.New("Missing [mail] user config")
+ }
+ if rv.Password, err = conf.GetString("mail", "passwd"); err != nil {
+ return rv, errors.New("Missing [mail] passwd config")
+ }
+ if !rv.UseCRAMMD5 {
+ if rv.Host, err = conf.GetString("mail", "host"); err != nil {
+ return rv, errors.New("Missing [mail] host config")
+ }
+ }
+
+ return rv, nil
+}