package main import ( "bufio" "flag" "fmt" "os" "strings" "time" ) var noVersion = "dev" var version string func readFromConsole(result chan 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++ } else { counter = 0 } text += fmt.Sprintf("%s\n", line) } if err != nil { Error.F("Error in reading text from console\n%s", err) os.Exit(1) } result <- strings.TrimRight(text, "\n") return } func toList(input string) []string { var result = []string{} list := strings.Split(input, ",") for _, element := range list { if element != "" { result = append(result, element) } } return result } func initializeConfig(configPath, section string) *Config { if configPath == "" { configPath = "/etc/sendmail.toml" // Ignore non existing config only if `-conf` not used on command line. if _, err := os.Stat(configPath); os.IsNotExist(err) { return NewConfig() } } config, err := readConfig(configPath, section) if err != nil { if os.IsNotExist(err) { Error.F("Error in parsing the configuration\n%s", err) os.Exit(-2) } } Debug.F("---\nConfig from %s\n%s", configPath, *config) return config } func main() { var err error var configPath, section, serverAddress, user, password, to, cc, bcc, from, subject, text string var encryption, dbg, versionFlag, interactive bool var serverPortAux int var serverPort int64 flag.BoolVar(&versionFlag, "version", false, "Prints the version and exits") flag.StringVar(&configPath, "conf", "", "Path to a config file (defaults to /etc/sendmail.toml)") flag.StringVar(§ion, "section", "default", "Section of the conf to read (defaults to \"default\")") flag.BoolVar(&dbg, "dbg", false, "Enable debugging output") flag.BoolVar(&interactive, "interactive", false, "Assume composing mail manually, do not timeout waiting input") flag.StringVar(&serverAddress, "server-address", "", "The SMTP server address") flag.IntVar(&serverPortAux, "server-port", 0, "The SMTP server") 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)") flag.StringVar(&cc, "cc", "", "Comma-separated list of carbon-copy recipient(s)") flag.StringVar(&bcc, "bcc", "", "Comma-separated list of blind carbon-copy recipient(s)") flag.StringVar(&from, "from", "", "Sender of the mail (used as default account user to log in on the SMTP server)") flag.StringVar(&subject, "sub", "", "Subject of the mail") flag.Parse() LogInit(dbg) if versionFlag { showVersion := noVersion if version != "" { showVersion = version } Info.F("Version: %s", showVersion) os.Exit(0) } if flag.NArg() == 0 { result := make(chan string, 1) go readFromConsole(result) if interactive { text = <-result } else { select { case text = <-result: Info.Ln("text read from console") case <-time.After(5 * time.Second): Error.Ln("timeout reading from console") os.Exit(3) } } } else { for _, arg := range flag.Args() { text += fmt.Sprintf("%s\n", arg) } } serverPort = int64(serverPortAux) 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, serverPort, encryption, user, password, to, from, subject, ) config := initializeConfig(configPath, section) 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", toList(to)) config.Merge("Cc", toList(cc)) config.Merge("Bcc", toList(bcc)) config.Merge("Subject", subject) config.Merge("Text", text) 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) }