-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmain.go
More file actions
228 lines (182 loc) · 6.65 KB
/
Copy pathmain.go
File metadata and controls
228 lines (182 loc) · 6.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
)
var version = "1.2.0" // Application version
var (
// Long-form flags
smtpServer string
smtpPort int
username string
password string
tlsMode string
configFile string
fromEmail string
toEmail string
replyTo string
subject string
body string
attachmentsFiles string
bodyFile string
showVersion bool
// Short-form flags
smtpServerShort string
smtpPortShort int
usernameShort string
passwordShort string
noAuth bool
noAuthShort bool
tlsModeShort string
configFileShort string
fromEmailShort string
toEmailShort string
replyToShort string
subjectShort string
bodyShort string
attachmentsFilesShort string
bodyFileShort string
showVersionShort bool
)
func init() {
// Long-form flags
flag.StringVar(&smtpServer, "smtp-server", "", "SMTP server for sending emails")
flag.IntVar(&smtpPort, "smtp-port", 0, "SMTP server port (default 587)")
flag.StringVar(&username, "smtp-username", "", "Username for SMTP authentication")
flag.StringVar(&password, "smtp-password", "", "Password for SMTP authentication")
flag.BoolVar(&noAuth, "no-auth", false, "Use unauthenticated SMTP")
flag.StringVar(&tlsMode, "tls-mode", "", "TLS mode (none, tls-skip, tls) (default tls)")
flag.StringVar(&configFile, "config", "", "Path to the SMTP config file")
flag.StringVar(&fromEmail, "from-email", "", "Email address to send from")
flag.StringVar(&toEmail, "to-email", "", "Email addresses that will receive the email, comma-separated")
flag.StringVar(&replyTo, "reply-to", "", "Email address to reply to")
flag.StringVar(&subject, "subject", "", "Subject of the email")
flag.StringVar(&body, "body", "", "Body of the email")
flag.StringVar(&attachmentsFiles, "attachments", "", "File paths for attachments, comma-separated")
flag.StringVar(&bodyFile, "body-file", "", "File path for email body")
flag.BoolVar(&showVersion, "version", false, "Display application version")
// Short-form flags
flag.StringVar(&smtpServerShort, "s", "", "SMTP server for sending emails (short)")
flag.IntVar(&smtpPortShort, "p", 0, "SMTP server port (short)")
flag.StringVar(&usernameShort, "u", "", "Username for SMTP authentication (short)")
flag.StringVar(&passwordShort, "w", "", "Password for SMTP authentication (short)")
flag.BoolVar(&noAuthShort, "na", false, "Use unauthenticated SMTP (short)")
flag.StringVar(&tlsModeShort, "l", "", "TLS mode (short)")
flag.StringVar(&configFileShort, "c", "", "Path to the SMTP config file (short)")
flag.StringVar(&fromEmailShort, "f", "", "Email address to send from (short)")
flag.StringVar(&toEmailShort, "t", "", "Email addresses that will receive the email, comma-separated (short)")
flag.StringVar(&replyToShort, "r", "", "Email address to reply to (short)")
flag.StringVar(&subjectShort, "h", "", "Subject of the email (short)")
flag.StringVar(&bodyShort, "b", "", "Body of the email (short)")
flag.StringVar(&attachmentsFilesShort, "af", "", "File paths for attachments, comma-separated (short)")
flag.StringVar(&bodyFileShort, "bf", "", "File path for email body (short)")
flag.BoolVar(&showVersionShort, "v", false, "Display application version")
}
func main() {
// Override the default flag.Usage
flag.Usage = Usage
flag.Parse()
showVersion = showVersion || showVersionShort
if showVersion {
fmt.Printf("Mail2Go Version: %s\n", version)
os.Exit(0)
}
var config Config = Config{}
// Load config file
configFile = priorityString([]string{configFile, configFileShort})
if configFile == "" {
// config file not provided -- look for default file
if path, err := os.UserConfigDir(); err == nil {
path = filepath.Join(path, "mail2go", "config.json")
if _, err := os.Stat(path); err == nil {
configFile = path
}
}
}
if configFile != "" {
c, err := loadConfig(configFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error loading config file: %v\n", err)
os.Exit(1)
}
config = c
}
// Clearly define our config priorities, lowest to highest: config files, long flags, short flags.
smtpServer = priorityString([]string{config.SMTPServer, smtpServer, smtpServerShort})
smtpPort = priorityInt([]int{config.SMTPPort, smtpPort, smtpPortShort})
if smtpPort == 0 {
smtpPort = 587
}
username = priorityString([]string{config.SMTPUsername, username, usernameShort})
password = priorityString([]string{config.SMTPPassword, password, passwordShort})
noAuth = config.NoAuth || noAuth || noAuthShort
tlsMode = priorityString([]string{config.TLSMode, tlsMode, tlsModeShort})
if tlsMode == "" {
tlsMode = "tls"
}
fromEmail = priorityString([]string{config.FromEmail, fromEmail, fromEmailShort})
toEmail = priorityString([]string{toEmail, toEmailShort})
replyTo = priorityString([]string{replyTo, replyToShort})
subject = priorityString([]string{subject, subjectShort})
body = priorityString([]string{body, bodyShort})
attachmentsFiles = priorityString([]string{attachmentsFiles, attachmentsFilesShort})
bodyFile = priorityString([]string{bodyFile, bodyFileShort})
// Check if required flags or config values are missing
if smtpServer == "" || fromEmail == "" || toEmail == "" || subject == "" {
fmt.Fprintln(os.Stderr, "Error: Required flags or config values are missing.")
Usage()
}
// Check if either direct input or file path is provided for body
if body == "" && bodyFile == "" {
fmt.Fprintln(os.Stderr, "Error: Subject and body are required, either directly or through a specified file.")
Usage()
}
// Read body from files if provided
if bodyFile != "" {
content, err := os.ReadFile(bodyFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading body file: %v\n", err)
os.Exit(1)
}
body = priorityString([]string{string(content), body}) //preserve the "flags override files" semantic
}
// Split attachment file paths
var attachmentPaths []string
if attachmentsFiles != "" {
attachmentPaths = strings.Split(attachmentsFiles, ",")
}
// Split recipient email addresses
var toEmails []string
if toEmail != "" {
toEmails = strings.Split(toEmail, ",")
}
if len(toEmails) == 0 {
fmt.Fprintln(os.Stderr, "Error: At least one recipient email address is required.")
Usage()
}
if err := sendEmail(smtpServer, smtpPort, username, password, fromEmail, toEmails, replyTo, subject, body, bodyFile, attachmentPaths, tlsMode, noAuth); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
func priorityString(strings []string) string {
var result = ""
for _, val := range strings {
if val != "" {
result = val
}
}
return result
}
func priorityInt(ints []int) int {
var result = 0
for _, val := range ints {
if val != 0 {
result = val
}
}
return result
}