|
@@ -1,155 +1,47 @@
|
|
|
package main
|
|
|
|
|
|
import (
|
|
|
+ "bufio"
|
|
|
"flag"
|
|
|
"fmt"
|
|
|
- "log"
|
|
|
- "reflect"
|
|
|
+ "os"
|
|
|
"strings"
|
|
|
-
|
|
|
- toml "github.com/pelletier/go-toml"
|
|
|
- // mail "gopkg.in/gomail.v2"
|
|
|
)
|
|
|
|
|
|
-type ServerConfig struct {
|
|
|
- Address string `toml:address,omitempty`
|
|
|
- Port int64 `toml:port,omitempty`
|
|
|
- Encryption string `toml:encryption,omitempty`
|
|
|
- User string `toml:user,omitempty`
|
|
|
- Password string `toml:password,omitempty`
|
|
|
-}
|
|
|
-
|
|
|
-func (s ServerConfig) String() string {
|
|
|
- return fmt.Sprintf(
|
|
|
- "\tAddress: %s\n\tPort: %d\n\tEncryption: %s\n\tUser: %s\n\tPassword: %s\n",
|
|
|
- s.Address,
|
|
|
- s.Port,
|
|
|
- s.Encryption,
|
|
|
- s.User,
|
|
|
- s.Password,
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-type Config struct {
|
|
|
- Server *ServerConfig `toml:server,omitempty`
|
|
|
- From string `toml:from,omitempty`
|
|
|
- To []string `toml:to,omitempty`
|
|
|
- Cc []string `toml:cc,omitempty`
|
|
|
- Bcc []string `toml:bcc,omitempty`
|
|
|
- Subject string `toml:subject,omitempty`
|
|
|
- Text string `toml:text,omitempty`
|
|
|
-}
|
|
|
-
|
|
|
-func (c Config) String() string {
|
|
|
- return fmt.Sprintf(
|
|
|
- "From: %s\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\nText:\n%s\nServer:\n%s",
|
|
|
- c.From,
|
|
|
- c.To,
|
|
|
- c.Cc,
|
|
|
- c.Bcc,
|
|
|
- c.Subject,
|
|
|
- c.Text,
|
|
|
- c.Server,
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-func NewConfig() *Config {
|
|
|
- server := &ServerConfig{}
|
|
|
- config := &Config{}
|
|
|
- config.Server = server
|
|
|
- return config
|
|
|
-}
|
|
|
-
|
|
|
-func debug(active bool, fmt string, msg ...interface{}) {
|
|
|
- if active {
|
|
|
- log.Printf(fmt, msg...)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func isPresent(slice []string, val string) bool {
|
|
|
- for _, item := range slice {
|
|
|
- if item == val {
|
|
|
- return true
|
|
|
+func readFromConsole() string {
|
|
|
+ var text, line string
|
|
|
+ var err error
|
|
|
+ counter := 0
|
|
|
+ reader := bufio.NewReader(os.Stdin)
|
|
|
+ for counter < 3 {
|
|
|
+ line, err = reader.ReadString('\n')
|
|
|
+ if line == "\n" {
|
|
|
+ counter += 1
|
|
|
}
|
|
|
+ text += fmt.Sprintf("%s\n", line)
|
|
|
}
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
-func isEmpty(value interface{}) bool {
|
|
|
- t := reflect.TypeOf(value)
|
|
|
- v := reflect.ValueOf(value)
|
|
|
- switch v.Kind() {
|
|
|
- case reflect.Slice:
|
|
|
- return v.Len() == 1
|
|
|
- default:
|
|
|
- return value == reflect.Zero(t).Interface()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func readConfig(configPath, section string) *Config {
|
|
|
- config := NewConfig()
|
|
|
- tree, err := toml.LoadFile(configPath)
|
|
|
if err != nil {
|
|
|
- log.Panicln(err)
|
|
|
+ Error.F("Error in reading text from console\n%s", err)
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
|
- keys := tree.Keys()
|
|
|
-
|
|
|
- if !isPresent(keys, section) {
|
|
|
- return config
|
|
|
- }
|
|
|
- sub := tree.Get(section).(*toml.Tree)
|
|
|
- err = sub.Unmarshal(config)
|
|
|
- return config
|
|
|
-}
|
|
|
-
|
|
|
-func (c *Config) Validate() error {
|
|
|
- return nil
|
|
|
+ return text
|
|
|
}
|
|
|
|
|
|
-func merge(key string, value, obj interface{}) {
|
|
|
- if isEmpty(value) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- var elem reflect.Value
|
|
|
- if reflect.TypeOf(obj) != reflect.TypeOf(reflect.Value{}) {
|
|
|
- log.Println("Not Value")
|
|
|
- elem = reflect.ValueOf(obj).Elem()
|
|
|
- } else {
|
|
|
- log.Println("Value")
|
|
|
- elem = obj.(reflect.Value)
|
|
|
- }
|
|
|
- field := elem.FieldByName(key)
|
|
|
-
|
|
|
- if field.CanSet() {
|
|
|
- switch field.Kind() {
|
|
|
- case reflect.Int64:
|
|
|
- field.SetInt(value.(int64))
|
|
|
- case reflect.Bool:
|
|
|
- field.SetBool(value.(bool))
|
|
|
- case reflect.String:
|
|
|
- field.SetString(value.(string))
|
|
|
- case reflect.Slice:
|
|
|
- field.Set(reflect.ValueOf(value))
|
|
|
- default:
|
|
|
- merge(key, reflect.ValueOf(value), field)
|
|
|
- //merge(key, value, field.Pointer())
|
|
|
+func toList(input string) []string {
|
|
|
+ var result = []string{}
|
|
|
+ list := strings.Split(input, ",")
|
|
|
+ for _, element := range list {
|
|
|
+ if element != "" {
|
|
|
+ result = append(result, element)
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-func (s *ServerConfig) Merge(key string, value interface{}) {
|
|
|
- merge(key, value, s)
|
|
|
-}
|
|
|
-
|
|
|
-func (c *Config) Merge(key string, value interface{}) {
|
|
|
- merge(key, value, c)
|
|
|
+ return result
|
|
|
}
|
|
|
|
|
|
func main() {
|
|
|
- //var err error
|
|
|
- var configPath, section, serverAddress, encryption, user, password, to, cc, bcc, from, subject string
|
|
|
- var dbg bool
|
|
|
+ var err error
|
|
|
+ var configPath, section, serverAddress, user, password, to, cc, bcc, from, subject, text string
|
|
|
+ var encryption, dbg bool
|
|
|
var serverPort_ int
|
|
|
var serverPort int64
|
|
|
flag.StringVar(&configPath, "conf", "/etc/sendmail.toml", "Path to a config file (defaults to /etc/sendmail.toml)")
|
|
@@ -157,7 +49,7 @@ func main() {
|
|
|
flag.BoolVar(&dbg, "dbg", false, "Enable debugging output")
|
|
|
flag.StringVar(&serverAddress, "server-address", "", "The SMTP server address")
|
|
|
flag.IntVar(&serverPort_, "server-port", 0, "The SMTP server")
|
|
|
- flag.StringVar(&encryption, "encryption", "", "The encryption type (no, starttls, tls)")
|
|
|
+ flag.BoolVar(&encryption, "force-ssl", false, "Force the use of ssl (defalut: false)")
|
|
|
flag.StringVar(&user, "user", "", "The user to authenticate with to the server")
|
|
|
flag.StringVar(&password, "password", "", "The password to authenticate with to the server")
|
|
|
flag.StringVar(&to, "to", "", "Comma-separated list of recipient(s)")
|
|
@@ -167,20 +59,31 @@ func main() {
|
|
|
flag.StringVar(&subject, "sub", "", "Subject of the mail")
|
|
|
flag.Parse()
|
|
|
|
|
|
+ LogInit(dbg)
|
|
|
+
|
|
|
+ if flag.NArg() == 0 {
|
|
|
+ text = readFromConsole()
|
|
|
+ } else {
|
|
|
+ for _, arg := range flag.Args() {
|
|
|
+ text += fmt.Sprintf("%s\n", arg)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
serverPort = int64(serverPort_)
|
|
|
- debug(
|
|
|
- dbg,
|
|
|
- `parameters:
|
|
|
- conf: %s
|
|
|
- dbg: %t
|
|
|
- address: %s
|
|
|
- port: %d
|
|
|
- encryption: %s
|
|
|
- user: %s
|
|
|
- password: %s
|
|
|
- to: %s
|
|
|
- from: %s
|
|
|
- subject: %s`,
|
|
|
+ Debug.F(
|
|
|
+ `
|
|
|
+---
|
|
|
+parameters:
|
|
|
+ conf: %s
|
|
|
+ dbg: %t
|
|
|
+ address: %s
|
|
|
+ port: %d
|
|
|
+ encryption: %t
|
|
|
+ user: %s
|
|
|
+ password: %s
|
|
|
+ to: %s
|
|
|
+ from: %s
|
|
|
+ subject: %s`,
|
|
|
configPath,
|
|
|
dbg,
|
|
|
serverAddress,
|
|
@@ -193,21 +96,27 @@ func main() {
|
|
|
subject,
|
|
|
)
|
|
|
config := readConfig(configPath, section)
|
|
|
- debug(dbg, "\n%s", *config)
|
|
|
+ Debug.F("---\nConfig from %s\n%s", configPath, *config)
|
|
|
|
|
|
- // config.Server.Merge("Address", serverAddress)
|
|
|
- // config.Server.Merge("Port", serverPort)
|
|
|
- // config.Server.Merge("Encryption", encryption)
|
|
|
- // config.Server.Merge("User", user)
|
|
|
- // config.Server.Merge("Password", password)
|
|
|
- config.Merge("Server", &ServerConfig{serverAddress, serverPort, encryption, user, password})
|
|
|
+ config.Server.Merge("Address", serverAddress)
|
|
|
+ config.Server.Merge("Port", serverPort)
|
|
|
+ config.Server.Merge("Encryption", encryption)
|
|
|
+ config.Server.Merge("User", user)
|
|
|
+ config.Server.Merge("Password", password)
|
|
|
config.Merge("From", from)
|
|
|
- config.Merge("To", strings.Split(to, ","))
|
|
|
- config.Merge("Cc", strings.Split(cc, ","))
|
|
|
- config.Merge("Bcc", strings.Split(bcc, ","))
|
|
|
+ config.Merge("To", toList(to))
|
|
|
+ config.Merge("Cc", toList(cc))
|
|
|
+ config.Merge("Bcc", toList(bcc))
|
|
|
config.Merge("Subject", subject)
|
|
|
- // config.Merge("Text", text)
|
|
|
+ config.Merge("Text", text)
|
|
|
|
|
|
- debug(dbg, "\n%s", config)
|
|
|
+ Debug.F("---\nPre-validation config\n%s", config)
|
|
|
+ err = config.Validate()
|
|
|
+ if err != nil {
|
|
|
+ Error.F("Config validation failed:\n%s\n", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
|
|
|
+ Info.F("Sending mail | to: %s", config.To)
|
|
|
+ SendMail(config)
|
|
|
}
|