aboutsummaryrefslogtreecommitdiff
path: root/po/pt/LC_MESSAGES/_tils/2021-01-12-awk-snippet-send-email-to-multiple-recipients-with-curl.po
blob: 5ed478339fead26673798e569c31691e40b1626b (about) (plain) (blame)
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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#
msgid ""
msgstr ""

msgid "title: 'Awk snippet: send email to multiple recipients with cURL'"
msgstr ""

msgid "date: 2021-01-12"
msgstr ""

msgid "layout: post"
msgstr ""

msgid "lang: en"
msgstr ""

msgid "ref: awk-snippet-send-email-to-multiple-recipients-with-curl"
msgstr ""

msgid "My requirements for the `sendmail` command were:"
msgstr ""

msgid "store the email in a file, and send it later."
msgstr ""

msgid "send from different addresses, using different SMTP servers;"
msgstr ""

msgid ""
"I couldn't find an MTA that could accomplish that, but I was able to quickly"
" write a solution."
msgstr ""

msgid "The first part was the easiest: store the email in a file:"
msgstr ""

msgid ""
"# ~/.config/mutt/muttrc:\n"
"set sendmail=~/bin/enqueue-email.sh\n"
"\n"
"# ~/bin/enqueue-email.sh:\n"
"#!/bin/sh -eu\n"
"\n"
"cat - > \"$HOME/mbsync/my-queued-emails/$(date -Is)\"\n"
msgstr ""

msgid ""
"Now that I had the email file store locally, I needed a program to send the "
"email from the file, so that I could create a cronjob like:"
msgstr ""

msgid ""
"for f in ~/mbsync/my-queued-emails/*; do\n"
"  ~/bin/dispatch-email.sh \"$f\" && rm \"$f\"\n"
"done\n"
msgstr ""

msgid ""
"The `dispatch-email.sh` would have to look at the `From: ` header and decide"
" which SMTP server to use. As I [found "
"out](https://blog.edmdesigner.com/send-email-from-linux-command-line/) that "
"[curl](https://curl.se/) supports SMTP and is able to send emails, this is "
"what I ended up with:"
msgstr ""

msgid "Most of curl flags used are self-explanatory, except for `$rcpt`."
msgstr ""

msgid ""
"curl connects to the SMTP server, but doesn't set the recipient address by "
"looking at the message. My solution was to generate the curl flags, store "
"them in `$rcpt` and use it unquoted to leverage shell word splitting."
msgstr ""

msgid ""
"To me, the most interesting part was building the `$rcpt` flags. My first "
"instinct was to try grep, but it couldn't print only matches in a regex. As "
"I started to turn towards sed, I envisioned needing something else to loop "
"over the sed output, and I then moved to Awk."
msgstr ""

msgid ""
"$ H='To: to@example.com, to2@example.com\\nCc: cc@example.com, cc2@example.com\\nBcc: bcc@example.com,bcc2@example.com\\n'\n"
"$ printf \"$H\" | awk '/^To: .*$/ { print $0 }'\n"
"To: to@example.com, to2@example.com\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { print m }'\n"
"awk: ligne de commande:1: (FILENAME=- FNR=1) fatal : tentative d'utilisation du tableau « m » dans un contexte scalaire\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { print m[0] }'\n"
"To: to@example.com, to2@example.com\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { print m[1] }'\n"
"to@example.com, to2@example.com\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, \" \"); print tos }'\n"
"awk: ligne de commande:1: (FILENAME=- FNR=1) fatal : tentative d'utilisation du tableau « tos » dans un contexte scalaire\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, \" \"); print tos[0] }'\n"
"\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, \" \"); print tos[1] }'\n"
"to@example.com,\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, \" \"); print tos[2] }'\n"
"to2@example.com\n"
"$ printf \"$H\" | awk 'match($0, /^To: (.*)$/, m) { split(m[1], tos, \" \"); print tos[3] }'\n"
"\n"
msgstr ""

msgid ""
"(This isn't the verbatim interactive session, but a cleaned version to make "
"it more readable.)"
msgstr ""

msgid ""
"At this point, I realized I needed a for loop over the `tos` array, and I "
"moved the Awk snippet into the `~/bin/dispatch-email.sh`. I liked the final "
"thing:"
msgstr ""

msgid ""
"match($0, /^(To|Cc|Bcc): (.*)$/, m) {\n"
"  split(m[2], tos, \",\")\n"
"  for (i in tos) {\n"
"    print \"--mail-rcpt \" tos[i]\n"
"  }\n"
"}\n"
msgstr ""

msgid ""
"As I learn more about Awk, I feel that it is too undervalued, as many people"
" turn to Perl or other programming languages when Awk suffices. The "
"advantage is pretty clear: writing programs that run on any POSIX system, "
"without extra dependencies required."
msgstr ""

msgid "Coding to the standards is underrated."
msgstr ""

msgid ""
"#!/bin/sh -eu\n"
"\n"
"F=\"$1\"\n"
"\n"
"rcpt=\"$(awk '\n"
"  match($0, /^(To|Cc|Bcc): (.*)$/, m) {\n"
"    split(m[2], tos, \",\")\n"
"    for (i in tos) {\n"
"      print \"--mail-rcpt \" tos[i]\n"
"    }\n"
"  }\n"
"'  \"$F\")\"\n"
"\n"
"if grep -qE '^From: .*<addr@server1\\.org>$' \"$F\"; then\n"
"  curl                                                      \\\n"
"    -s                                                      \\\n"
"    --url smtp://smtp.server1.org:587                       \\\n"
"    --ssl-reqd                                              \\\n"
"    --mail-from addr@server1.org                            \\\n"
"    $rcpt                                                   \\\n"
"    --user 'addr@server1.org:my-long-and-secure-passphrase' \\\n"
"    --upload-file \"$F\"\n"
"elif grep -qE '^From: .*<addr@server2\\.org>$' \"$F\"; then\n"
"  curl                                                      \\\n"
"    -s                                                      \\\n"
"    --url smtp://smtp.server2.org:587                       \\\n"
"    --ssl-reqd                                              \\\n"
"    --mail-from addr@server2.org                            \\\n"
"    $rcpt                                                   \\\n"
"    --user 'addr@server2.org:my-long-and-secure-passphrase' \\\n"
"    --upload-file \"$F\"\n"
"else\n"
"  echo 'Bad \"From: \" address'\n"
"  exit 1\n"
"fi\n"
msgstr ""

msgid ""
"In the short Awk snippet, 3 things were new to me: the `match(...)`, "
"`split(...)` and `for () {}`. The only other function I have ever used was "
"`gsub(...)`, but these new ones felt similar enough that I could almost "
"guess their behaviour and arguments. `match(...)` stores the matches of a "
"regex on the given array positionally, and `split(...)` stores the chunks in"
" the given array."
msgstr ""

msgid "I even did it incrementally:"
msgstr ""

msgid ""
"As I experiment with [Neomutt](https://neomutt.org/), I wanted to keep being"
" able to enqueue emails for sending later like my previous setup, so that I "
"didn't rely on having an internet connection."
msgstr ""

#~ msgid ""
#~ "As I experimented with [Neomutt](https://neomutt.org/), I wanted to keep "
#~ "being able to enqueue emails for sending later like my previous setup, so "
#~ "that I didn't rely on having an internet connection."
#~ msgstr ""

#~ msgid "I even did this incrementally:"
#~ msgstr ""

#~ msgid ""
#~ "In the short Awk snippet, 3 things were new to me: the `match(...)`, "
#~ "`split(...)` and `for () {}`. The only other function I have ever used was "
#~ "`gsub(...)`, but these new felt similar enough that I could almost guess "
#~ "their behaviour. `match(...)` stores the matches of a regex on the given "
#~ "array positionally, and `split(...)` stores the chunks in the given array."
#~ msgstr ""

#~ msgid ""
#~ "As I experimented with [Neomutt](https://neomutt.org/), I wanted to keep "
#~ "being able to enqueue emails for sending later, so that I didn't rely on "
#~ "having an internet connection."
#~ msgstr ""

#~ msgid ""
#~ "#!/bin/sh -eu\n"
#~ "\n"
#~ "F=\"$1\"\n"
#~ "\n"
#~ "rcpt=\"$(awk '\n"
#~ "  match($0, /^(To|Cc|Bcc): (.*)$/, m) {\n"
#~ "    split(m[2], tos, \",\")\n"
#~ "    for (i in tos) {\n"
#~ "      print \"--mail-rcpt \" tos[i]\n"
#~ "    }\n"
#~ "  }\n"
#~ "'  \"$F\")\"\n"
#~ "\n"
#~ "if grep -qE '^From: .*<addr@server1\\.org>$' \"$F\"; then\n"
#~ "  curl                                                      \\\n"
#~ "    -s                                                      \\\n"
#~ "    --url smtp://smtp.server1.org:587                       \\\n"
#~ "    --ssl-reqd                                              \\\n"
#~ "    --mail-from addr@server1.org                            \\\n"
#~ "    $rcpt                                                   \\\n"
#~ "    --user 'addr@server1.org:my-long-and-secure-passphrase' \\\n"
#~ "    --upload-file \"$F\"\n"
#~ "eliif grep -qE '^From: .*<addr@server2\\.org>$' \"$F\"; then\n"
#~ "  curl                                                      \\\n"
#~ "    -s                                                      \\\n"
#~ "    --url smtp://smtp.server2.org:587                       \\\n"
#~ "    --ssl-reqd                                              \\\n"
#~ "    --mail-from addr@server2.org                            \\\n"
#~ "    $rcpt                                                   \\\n"
#~ "    --user 'addr@server2.org:my-long-and-secure-passphrase' \\\n"
#~ "    --upload-file \"$F\"\n"
#~ "else\n"
#~ "  echo 'Bad \"From: \" address'\n"
#~ "  exit 1\n"
#~ "fi\n"
#~ msgstr ""