Fossil SCM

Fixes to the "SMTP relay" alert send method. Add the --smtp-trace option to the "fossil email send" command. Expose and document the "email-send-relayhost" setting.

drh 2018-06-30 18:29 UTC smtp
Commit 006cc8143740974fc64a7ee2c3ed7a56b14e5d8db7c3bb382531bdcf6660c555
1 file changed +27 -7
+27 -7
--- src/email.c
+++ src/email.c
@@ -386,12 +386,18 @@
386386
const char *zCmd; /* Command to run for each email */
387387
const char *zFrom; /* Emails come from here */
388388
SmtpSession *pSmtp; /* SMTP relay connection */
389389
Blob out; /* For zDest=="blob" */
390390
char *zErr; /* Error message */
391
+ u32 mFlags; /* Flags */
391392
int bImmediateFail; /* On any error, call fossil_fatal() */
392393
};
394
+
395
+/* Allowed values for EmailSender flags */
396
+#define EMAIL_IMMEDIATE_FAIL 0x0001 /* Call fossil_fatal() on any error */
397
+#define EMAIL_SMTP_TRACE 0x0002 /* Write SMTP transcript to console */
398
+
393399
#endif /* INTERFACE */
394400
395401
/*
396402
** Shutdown an emailer. Clear all information other than the error message.
397403
*/
@@ -402,10 +408,11 @@
402408
p->db = 0;
403409
p->zDb = 0;
404410
p->zDir = 0;
405411
p->zCmd = 0;
406412
if( p->pSmtp ){
413
+ smtp_client_quit(p->pSmtp);
407414
smtp_session_free(p->pSmtp);
408415
p->pSmtp = 0;
409416
}
410417
blob_reset(&p->out);
411418
}
@@ -418,11 +425,11 @@
418425
fossil_free(p->zErr);
419426
va_start(ap, zFormat);
420427
p->zErr = vmprintf(zFormat, ap);
421428
va_end(ap);
422429
emailerShutdown(p);
423
- if( p->bImmediateFail ){
430
+ if( p->mFlags & EMAIL_IMMEDIATE_FAIL ){
424431
fossil_fatal("%s", p->zErr);
425432
}
426433
}
427434
428435
/*
@@ -466,17 +473,17 @@
466473
** zAltDest to cause all emails to be printed to the console for
467474
** debugging purposes.
468475
**
469476
** The EmailSender object returned must be freed using email_sender_free().
470477
*/
471
-EmailSender *email_sender_new(const char *zAltDest, int bImmediateFail){
478
+EmailSender *email_sender_new(const char *zAltDest, u32 mFlags){
472479
EmailSender *p;
473480
474481
p = fossil_malloc(sizeof(*p));
475482
memset(p, 0, sizeof(*p));
476483
blob_init(&p->out, 0, 0);
477
- p->bImmediateFail = bImmediateFail;
484
+ p->mFlags = mFlags;
478485
if( zAltDest ){
479486
p->zDest = zAltDest;
480487
}else{
481488
p->zDest = db_get("email-send-method","off");
482489
}
@@ -515,11 +522,14 @@
515522
blob_init(&p->out, 0, 0);
516523
}else if( fossil_strcmp(p->zDest, "relay")==0 ){
517524
const char *zRelay = 0;
518525
emailerGetSetting(p, &zRelay, "email-send-relayhost");
519526
if( zRelay ){
520
- p->pSmtp = smtp_session_new(p->zFrom, zRelay, SMTP_DIRECT);
527
+ u32 smtpFlags = SMTP_DIRECT;
528
+ if( mFlags & EMAIL_SMTP_TRACE ) smtpFlags |= SMTP_TRACE_STDOUT;
529
+ p->pSmtp = smtp_session_new(p->zFrom, zRelay, smtpFlags);
530
+ smtp_client_startup(p->pSmtp);
521531
}
522532
}
523533
return p;
524534
}
525535
@@ -729,11 +739,11 @@
729739
}else if( p->pSmtp ){
730740
char **azTo = 0;
731741
int nTo = 0;
732742
email_header_to(pHdr, &nTo, &azTo);
733743
if( nTo>0 ){
734
- smtp_send_msg(p->pSmtp, p->zFrom, nTo, azTo, blob_str(&all));
744
+ smtp_send_msg(p->pSmtp, p->zFrom, nTo, (const char**)azTo,blob_str(&all));
735745
email_header_to_free(nTo, azTo);
736746
}
737747
}else if( strcmp(p->zDest, "stdout")==0 ){
738748
char **azTo = 0;
739749
int nTo = 0;
@@ -801,10 +811,17 @@
801811
** SETTING: email-receive-dir width=40
802812
** Inbound email messages are saved as separate files in this directory,
803813
** for debugging analysis. Disable saving of inbound emails omitting
804814
** this setting, or making it an empty string.
805815
*/
816
+/*
817
+** SETTING: email-send-relayhost width=40
818
+** This is the hostname and TCP port to which output email messages
819
+** are sent when email-send-method is "relay". There should be an
820
+** SMTP server configured as a Mail Submission Agent listening on the
821
+** designated host and port and all times.
822
+*/
806823
807824
808825
/*
809826
** COMMAND: email
810827
**
@@ -833,10 +850,11 @@
833850
** email sending mechanism is currently configured.
834851
** Use this for testing the email configuration.
835852
** Options:
836853
**
837854
** --body FILENAME
855
+** --smtp-trace
838856
** --stdout
839857
** --subject|-S SUBJECT
840858
**
841859
** settings [NAME VALUE] With no arguments, list all email settings.
842860
** Or change the value of a single email setting.
@@ -907,13 +925,15 @@
907925
}else
908926
if( strncmp(zCmd, "send", nCmd)==0 ){
909927
Blob prompt, body, hdr;
910928
const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
911929
int i;
930
+ u32 mFlags = EMAIL_IMMEDIATE_FAIL;
912931
const char *zSubject = find_option("subject", "S", 1);
913932
const char *zSource = find_option("body", 0, 1);
914933
EmailSender *pSender;
934
+ if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_SMTP_TRACE;
915935
verify_all_options();
916936
blob_init(&prompt, 0, 0);
917937
blob_init(&body, 0, 0);
918938
blob_init(&hdr, 0, 0);
919939
blob_appendf(&hdr,"To: ");
@@ -929,11 +949,11 @@
929949
blob_read_from_file(&body, zSource, ExtFILE);
930950
}else{
931951
prompt_for_user_comment(&body, &prompt);
932952
}
933953
blob_add_final_newline(&body);
934
- pSender = email_sender_new(zDest, 1);
954
+ pSender = email_sender_new(zDest, mFlags);
935955
email_send(pSender, &hdr, &body);
936956
email_sender_free(pSender);
937957
blob_reset(&hdr);
938958
blob_reset(&body);
939959
blob_reset(&prompt);
@@ -1179,11 +1199,11 @@
11791199
/* We need to send a verification email */
11801200
Blob hdr, body;
11811201
EmailSender *pSender = email_sender_new(0,0);
11821202
blob_init(&hdr,0,0);
11831203
blob_init(&body,0,0);
1184
- blob_appendf(&hdr, "To: %s\n", zEAddr);
1204
+ blob_appendf(&hdr, "To: <%s>\n", zEAddr);
11851205
blob_appendf(&hdr, "Subject: Subscription verification\n");
11861206
blob_appendf(&body, zConfirmMsg/*works-like:"%s%s%s"*/,
11871207
g.zBaseURL, g.zBaseURL, zCode);
11881208
email_send(pSender, &hdr, &body);
11891209
style_header("Email Alert Verification");
11901210
--- src/email.c
+++ src/email.c
@@ -386,12 +386,18 @@
386 const char *zCmd; /* Command to run for each email */
387 const char *zFrom; /* Emails come from here */
388 SmtpSession *pSmtp; /* SMTP relay connection */
389 Blob out; /* For zDest=="blob" */
390 char *zErr; /* Error message */
 
391 int bImmediateFail; /* On any error, call fossil_fatal() */
392 };
 
 
 
 
 
393 #endif /* INTERFACE */
394
395 /*
396 ** Shutdown an emailer. Clear all information other than the error message.
397 */
@@ -402,10 +408,11 @@
402 p->db = 0;
403 p->zDb = 0;
404 p->zDir = 0;
405 p->zCmd = 0;
406 if( p->pSmtp ){
 
407 smtp_session_free(p->pSmtp);
408 p->pSmtp = 0;
409 }
410 blob_reset(&p->out);
411 }
@@ -418,11 +425,11 @@
418 fossil_free(p->zErr);
419 va_start(ap, zFormat);
420 p->zErr = vmprintf(zFormat, ap);
421 va_end(ap);
422 emailerShutdown(p);
423 if( p->bImmediateFail ){
424 fossil_fatal("%s", p->zErr);
425 }
426 }
427
428 /*
@@ -466,17 +473,17 @@
466 ** zAltDest to cause all emails to be printed to the console for
467 ** debugging purposes.
468 **
469 ** The EmailSender object returned must be freed using email_sender_free().
470 */
471 EmailSender *email_sender_new(const char *zAltDest, int bImmediateFail){
472 EmailSender *p;
473
474 p = fossil_malloc(sizeof(*p));
475 memset(p, 0, sizeof(*p));
476 blob_init(&p->out, 0, 0);
477 p->bImmediateFail = bImmediateFail;
478 if( zAltDest ){
479 p->zDest = zAltDest;
480 }else{
481 p->zDest = db_get("email-send-method","off");
482 }
@@ -515,11 +522,14 @@
515 blob_init(&p->out, 0, 0);
516 }else if( fossil_strcmp(p->zDest, "relay")==0 ){
517 const char *zRelay = 0;
518 emailerGetSetting(p, &zRelay, "email-send-relayhost");
519 if( zRelay ){
520 p->pSmtp = smtp_session_new(p->zFrom, zRelay, SMTP_DIRECT);
 
 
 
521 }
522 }
523 return p;
524 }
525
@@ -729,11 +739,11 @@
729 }else if( p->pSmtp ){
730 char **azTo = 0;
731 int nTo = 0;
732 email_header_to(pHdr, &nTo, &azTo);
733 if( nTo>0 ){
734 smtp_send_msg(p->pSmtp, p->zFrom, nTo, azTo, blob_str(&all));
735 email_header_to_free(nTo, azTo);
736 }
737 }else if( strcmp(p->zDest, "stdout")==0 ){
738 char **azTo = 0;
739 int nTo = 0;
@@ -801,10 +811,17 @@
801 ** SETTING: email-receive-dir width=40
802 ** Inbound email messages are saved as separate files in this directory,
803 ** for debugging analysis. Disable saving of inbound emails omitting
804 ** this setting, or making it an empty string.
805 */
 
 
 
 
 
 
 
806
807
808 /*
809 ** COMMAND: email
810 **
@@ -833,10 +850,11 @@
833 ** email sending mechanism is currently configured.
834 ** Use this for testing the email configuration.
835 ** Options:
836 **
837 ** --body FILENAME
 
838 ** --stdout
839 ** --subject|-S SUBJECT
840 **
841 ** settings [NAME VALUE] With no arguments, list all email settings.
842 ** Or change the value of a single email setting.
@@ -907,13 +925,15 @@
907 }else
908 if( strncmp(zCmd, "send", nCmd)==0 ){
909 Blob prompt, body, hdr;
910 const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
911 int i;
 
912 const char *zSubject = find_option("subject", "S", 1);
913 const char *zSource = find_option("body", 0, 1);
914 EmailSender *pSender;
 
915 verify_all_options();
916 blob_init(&prompt, 0, 0);
917 blob_init(&body, 0, 0);
918 blob_init(&hdr, 0, 0);
919 blob_appendf(&hdr,"To: ");
@@ -929,11 +949,11 @@
929 blob_read_from_file(&body, zSource, ExtFILE);
930 }else{
931 prompt_for_user_comment(&body, &prompt);
932 }
933 blob_add_final_newline(&body);
934 pSender = email_sender_new(zDest, 1);
935 email_send(pSender, &hdr, &body);
936 email_sender_free(pSender);
937 blob_reset(&hdr);
938 blob_reset(&body);
939 blob_reset(&prompt);
@@ -1179,11 +1199,11 @@
1179 /* We need to send a verification email */
1180 Blob hdr, body;
1181 EmailSender *pSender = email_sender_new(0,0);
1182 blob_init(&hdr,0,0);
1183 blob_init(&body,0,0);
1184 blob_appendf(&hdr, "To: %s\n", zEAddr);
1185 blob_appendf(&hdr, "Subject: Subscription verification\n");
1186 blob_appendf(&body, zConfirmMsg/*works-like:"%s%s%s"*/,
1187 g.zBaseURL, g.zBaseURL, zCode);
1188 email_send(pSender, &hdr, &body);
1189 style_header("Email Alert Verification");
1190
--- src/email.c
+++ src/email.c
@@ -386,12 +386,18 @@
386 const char *zCmd; /* Command to run for each email */
387 const char *zFrom; /* Emails come from here */
388 SmtpSession *pSmtp; /* SMTP relay connection */
389 Blob out; /* For zDest=="blob" */
390 char *zErr; /* Error message */
391 u32 mFlags; /* Flags */
392 int bImmediateFail; /* On any error, call fossil_fatal() */
393 };
394
395 /* Allowed values for EmailSender flags */
396 #define EMAIL_IMMEDIATE_FAIL 0x0001 /* Call fossil_fatal() on any error */
397 #define EMAIL_SMTP_TRACE 0x0002 /* Write SMTP transcript to console */
398
399 #endif /* INTERFACE */
400
401 /*
402 ** Shutdown an emailer. Clear all information other than the error message.
403 */
@@ -402,10 +408,11 @@
408 p->db = 0;
409 p->zDb = 0;
410 p->zDir = 0;
411 p->zCmd = 0;
412 if( p->pSmtp ){
413 smtp_client_quit(p->pSmtp);
414 smtp_session_free(p->pSmtp);
415 p->pSmtp = 0;
416 }
417 blob_reset(&p->out);
418 }
@@ -418,11 +425,11 @@
425 fossil_free(p->zErr);
426 va_start(ap, zFormat);
427 p->zErr = vmprintf(zFormat, ap);
428 va_end(ap);
429 emailerShutdown(p);
430 if( p->mFlags & EMAIL_IMMEDIATE_FAIL ){
431 fossil_fatal("%s", p->zErr);
432 }
433 }
434
435 /*
@@ -466,17 +473,17 @@
473 ** zAltDest to cause all emails to be printed to the console for
474 ** debugging purposes.
475 **
476 ** The EmailSender object returned must be freed using email_sender_free().
477 */
478 EmailSender *email_sender_new(const char *zAltDest, u32 mFlags){
479 EmailSender *p;
480
481 p = fossil_malloc(sizeof(*p));
482 memset(p, 0, sizeof(*p));
483 blob_init(&p->out, 0, 0);
484 p->mFlags = mFlags;
485 if( zAltDest ){
486 p->zDest = zAltDest;
487 }else{
488 p->zDest = db_get("email-send-method","off");
489 }
@@ -515,11 +522,14 @@
522 blob_init(&p->out, 0, 0);
523 }else if( fossil_strcmp(p->zDest, "relay")==0 ){
524 const char *zRelay = 0;
525 emailerGetSetting(p, &zRelay, "email-send-relayhost");
526 if( zRelay ){
527 u32 smtpFlags = SMTP_DIRECT;
528 if( mFlags & EMAIL_SMTP_TRACE ) smtpFlags |= SMTP_TRACE_STDOUT;
529 p->pSmtp = smtp_session_new(p->zFrom, zRelay, smtpFlags);
530 smtp_client_startup(p->pSmtp);
531 }
532 }
533 return p;
534 }
535
@@ -729,11 +739,11 @@
739 }else if( p->pSmtp ){
740 char **azTo = 0;
741 int nTo = 0;
742 email_header_to(pHdr, &nTo, &azTo);
743 if( nTo>0 ){
744 smtp_send_msg(p->pSmtp, p->zFrom, nTo, (const char**)azTo,blob_str(&all));
745 email_header_to_free(nTo, azTo);
746 }
747 }else if( strcmp(p->zDest, "stdout")==0 ){
748 char **azTo = 0;
749 int nTo = 0;
@@ -801,10 +811,17 @@
811 ** SETTING: email-receive-dir width=40
812 ** Inbound email messages are saved as separate files in this directory,
813 ** for debugging analysis. Disable saving of inbound emails omitting
814 ** this setting, or making it an empty string.
815 */
816 /*
817 ** SETTING: email-send-relayhost width=40
818 ** This is the hostname and TCP port to which output email messages
819 ** are sent when email-send-method is "relay". There should be an
820 ** SMTP server configured as a Mail Submission Agent listening on the
821 ** designated host and port and all times.
822 */
823
824
825 /*
826 ** COMMAND: email
827 **
@@ -833,10 +850,11 @@
850 ** email sending mechanism is currently configured.
851 ** Use this for testing the email configuration.
852 ** Options:
853 **
854 ** --body FILENAME
855 ** --smtp-trace
856 ** --stdout
857 ** --subject|-S SUBJECT
858 **
859 ** settings [NAME VALUE] With no arguments, list all email settings.
860 ** Or change the value of a single email setting.
@@ -907,13 +925,15 @@
925 }else
926 if( strncmp(zCmd, "send", nCmd)==0 ){
927 Blob prompt, body, hdr;
928 const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
929 int i;
930 u32 mFlags = EMAIL_IMMEDIATE_FAIL;
931 const char *zSubject = find_option("subject", "S", 1);
932 const char *zSource = find_option("body", 0, 1);
933 EmailSender *pSender;
934 if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_SMTP_TRACE;
935 verify_all_options();
936 blob_init(&prompt, 0, 0);
937 blob_init(&body, 0, 0);
938 blob_init(&hdr, 0, 0);
939 blob_appendf(&hdr,"To: ");
@@ -929,11 +949,11 @@
949 blob_read_from_file(&body, zSource, ExtFILE);
950 }else{
951 prompt_for_user_comment(&body, &prompt);
952 }
953 blob_add_final_newline(&body);
954 pSender = email_sender_new(zDest, mFlags);
955 email_send(pSender, &hdr, &body);
956 email_sender_free(pSender);
957 blob_reset(&hdr);
958 blob_reset(&body);
959 blob_reset(&prompt);
@@ -1179,11 +1199,11 @@
1199 /* We need to send a verification email */
1200 Blob hdr, body;
1201 EmailSender *pSender = email_sender_new(0,0);
1202 blob_init(&hdr,0,0);
1203 blob_init(&body,0,0);
1204 blob_appendf(&hdr, "To: <%s>\n", zEAddr);
1205 blob_appendf(&hdr, "Subject: Subscription verification\n");
1206 blob_appendf(&body, zConfirmMsg/*works-like:"%s%s%s"*/,
1207 g.zBaseURL, g.zBaseURL, zCode);
1208 email_send(pSender, &hdr, &body);
1209 style_header("Email Alert Verification");
1210

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button