main.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package main
  2. import (
  3. "bufio"
  4. "flag"
  5. "fmt"
  6. "os"
  7. "strings"
  8. "time"
  9. )
  10. var noVersion = "dev"
  11. var version string
  12. func readFromConsole(result chan string) {
  13. var text, line string
  14. var err error
  15. counter := 0
  16. reader := bufio.NewReader(os.Stdin)
  17. for counter < 3 {
  18. line, err = reader.ReadString('\n')
  19. if line == "\n" {
  20. counter++
  21. } else {
  22. counter = 0
  23. }
  24. text += fmt.Sprintf("%s\n", line)
  25. }
  26. if err != nil {
  27. Error.F("Error in reading text from console\n%s", err)
  28. os.Exit(1)
  29. }
  30. result <- strings.TrimRight(text, "\n")
  31. return
  32. }
  33. func toList(input string) []string {
  34. var result = []string{}
  35. list := strings.Split(input, ",")
  36. for _, element := range list {
  37. if element != "" {
  38. result = append(result, element)
  39. }
  40. }
  41. return result
  42. }
  43. func initializeConfig(configPath, section string) *Config {
  44. if configPath == "" {
  45. configPath = "/etc/sendmail.toml"
  46. // Ignore non existing config only if `-conf` not used on command line.
  47. if _, err := os.Stat(configPath); os.IsNotExist(err) {
  48. return NewConfig()
  49. }
  50. }
  51. config, err := readConfig(configPath, section)
  52. if err != nil {
  53. if os.IsNotExist(err) {
  54. Error.F("Error in parsing the configuration\n%s", err)
  55. os.Exit(-2)
  56. }
  57. }
  58. Debug.F("---\nConfig from %s\n%s", configPath, *config)
  59. return config
  60. }
  61. func main() {
  62. var err error
  63. var configPath, section, serverAddress, user, password, to, cc, bcc, from, subject, text string
  64. var encryption, dbg, versionFlag bool
  65. var serverPortAux int
  66. var serverPort int64
  67. flag.BoolVar(&versionFlag, "version", false, "Prints the version and exits")
  68. flag.StringVar(&configPath, "conf", "", "Path to a config file (defaults to /etc/sendmail.toml)")
  69. flag.StringVar(&section, "section", "default", "Section of the conf to read (defaults to \"default\")")
  70. flag.BoolVar(&dbg, "dbg", false, "Enable debugging output")
  71. flag.StringVar(&serverAddress, "server-address", "", "The SMTP server address")
  72. flag.IntVar(&serverPortAux, "server-port", 0, "The SMTP server")
  73. flag.BoolVar(&encryption, "force-ssl", false, "Force the use of ssl (defalut: false)")
  74. flag.StringVar(&user, "user", "", "The user to authenticate with to the server")
  75. flag.StringVar(&password, "password", "", "The password to authenticate with to the server")
  76. flag.StringVar(&to, "to", "", "Comma-separated list of recipient(s)")
  77. flag.StringVar(&cc, "cc", "", "Comma-separated list of carbon-copy recipient(s)")
  78. flag.StringVar(&bcc, "bcc", "", "Comma-separated list of blind carbon-copy recipient(s)")
  79. flag.StringVar(&from, "from", "", "Sender of the mail (used as default account user to log in on the SMTP server)")
  80. flag.StringVar(&subject, "sub", "", "Subject of the mail")
  81. flag.Parse()
  82. LogInit(dbg)
  83. if versionFlag {
  84. showVersion := noVersion
  85. if version != "" {
  86. showVersion = version
  87. }
  88. Info.F("Version: %s", showVersion)
  89. os.Exit(0)
  90. }
  91. if flag.NArg() == 0 {
  92. result := make(chan string, 1)
  93. go readFromConsole(result)
  94. select {
  95. case text = <-result:
  96. Info.Ln("text read from console")
  97. case <-time.After(5 * time.Minute):
  98. Error.Ln("timeout reading from console")
  99. os.Exit(3)
  100. }
  101. } else {
  102. for _, arg := range flag.Args() {
  103. text += fmt.Sprintf("%s\n", arg)
  104. }
  105. }
  106. serverPort = int64(serverPortAux)
  107. Debug.F(
  108. `
  109. ---
  110. parameters:
  111. conf: %s
  112. dbg: %t
  113. address: %s
  114. port: %d
  115. encryption: %t
  116. user: %s
  117. password: %s
  118. to: %s
  119. from: %s
  120. subject: %s`,
  121. configPath,
  122. dbg,
  123. serverAddress,
  124. serverPort,
  125. encryption,
  126. user,
  127. password,
  128. to,
  129. from,
  130. subject,
  131. )
  132. config := initializeConfig(configPath, section)
  133. config.Server.Merge("Address", serverAddress)
  134. config.Server.Merge("Port", serverPort)
  135. config.Server.Merge("Encryption", encryption)
  136. config.Server.Merge("User", user)
  137. config.Server.Merge("Password", password)
  138. config.Merge("From", from)
  139. config.Merge("To", toList(to))
  140. config.Merge("Cc", toList(cc))
  141. config.Merge("Bcc", toList(bcc))
  142. config.Merge("Subject", subject)
  143. config.Merge("Text", text)
  144. Debug.F("---\nPre-validation config\n%s", config)
  145. err = config.Validate()
  146. if err != nil {
  147. Error.F("Config validation failed:\n%s\n", err)
  148. os.Exit(1)
  149. }
  150. Info.F("Sending mail | to: %s", config.To)
  151. SendMail(config)
  152. }