Fossil SCM

Automatic retry on an SMTP relay failure.

drh 2025-04-16 00:48 trunk
Commit 2b96941c4c924e56246d673a30d5ef5146824dfd7361af503c55bbf66fc4eac8
2 files changed -1 +36 -33
--- src/alerts.c
+++ src/alerts.c
@@ -655,11 +655,10 @@
655655
emailerError(p, "Could not start SMTP session: %s",
656656
p->pSmtp ? p->pSmtp->zErr : "reason unknown");
657657
}else if( p->zDest[0]=='d' ){
658658
smtp_session_config(p->pSmtp, SMTP_TRACE_BLOB, &p->out);
659659
}
660
- smtp_client_startup(p->pSmtp);
661660
}
662661
}
663662
return p;
664663
}
665664
666665
--- src/alerts.c
+++ src/alerts.c
@@ -655,11 +655,10 @@
655 emailerError(p, "Could not start SMTP session: %s",
656 p->pSmtp ? p->pSmtp->zErr : "reason unknown");
657 }else if( p->zDest[0]=='d' ){
658 smtp_session_config(p->pSmtp, SMTP_TRACE_BLOB, &p->out);
659 }
660 smtp_client_startup(p->pSmtp);
661 }
662 }
663 return p;
664 }
665
666
--- src/alerts.c
+++ src/alerts.c
@@ -655,11 +655,10 @@
655 emailerError(p, "Could not start SMTP session: %s",
656 p->pSmtp ? p->pSmtp->zErr : "reason unknown");
657 }else if( p->zDest[0]=='d' ){
658 smtp_session_config(p->pSmtp, SMTP_TRACE_BLOB, &p->out);
659 }
 
660 }
661 }
662 return p;
663 }
664
665
+36 -33
--- src/smtp.c
+++ src/smtp.c
@@ -156,14 +156,15 @@
156156
const char *zDest; /* Domain that will receive the email */
157157
char *zHostname; /* Hostname of SMTP server for zDest */
158158
u32 smtpFlags; /* Flags changing the operation */
159159
FILE *logFile; /* Write session transcript to this log file */
160160
Blob *pTranscript; /* Record session transcript here */
161
- int atEof; /* True after connection closes */
161
+ int bOpen; /* True if connection is Open */
162162
int bFatal; /* Error is fatal. Do not retry */
163163
char *zErr; /* Error message */
164164
Blob inbuf; /* Input buffer */
165
+ UrlData url; /* Address of the server */
165166
};
166167
167168
/* Allowed values for SmtpSession.smtpFlags */
168169
#define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
169170
#define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -198,12 +199,14 @@
198199
va_list ap;
199200
va_start(ap, zFormat);
200201
p->zErr = vmprintf(zFormat, ap);
201202
va_end(ap);
202203
}
203
- socket_close();
204
- p->atEof = 1;
204
+ if( p->bOpen ){
205
+ socket_close();
206
+ p->bOpen = 0;
207
+ }
205208
}
206209
207210
/*
208211
** Allocate a new SmtpSession object.
209212
**
@@ -218,43 +221,39 @@
218221
const char *zDest, /* Domain of the server */
219222
u32 smtpFlags, /* Flags */
220223
int iPort /* TCP port if the SMTP_PORT flags is present */
221224
){
222225
SmtpSession *p;
223
- UrlData url;
224226
225227
p = fossil_malloc( sizeof(*p) );
226228
memset(p, 0, sizeof(*p));
227229
p->zFrom = zFrom;
228230
p->zDest = zDest;
229231
p->smtpFlags = smtpFlags;
230
- memset(&url, 0, sizeof(url));
231
- url.port = 25;
232
+ p->url.port = 25;
232233
blob_init(&p->inbuf, 0, 0);
233234
if( smtpFlags & SMTP_PORT ){
234
- url.port = iPort;
235
+ p->url.port = iPort;
235236
}
236237
if( (smtpFlags & SMTP_DIRECT)!=0 ){
237238
int i;
238239
p->zHostname = fossil_strdup(zDest);
239240
for(i=0; p->zHostname[i] && p->zHostname[i]!=':'; i++){}
240241
if( p->zHostname[i]==':' ){
241242
p->zHostname[i] = 0;
242
- url.port = atoi(&p->zHostname[i+1]);
243
+ p->url.port = atoi(&p->zHostname[i+1]);
243244
}
244245
}else{
245246
p->zHostname = smtp_mx_host(zDest);
246247
}
247248
if( p->zHostname==0 ){
248249
smtp_set_error(p, 1, "cannot locate SMTP server for \"%s\"", zDest);
249250
return p;
250251
}
251
- url.name = p->zHostname;
252
+ p->url.name = p->zHostname;
252253
socket_global_init();
253
- if( socket_open(&url) ){
254
- smtp_set_error(p, 1, "can't open socket: %z", socket_errmsg());
255
- }
254
+ p->bOpen = 0;
256255
return p;
257256
}
258257
259258
/*
260259
** Configure debugging options on SmtpSession. Add all bits in
@@ -279,11 +278,11 @@
279278
static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
280279
Blob b = empty_blob;
281280
va_list ap;
282281
char *z;
283282
int n;
284
- if( p->atEof ) return;
283
+ if( !p->bOpen ) return;
285284
va_start(ap, zFormat);
286285
blob_vappendf(&b, zFormat, ap);
287286
va_end(ap);
288287
z = blob_buffer(&b);
289288
n = blob_size(&b);
@@ -315,11 +314,11 @@
315314
char *z = blob_buffer(&p->inbuf);
316315
int i = blob_tell(&p->inbuf);
317316
int nDelay = 0;
318317
if( i<n && z[n-1]=='\n' ){
319318
blob_line(&p->inbuf, in);
320
- }else if( p->atEof ){
319
+ }else if( !p->bOpen ){
321320
blob_init(in, 0, 0);
322321
}else{
323322
if( n>0 && i>=n ){
324323
blob_truncate(&p->inbuf, 0);
325324
blob_rewind(&p->inbuf);
@@ -376,10 +375,11 @@
376375
){
377376
int n;
378377
char *z;
379378
blob_truncate(in, 0);
380379
smtp_recv_line(p, in);
380
+ blob_trim(in);
381381
z = blob_str(in);
382382
n = blob_size(in);
383383
if( z[0]=='#' ){
384384
*piCode = 0;
385385
*pbMore = 1;
@@ -397,52 +397,57 @@
397397
int smtp_client_quit(SmtpSession *p){
398398
Blob in = BLOB_INITIALIZER;
399399
int iCode = 0;
400400
int bMore = 0;
401401
char *zArg = 0;
402
- if( !p->atEof ){
402
+ if( p->bOpen ){
403403
smtp_send_line(p, "QUIT\r\n");
404404
do{
405405
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
406406
}while( bMore );
407
- p->atEof = 1;
407
+ p->bOpen = 0;
408
+ socket_close();
408409
}
409
- socket_close();
410410
return 0;
411411
}
412412
413413
/*
414414
** Begin a client SMTP session. Wait for the initial 220 then send
415415
** the EHLO and wait for a 250.
416416
**
417417
** Return 0 on success and non-zero for a failure.
418418
*/
419
-int smtp_client_startup(SmtpSession *p){
419
+static int smtp_client_startup(SmtpSession *p){
420420
Blob in = BLOB_INITIALIZER;
421421
int iCode = 0;
422422
int bMore = 0;
423423
char *zArg = 0;
424424
if( p==0 || p->bFatal ) return 1;
425
- fossil_free(p->zErr);
426
- p->zErr = 0;
425
+ if( socket_open(&p->url) ){
426
+ smtp_set_error(p, 1, "can't open socket: %z", socket_errmsg());
427
+ return 1;
428
+ }
429
+ p->bOpen = 1;
427430
do{
428431
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
429432
}while( bMore );
430433
if( iCode!=220 ){
431
- smtp_set_error(p, 1, "server opens conversation with: %b", &in);
434
+ smtp_set_error(p, 1, "conversation begins with: \"%d %s\"",iCode,zArg);
432435
smtp_client_quit(p);
433436
return 1;
434437
}
435438
smtp_send_line(p, "EHLO %s\r\n", p->zFrom);
436439
do{
437440
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
438441
}while( bMore );
439442
if( iCode!=250 ){
440
- smtp_set_error(p, 1, "server responds to EHLO with: %b", &in);
443
+ smtp_set_error(p, 1, "reply to EHLO with: \"%d %s\"",iCode, zArg);
441444
smtp_client_quit(p);
442445
return 1;
443446
}
447
+ fossil_free(p->zErr);
448
+ p->zErr = 0;
444449
return 0;
445450
}
446451
447452
/*
448453
** COMMAND: test-smtp-probe
@@ -570,38 +575,38 @@
570575
int iCode = 0;
571576
int bMore = 0;
572577
char *zArg = 0;
573578
Blob in;
574579
blob_init(&in, 0, 0);
575
- if( p->atEof && !p->bFatal ){
576
- smtp_client_startup(p);
577
- if( p->atEof ) return 1;
580
+ if( !p->bOpen ){
581
+ if( !p->bFatal ) smtp_client_startup(p);
582
+ if( !p->bOpen ) return 1;
578583
}
579584
smtp_send_line(p, "MAIL FROM:<%s>\r\n", zFrom);
580585
do{
581586
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
582587
}while( bMore );
583588
if( iCode!=250 ){
584
- smtp_set_error(p, 0, "server replies to MAIL FROM with: %b", &in);
589
+ smtp_set_error(p, 0,"reply to MAIL FROM: \"%d %s\"",iCode,zArg);
585590
return 1;
586591
}
587592
for(i=0; i<nTo; i++){
588593
smtp_send_line(p, "RCPT TO:<%s>\r\n", azTo[i]);
589594
do{
590595
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
591596
}while( bMore );
592597
if( iCode!=250 ){
593
- smtp_set_error(p, 0, "server replies to RCPT TO with: %b", &in);
598
+ smtp_set_error(p, 0,"reply to RCPT TO: \"%d %s\"",iCode,zArg);
594599
return 1;
595600
}
596601
}
597602
smtp_send_line(p, "DATA\r\n");
598603
do{
599604
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
600605
}while( bMore );
601606
if( iCode!=354 ){
602
- smtp_set_error(p, 0, "server replies to DATA with: %b", &in);
607
+ smtp_set_error(p, 0, "reply to DATA with: \"%d %s\"",iCode,zArg);
603608
return 1;
604609
}
605610
smtp_send_email_body(zMsg, socket_send, 0);
606611
if( p->smtpFlags & SMTP_TRACE_STDOUT ){
607612
fossil_print("C: # message content\nC: .\n");
@@ -614,11 +619,12 @@
614619
}
615620
do{
616621
smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
617622
}while( bMore );
618623
if( iCode!=250 ){
619
- smtp_set_error(p, 0, "server replies to end-of-DATA with: %b", &in);
624
+ smtp_set_error(p, 0, "reply to end-of-DATA with: \"%d %s\"",
625
+ iCode, zArg);
620626
return 1;
621627
}
622628
return 0;
623629
}
624630
@@ -681,16 +687,13 @@
681687
p = smtp_session_new(zFromDomain, zToDomain, smtpFlags, smtpPort);
682688
if( p->zErr ){
683689
fossil_fatal("%s", p->zErr);
684690
}
685691
fossil_print("Connection to \"%s\"\n", p->zHostname);
686
- smtp_client_startup(p);
687
- if( !p->atEof ){
688
- smtp_send_msg(p, zFrom, nTo, azTo, blob_str(&body));
689
- }
692
+ smtp_send_msg(p, zFrom, nTo, azTo, blob_str(&body));
690693
smtp_client_quit(p);
691694
if( p->zErr ){
692695
fossil_fatal("ERROR: %s\n", p->zErr);
693696
}
694697
smtp_session_free(p);
695698
blob_reset(&body);
696699
}
697700
--- src/smtp.c
+++ src/smtp.c
@@ -156,14 +156,15 @@
156 const char *zDest; /* Domain that will receive the email */
157 char *zHostname; /* Hostname of SMTP server for zDest */
158 u32 smtpFlags; /* Flags changing the operation */
159 FILE *logFile; /* Write session transcript to this log file */
160 Blob *pTranscript; /* Record session transcript here */
161 int atEof; /* True after connection closes */
162 int bFatal; /* Error is fatal. Do not retry */
163 char *zErr; /* Error message */
164 Blob inbuf; /* Input buffer */
 
165 };
166
167 /* Allowed values for SmtpSession.smtpFlags */
168 #define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
169 #define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -198,12 +199,14 @@
198 va_list ap;
199 va_start(ap, zFormat);
200 p->zErr = vmprintf(zFormat, ap);
201 va_end(ap);
202 }
203 socket_close();
204 p->atEof = 1;
 
 
205 }
206
207 /*
208 ** Allocate a new SmtpSession object.
209 **
@@ -218,43 +221,39 @@
218 const char *zDest, /* Domain of the server */
219 u32 smtpFlags, /* Flags */
220 int iPort /* TCP port if the SMTP_PORT flags is present */
221 ){
222 SmtpSession *p;
223 UrlData url;
224
225 p = fossil_malloc( sizeof(*p) );
226 memset(p, 0, sizeof(*p));
227 p->zFrom = zFrom;
228 p->zDest = zDest;
229 p->smtpFlags = smtpFlags;
230 memset(&url, 0, sizeof(url));
231 url.port = 25;
232 blob_init(&p->inbuf, 0, 0);
233 if( smtpFlags & SMTP_PORT ){
234 url.port = iPort;
235 }
236 if( (smtpFlags & SMTP_DIRECT)!=0 ){
237 int i;
238 p->zHostname = fossil_strdup(zDest);
239 for(i=0; p->zHostname[i] && p->zHostname[i]!=':'; i++){}
240 if( p->zHostname[i]==':' ){
241 p->zHostname[i] = 0;
242 url.port = atoi(&p->zHostname[i+1]);
243 }
244 }else{
245 p->zHostname = smtp_mx_host(zDest);
246 }
247 if( p->zHostname==0 ){
248 smtp_set_error(p, 1, "cannot locate SMTP server for \"%s\"", zDest);
249 return p;
250 }
251 url.name = p->zHostname;
252 socket_global_init();
253 if( socket_open(&url) ){
254 smtp_set_error(p, 1, "can't open socket: %z", socket_errmsg());
255 }
256 return p;
257 }
258
259 /*
260 ** Configure debugging options on SmtpSession. Add all bits in
@@ -279,11 +278,11 @@
279 static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
280 Blob b = empty_blob;
281 va_list ap;
282 char *z;
283 int n;
284 if( p->atEof ) return;
285 va_start(ap, zFormat);
286 blob_vappendf(&b, zFormat, ap);
287 va_end(ap);
288 z = blob_buffer(&b);
289 n = blob_size(&b);
@@ -315,11 +314,11 @@
315 char *z = blob_buffer(&p->inbuf);
316 int i = blob_tell(&p->inbuf);
317 int nDelay = 0;
318 if( i<n && z[n-1]=='\n' ){
319 blob_line(&p->inbuf, in);
320 }else if( p->atEof ){
321 blob_init(in, 0, 0);
322 }else{
323 if( n>0 && i>=n ){
324 blob_truncate(&p->inbuf, 0);
325 blob_rewind(&p->inbuf);
@@ -376,10 +375,11 @@
376 ){
377 int n;
378 char *z;
379 blob_truncate(in, 0);
380 smtp_recv_line(p, in);
 
381 z = blob_str(in);
382 n = blob_size(in);
383 if( z[0]=='#' ){
384 *piCode = 0;
385 *pbMore = 1;
@@ -397,52 +397,57 @@
397 int smtp_client_quit(SmtpSession *p){
398 Blob in = BLOB_INITIALIZER;
399 int iCode = 0;
400 int bMore = 0;
401 char *zArg = 0;
402 if( !p->atEof ){
403 smtp_send_line(p, "QUIT\r\n");
404 do{
405 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
406 }while( bMore );
407 p->atEof = 1;
 
408 }
409 socket_close();
410 return 0;
411 }
412
413 /*
414 ** Begin a client SMTP session. Wait for the initial 220 then send
415 ** the EHLO and wait for a 250.
416 **
417 ** Return 0 on success and non-zero for a failure.
418 */
419 int smtp_client_startup(SmtpSession *p){
420 Blob in = BLOB_INITIALIZER;
421 int iCode = 0;
422 int bMore = 0;
423 char *zArg = 0;
424 if( p==0 || p->bFatal ) return 1;
425 fossil_free(p->zErr);
426 p->zErr = 0;
 
 
 
427 do{
428 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
429 }while( bMore );
430 if( iCode!=220 ){
431 smtp_set_error(p, 1, "server opens conversation with: %b", &in);
432 smtp_client_quit(p);
433 return 1;
434 }
435 smtp_send_line(p, "EHLO %s\r\n", p->zFrom);
436 do{
437 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
438 }while( bMore );
439 if( iCode!=250 ){
440 smtp_set_error(p, 1, "server responds to EHLO with: %b", &in);
441 smtp_client_quit(p);
442 return 1;
443 }
 
 
444 return 0;
445 }
446
447 /*
448 ** COMMAND: test-smtp-probe
@@ -570,38 +575,38 @@
570 int iCode = 0;
571 int bMore = 0;
572 char *zArg = 0;
573 Blob in;
574 blob_init(&in, 0, 0);
575 if( p->atEof && !p->bFatal ){
576 smtp_client_startup(p);
577 if( p->atEof ) return 1;
578 }
579 smtp_send_line(p, "MAIL FROM:<%s>\r\n", zFrom);
580 do{
581 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
582 }while( bMore );
583 if( iCode!=250 ){
584 smtp_set_error(p, 0, "server replies to MAIL FROM with: %b", &in);
585 return 1;
586 }
587 for(i=0; i<nTo; i++){
588 smtp_send_line(p, "RCPT TO:<%s>\r\n", azTo[i]);
589 do{
590 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
591 }while( bMore );
592 if( iCode!=250 ){
593 smtp_set_error(p, 0, "server replies to RCPT TO with: %b", &in);
594 return 1;
595 }
596 }
597 smtp_send_line(p, "DATA\r\n");
598 do{
599 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
600 }while( bMore );
601 if( iCode!=354 ){
602 smtp_set_error(p, 0, "server replies to DATA with: %b", &in);
603 return 1;
604 }
605 smtp_send_email_body(zMsg, socket_send, 0);
606 if( p->smtpFlags & SMTP_TRACE_STDOUT ){
607 fossil_print("C: # message content\nC: .\n");
@@ -614,11 +619,12 @@
614 }
615 do{
616 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
617 }while( bMore );
618 if( iCode!=250 ){
619 smtp_set_error(p, 0, "server replies to end-of-DATA with: %b", &in);
 
620 return 1;
621 }
622 return 0;
623 }
624
@@ -681,16 +687,13 @@
681 p = smtp_session_new(zFromDomain, zToDomain, smtpFlags, smtpPort);
682 if( p->zErr ){
683 fossil_fatal("%s", p->zErr);
684 }
685 fossil_print("Connection to \"%s\"\n", p->zHostname);
686 smtp_client_startup(p);
687 if( !p->atEof ){
688 smtp_send_msg(p, zFrom, nTo, azTo, blob_str(&body));
689 }
690 smtp_client_quit(p);
691 if( p->zErr ){
692 fossil_fatal("ERROR: %s\n", p->zErr);
693 }
694 smtp_session_free(p);
695 blob_reset(&body);
696 }
697
--- src/smtp.c
+++ src/smtp.c
@@ -156,14 +156,15 @@
156 const char *zDest; /* Domain that will receive the email */
157 char *zHostname; /* Hostname of SMTP server for zDest */
158 u32 smtpFlags; /* Flags changing the operation */
159 FILE *logFile; /* Write session transcript to this log file */
160 Blob *pTranscript; /* Record session transcript here */
161 int bOpen; /* True if connection is Open */
162 int bFatal; /* Error is fatal. Do not retry */
163 char *zErr; /* Error message */
164 Blob inbuf; /* Input buffer */
165 UrlData url; /* Address of the server */
166 };
167
168 /* Allowed values for SmtpSession.smtpFlags */
169 #define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
170 #define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -198,12 +199,14 @@
199 va_list ap;
200 va_start(ap, zFormat);
201 p->zErr = vmprintf(zFormat, ap);
202 va_end(ap);
203 }
204 if( p->bOpen ){
205 socket_close();
206 p->bOpen = 0;
207 }
208 }
209
210 /*
211 ** Allocate a new SmtpSession object.
212 **
@@ -218,43 +221,39 @@
221 const char *zDest, /* Domain of the server */
222 u32 smtpFlags, /* Flags */
223 int iPort /* TCP port if the SMTP_PORT flags is present */
224 ){
225 SmtpSession *p;
 
226
227 p = fossil_malloc( sizeof(*p) );
228 memset(p, 0, sizeof(*p));
229 p->zFrom = zFrom;
230 p->zDest = zDest;
231 p->smtpFlags = smtpFlags;
232 p->url.port = 25;
 
233 blob_init(&p->inbuf, 0, 0);
234 if( smtpFlags & SMTP_PORT ){
235 p->url.port = iPort;
236 }
237 if( (smtpFlags & SMTP_DIRECT)!=0 ){
238 int i;
239 p->zHostname = fossil_strdup(zDest);
240 for(i=0; p->zHostname[i] && p->zHostname[i]!=':'; i++){}
241 if( p->zHostname[i]==':' ){
242 p->zHostname[i] = 0;
243 p->url.port = atoi(&p->zHostname[i+1]);
244 }
245 }else{
246 p->zHostname = smtp_mx_host(zDest);
247 }
248 if( p->zHostname==0 ){
249 smtp_set_error(p, 1, "cannot locate SMTP server for \"%s\"", zDest);
250 return p;
251 }
252 p->url.name = p->zHostname;
253 socket_global_init();
254 p->bOpen = 0;
 
 
255 return p;
256 }
257
258 /*
259 ** Configure debugging options on SmtpSession. Add all bits in
@@ -279,11 +278,11 @@
278 static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
279 Blob b = empty_blob;
280 va_list ap;
281 char *z;
282 int n;
283 if( !p->bOpen ) return;
284 va_start(ap, zFormat);
285 blob_vappendf(&b, zFormat, ap);
286 va_end(ap);
287 z = blob_buffer(&b);
288 n = blob_size(&b);
@@ -315,11 +314,11 @@
314 char *z = blob_buffer(&p->inbuf);
315 int i = blob_tell(&p->inbuf);
316 int nDelay = 0;
317 if( i<n && z[n-1]=='\n' ){
318 blob_line(&p->inbuf, in);
319 }else if( !p->bOpen ){
320 blob_init(in, 0, 0);
321 }else{
322 if( n>0 && i>=n ){
323 blob_truncate(&p->inbuf, 0);
324 blob_rewind(&p->inbuf);
@@ -376,10 +375,11 @@
375 ){
376 int n;
377 char *z;
378 blob_truncate(in, 0);
379 smtp_recv_line(p, in);
380 blob_trim(in);
381 z = blob_str(in);
382 n = blob_size(in);
383 if( z[0]=='#' ){
384 *piCode = 0;
385 *pbMore = 1;
@@ -397,52 +397,57 @@
397 int smtp_client_quit(SmtpSession *p){
398 Blob in = BLOB_INITIALIZER;
399 int iCode = 0;
400 int bMore = 0;
401 char *zArg = 0;
402 if( p->bOpen ){
403 smtp_send_line(p, "QUIT\r\n");
404 do{
405 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
406 }while( bMore );
407 p->bOpen = 0;
408 socket_close();
409 }
 
410 return 0;
411 }
412
413 /*
414 ** Begin a client SMTP session. Wait for the initial 220 then send
415 ** the EHLO and wait for a 250.
416 **
417 ** Return 0 on success and non-zero for a failure.
418 */
419 static int smtp_client_startup(SmtpSession *p){
420 Blob in = BLOB_INITIALIZER;
421 int iCode = 0;
422 int bMore = 0;
423 char *zArg = 0;
424 if( p==0 || p->bFatal ) return 1;
425 if( socket_open(&p->url) ){
426 smtp_set_error(p, 1, "can't open socket: %z", socket_errmsg());
427 return 1;
428 }
429 p->bOpen = 1;
430 do{
431 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
432 }while( bMore );
433 if( iCode!=220 ){
434 smtp_set_error(p, 1, "conversation begins with: \"%d %s\"",iCode,zArg);
435 smtp_client_quit(p);
436 return 1;
437 }
438 smtp_send_line(p, "EHLO %s\r\n", p->zFrom);
439 do{
440 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
441 }while( bMore );
442 if( iCode!=250 ){
443 smtp_set_error(p, 1, "reply to EHLO with: \"%d %s\"",iCode, zArg);
444 smtp_client_quit(p);
445 return 1;
446 }
447 fossil_free(p->zErr);
448 p->zErr = 0;
449 return 0;
450 }
451
452 /*
453 ** COMMAND: test-smtp-probe
@@ -570,38 +575,38 @@
575 int iCode = 0;
576 int bMore = 0;
577 char *zArg = 0;
578 Blob in;
579 blob_init(&in, 0, 0);
580 if( !p->bOpen ){
581 if( !p->bFatal ) smtp_client_startup(p);
582 if( !p->bOpen ) return 1;
583 }
584 smtp_send_line(p, "MAIL FROM:<%s>\r\n", zFrom);
585 do{
586 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
587 }while( bMore );
588 if( iCode!=250 ){
589 smtp_set_error(p, 0,"reply to MAIL FROM: \"%d %s\"",iCode,zArg);
590 return 1;
591 }
592 for(i=0; i<nTo; i++){
593 smtp_send_line(p, "RCPT TO:<%s>\r\n", azTo[i]);
594 do{
595 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
596 }while( bMore );
597 if( iCode!=250 ){
598 smtp_set_error(p, 0,"reply to RCPT TO: \"%d %s\"",iCode,zArg);
599 return 1;
600 }
601 }
602 smtp_send_line(p, "DATA\r\n");
603 do{
604 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
605 }while( bMore );
606 if( iCode!=354 ){
607 smtp_set_error(p, 0, "reply to DATA with: \"%d %s\"",iCode,zArg);
608 return 1;
609 }
610 smtp_send_email_body(zMsg, socket_send, 0);
611 if( p->smtpFlags & SMTP_TRACE_STDOUT ){
612 fossil_print("C: # message content\nC: .\n");
@@ -614,11 +619,12 @@
619 }
620 do{
621 smtp_get_reply_from_server(p, &in, &iCode, &bMore, &zArg);
622 }while( bMore );
623 if( iCode!=250 ){
624 smtp_set_error(p, 0, "reply to end-of-DATA with: \"%d %s\"",
625 iCode, zArg);
626 return 1;
627 }
628 return 0;
629 }
630
@@ -681,16 +687,13 @@
687 p = smtp_session_new(zFromDomain, zToDomain, smtpFlags, smtpPort);
688 if( p->zErr ){
689 fossil_fatal("%s", p->zErr);
690 }
691 fossil_print("Connection to \"%s\"\n", p->zHostname);
692 smtp_send_msg(p, zFrom, nTo, azTo, blob_str(&body));
 
 
 
693 smtp_client_quit(p);
694 if( p->zErr ){
695 fossil_fatal("ERROR: %s\n", p->zErr);
696 }
697 smtp_session_free(p);
698 blob_reset(&body);
699 }
700

Keyboard Shortcuts

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