aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-09-27 14:01:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-09-27 14:01:22 +0000
commitbed22a01fb19de6e4b4c2c7d8c5953bc7aa2580e (patch)
treeb10a0bd2e8a115f679cd0b955fc6661cea3e2d8a /networking
parent682ad3045c11f6d8961306b1a364289c2aae35ef (diff)
downloadbusybox-w32-bed22a01fb19de6e4b4c2c7d8c5953bc7aa2580e.tar.gz
busybox-w32-bed22a01fb19de6e4b4c2c7d8c5953bc7aa2580e.tar.bz2
busybox-w32-bed22a01fb19de6e4b4c2c7d8c5953bc7aa2580e.zip
sendmail: compat update by Vladimir
function old new delta sendgetmail_main 1889 2091 +202 putchar_unlocked - 43 +43 putchar - 43 +43 packed_usage 24868 24910 +42 smtp_checkp 102 111 +9 uuencode 235 227 -8 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 3/1 up/down: 339/-8) Total: 331 bytes
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.in21
-rw-r--r--networking/sendmail.c315
2 files changed, 202 insertions, 134 deletions
diff --git a/networking/Config.in b/networking/Config.in
index f23ca47c0..1984297a6 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -687,6 +687,27 @@ config SENDMAIL
687 help 687 help
688 Barebones sendmail. 688 Barebones sendmail.
689 689
690config FEATURE_SENDMAIL_MAILX
691 bool "Allow to specify subject, attachments and their charset"
692 default y
693 depends on SENDMAIL
694 help
695 Allow to specify subject, attachments and their charset.
696
697config FEATURE_SENDMAIL_SSL
698 bool "Allow to communicate via SSL/TLS"
699 default y
700 depends on SENDMAIL
701 help
702 Allow to use secure connections provided by openssl. E.g. @gmail.com.
703
704config FEATURE_SENDMAIL_CHARSET
705 string "Default charset"
706 default "utf-8"
707 depends on SENDMAIL
708 help
709 Default charset of the message.
710
690config FETCHMAIL 711config FETCHMAIL
691 bool "fetchmail" 712 bool "fetchmail"
692 default n 713 default n
diff --git a/networking/sendmail.c b/networking/sendmail.c
index c605d7c1b..6d00026e2 100644
--- a/networking/sendmail.c
+++ b/networking/sendmail.c
@@ -8,7 +8,38 @@
8 */ 8 */
9#include "libbb.h" 9#include "libbb.h"
10 10
11#define INITIAL_STDIN_FILENO 3 11struct globals {
12 pid_t helper_pid;
13 unsigned timeout;
14 FILE *fp0; // initial stdin
15 // arguments for SSL connection helper
16 const char *xargs[9];
17 // arguments for postprocess helper
18 const char *fargs[3];
19};
20#define G (*ptr_to_globals)
21#define helper_pid (G.helper_pid)
22#define timeout (G.timeout )
23#define fp0 (G.fp0 )
24#define xargs (G.xargs )
25#define fargs (G.fargs )
26#define INIT_G() do { \
27 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
28 xargs[0] = "openssl"; \
29 xargs[1] = "s_client"; \
30 xargs[2] = "-quiet"; \
31 xargs[3] = "-connect"; \
32 /*xargs[4] = "localhost";*/ \
33 xargs[5] = "-tls1"; \
34 xargs[6] = "-starttls"; \
35 xargs[7] = "smtp"; \
36 fargs[0] = CONFIG_FEATURE_SENDMAIL_CHARSET; \
37} while (0)
38
39#define opt_connect (xargs[4])
40#define opt_after_connect (xargs[5])
41#define opt_charset (fargs[0])
42#define opt_subject (fargs[1])
12 43
13static void uuencode(char *fname, const char *text) 44static void uuencode(char *fname, const char *text)
14{ 45{
@@ -18,14 +49,12 @@ static void uuencode(char *fname, const char *text)
18 }; 49 };
19 50
20#define src_buf text 51#define src_buf text
21 int fd; 52 FILE *fp = fp;
22#define len fd 53 ssize_t len = len;
23 char dst_buf[DST_BUF_SIZE + 1]; 54 char dst_buf[DST_BUF_SIZE + 1];
24 55
25 if (fname) { 56 if (fname) {
26 fd = INITIAL_STDIN_FILENO; 57 fp = (NOT_LONE_DASH(fname)) ? xfopen_for_read(fname) : fp0;
27 if (NOT_LONE_DASH(fname))
28 fd = xopen(fname, O_RDONLY);
29 src_buf = bb_common_bufsiz1; 58 src_buf = bb_common_bufsiz1;
30 // N.B. strlen(NULL) segfaults! 59 // N.B. strlen(NULL) segfaults!
31 } else if (text) { 60 } else if (text) {
@@ -35,11 +64,10 @@ static void uuencode(char *fname, const char *text)
35 } else 64 } else
36 return; 65 return;
37 66
38 fflush(stdout); // sync stdio and unistd output
39 while (1) { 67 while (1) {
40 size_t size; 68 size_t size;
41 if (fname) { 69 if (fname) {
42 size = full_read(fd, (char *)src_buf, SRC_BUF_SIZE); 70 size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp);
43 if ((ssize_t)size < 0) 71 if ((ssize_t)size < 0)
44 bb_perror_msg_and_die(bb_msg_read_error); 72 bb_perror_msg_and_die(bb_msg_read_error);
45 } else { 73 } else {
@@ -52,50 +80,20 @@ static void uuencode(char *fname, const char *text)
52 // encode the buffer we just read in 80 // encode the buffer we just read in
53 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); 81 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64);
54 if (fname) { 82 if (fname) {
55 xwrite(STDOUT_FILENO, "\r\n", 2); 83 printf("\r\n");
56 } else { 84 } else {
57 src_buf += size; 85 src_buf += size;
58 len -= size; 86 len -= size;
59 } 87 }
60 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3)); 88 fwrite(dst_buf, 1, 4 * ((size + 2) / 3), stdout);
61 } 89 }
62 if (fname) 90 if (fname)
63 close(fd); 91 fclose(fp);
64#undef src_buf 92#undef src_buf
65#undef len
66} 93}
67 94
68struct globals {
69 pid_t helper_pid;
70 unsigned timeout;
71 // arguments for SSL connection helper
72 const char *xargs[9];
73 // arguments for postprocess helper
74 const char *fargs[3];
75};
76#define G (*ptr_to_globals)
77#define helper_pid (G.helper_pid)
78#define timeout (G.timeout )
79#define xargs (G.xargs )
80#define fargs (G.fargs )
81#define INIT_G() do { \
82 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
83 xargs[0] = "openssl"; \
84 xargs[1] = "s_client"; \
85 xargs[2] = "-quiet"; \
86 xargs[3] = "-connect"; \
87 /*xargs[4] = "localhost";*/ \
88 xargs[5] = "-tls1"; \
89 xargs[6] = "-starttls"; \
90 xargs[7] = "smtp"; \
91 fargs[0] = "utf-8"; \
92} while (0)
93
94#define opt_connect (xargs[4])
95#define opt_after_connect (xargs[5])
96#define opt_charset (fargs[0])
97#define opt_subject (fargs[1])
98 95
96#if ENABLE_FEATURE_SENDMAIL_SSL
99static void kill_helper(void) 97static void kill_helper(void)
100{ 98{
101 // TODO!!!: is there more elegant way to terminate child on program failure? 99 // TODO!!!: is there more elegant way to terminate child on program failure?
@@ -107,7 +105,6 @@ static void kill_helper(void)
107static void signal_handler(int signo) 105static void signal_handler(int signo)
108{ 106{
109#define err signo 107#define err signo
110
111 if (SIGALRM == signo) { 108 if (SIGALRM == signo) {
112 kill_helper(); 109 kill_helper();
113 bb_error_msg_and_die("timed out"); 110 bb_error_msg_and_die("timed out");
@@ -151,6 +148,10 @@ static void launch_helper(const char **argv)
151 signal_handler(SIGCHLD); 148 signal_handler(SIGCHLD);
152 // child seems OK -> parent goes on 149 // child seems OK -> parent goes on
153} 150}
151#else
152#define kill_helper() ((void)0)
153#define launch_helper(x) bb_error_msg_and_die("no SSL support")
154#endif
154 155
155static const char *command(const char *fmt, const char *param) 156static const char *command(const char *fmt, const char *param)
156{ 157{
@@ -177,15 +178,14 @@ static int smtp_checkp(const char *fmt, const char *param, int code)
177 while ((answer = xmalloc_fgetline(stdin)) != NULL) 178 while ((answer = xmalloc_fgetline(stdin)) != NULL)
178 if (strlen(answer) <= 3 || '-' != answer[3]) 179 if (strlen(answer) <= 3 || '-' != answer[3])
179 break; 180 break;
181//bb_error_msg("FMT[%s]ANS[%s]", fmt, answer);
180 if (answer) { 182 if (answer) {
181 int n = atoi(answer); 183 int n = atoi(answer);
184//bb_error_msg("FMT[%s]COD[%d][%d]", fmt, n, code);
182 alarm(0); 185 alarm(0);
183 if (ENABLE_FEATURE_CLEAN_UP) { 186 free(answer);
184 free(answer); 187 if (-1 == code || n == code)
185 }
186 if (-1 == code || n == code) {
187 return n; 188 return n;
188 }
189 } 189 }
190 kill_helper(); 190 kill_helper();
191 bb_error_msg_and_die("%s failed", msg); 191 bb_error_msg_and_die("%s failed", msg);
@@ -283,30 +283,34 @@ static void rcptto(const char *s)
283int sendgetmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 283int sendgetmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
284int sendgetmail_main(int argc UNUSED_PARAM, char **argv) 284int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
285{ 285{
286#if ENABLE_FEATURE_SENDMAIL_MAILX
286 llist_t *opt_attachments = NULL; 287 llist_t *opt_attachments = NULL;
287 char *opt_from; 288#endif
289 char *opt_from, *opt_fullname;
288 const char *opt_user; 290 const char *opt_user;
289 const char *opt_pass; 291 const char *opt_pass;
292
290 enum { 293 enum {
291 OPT_w = 1 << 0, // network timeout 294 OPT_w = 1 << 0, // network timeout
295
292 OPT_H = 1 << 1, // [user:password@]server[:port] 296 OPT_H = 1 << 1, // [user:password@]server[:port]
293 OPT_S = 1 << 2, // connect using openssl s_client helper 297 OPT_S = 1 << 2, // connect using openssl s_client helper
294 298
295 OPTS_t = 1 << 3, // sendmail: read addresses from body 299 OPTS_t = 1 << 3, // sendmail: read message for recipients
296 OPTF_t = 1 << 3, // fetchmail: use "TOP" not "RETR" 300 OPTF_t = 1 << 3, // fetchmail: use "TOP" not "RETR"
297 301
298 OPTS_s = 1 << 4, // sendmail: subject 302 OPTS_N = 1 << 4, // sendmail: request notification
299 OPTF_z = 1 << 4, // fetchmail: delete from server 303 OPTF_z = 1 << 4, // fetchmail: delete from server
300 304
301 OPTS_c = 1 << 5, // sendmail: assumed charset 305 OPTS_f = 1 << 5, // sendmail: sender address
302 OPTS_a = 1 << 6, // sendmail: attachment(s) 306 OPTS_F = 1 << 6, // sendmail: sender name, overrides $NAME
303 OPTS_i = 1 << 7, // sendmail: ignore lone dots in message body (implied)
304 307
305 OPTS_N = 1 << 8, // sendmail: request notification 308 OPTS_s = 1 << 7, // sendmail: subject
306 OPTS_f = 1 << 9, // sendmail: sender address 309 OPTS_c = 1 << 8, // sendmail: assumed charset
310 OPTS_a = 1 << 9, // sendmail: attachment(s)
307 }; 311 };
308 const char *options; 312 const char *options;
309 int opts; 313 unsigned opts;
310 314
311 // init global variables 315 // init global variables
312 INIT_G(); 316 INIT_G();
@@ -317,11 +321,11 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
317 if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) { 321 if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) {
318 // SENDMAIL 322 // SENDMAIL
319 // save initial stdin since body is piped! 323 // save initial stdin since body is piped!
320 xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); 324 xdup2(STDIN_FILENO, 3);
325 fp0 = fdopen(3, "r");
321 opt_complementary = "w+:a::"; 326 opt_complementary = "w+:a::";
322 options = "w:H:St" "s:c:a:iN:f:"; 327 options = "w:H:St" "N:f:F:" USE_FEATURE_SENDMAIL_MAILX("s:c:a:")
323 // body is pseudo attachment read from stdin 328 "X:V:vq:R:O:o:nmL:Iih:GC:B:b:A:"; // postfix compat only, ignored
324 llist_add_to_end(&opt_attachments, (char *)"-");
325 } else { 329 } else {
326 // FETCHMAIL 330 // FETCHMAIL
327 opt_after_connect = NULL; 331 opt_after_connect = NULL;
@@ -330,15 +334,19 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
330 } 334 }
331 opts = getopt32(argv, options, 335 opts = getopt32(argv, options,
332 &timeout /* -w */, &opt_connect /* -H */, 336 &timeout /* -w */, &opt_connect /* -H */,
333 &opt_subject, &opt_charset, &opt_attachments, NULL, &opt_from 337 NULL, &opt_from, &opt_fullname,
338#if ENABLE_FEATURE_SENDMAIL_MAILX
339 &opt_subject, &opt_charset, &opt_attachments,
340#endif
341 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
334 ); 342 );
335 //argc -= optind; 343 //argc -= optind;
336 argv += optind; 344 argv += optind;
337 345
338 // connect to server 346 // connect to server
339 // host[:port] not specified ? -> use $HOSTNAME. no $HOSTNAME ? -> use localhost 347 // host[:port] not specified ? -> use $SMTPHOST. no $SMTPHOST ? -> use localhost
340 if (!(opts & OPT_H)) { 348 if (!(opts & OPT_H)) {
341 opt_connect = getenv("HOSTNAME"); 349 opt_connect = getenv("SMTPHOST");
342 if (!opt_connect) 350 if (!opt_connect)
343 opt_connect = "127.0.0.1"; 351 opt_connect = "127.0.0.1";
344 } 352 }
@@ -376,18 +384,13 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
376 { 384 {
377 int code; 385 int code;
378 char *boundary; 386 char *boundary;
379 const char *fmt;
380 const char *p;
381 char *q;
382 llist_t *l; 387 llist_t *l;
383 llist_t *headers = NULL; 388 llist_t *headers = NULL;
389 char *domain = sane(safe_getdomainname());
384 390
385 // got no sender address? -> use username as a resort 391 // got no sender address? -> use username as a resort
386 if (!(opts & OPTS_f)) { 392 if (!(opts & OPTS_f)) {
387 char *domain = safe_getdomainname();
388 opt_from = xasprintf("%s@%s", opt_user, domain); 393 opt_from = xasprintf("%s@%s", opt_user, domain);
389 if (ENABLE_FEATURE_CLEAN_UP)
390 free(domain);
391 } 394 }
392 395
393 // introduce to server 396 // introduce to server
@@ -399,9 +402,11 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
399 } 402 }
400 403
401 // we should start with modern EHLO 404 // we should start with modern EHLO
402 if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) { 405 if (250 != smtp_checkp("EHLO %s", domain, -1)) {
403 smtp_checkp("HELO %s", opt_from, 250); 406 smtp_checkp("HELO %s", domain, 250);
404 } 407 }
408 if (ENABLE_FEATURE_CLEAN_UP)
409 free(domain);
405 410
406 // set sender 411 // set sender
407 // NOTE: if password has not been specified 412 // NOTE: if password has not been specified
@@ -431,37 +436,36 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
431 argv++; 436 argv++;
432 } 437 }
433 438
434 // if -t specified or no recipients specified -> enter all-included mode 439 // if -t specified or no recipients specified -> read recipients from message
435 // i.e. scan stdin for To:, Cc:, Bcc:, and Subject: lines ... 440 // i.e. scan stdin for To:, Cc:, Bcc: lines ...
436 // ... and then use the rest of stdin as message body 441 // ... and then use the rest of stdin as message body
437 // N.B. subject read from body has priority 442 // N.B. subject read from body can be further overrided with one specified on command line.
438 // over that specified on command line. 443 // recipients are merged. Bcc: lines are deleted
439 // recipients are merged
440 // N.B. other headers are collected and will be dumped verbatim 444 // N.B. other headers are collected and will be dumped verbatim
441 if (opts & OPTS_t || !headers) { 445 if (opts & OPTS_t || !headers) {
442 // fetch recipients and (optionally) subject 446 // fetch recipients and (optionally) subject
443 char *s; 447 char *s;
444 while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { 448 while ((s = xmalloc_fgetline(fp0)) != NULL) {
445 if (0 == strncasecmp("To: ", s, 4) || 0 == strncasecmp("Cc: ", s, 4)) { 449 if (0 == strncasecmp("To: ", s, 4) || 0 == strncasecmp("Cc: ", s, 4)) {
446 rcptto(sane(s+4)); 450 rcptto(sane(s+4));
447 llist_add_to_end(&headers, s); 451 llist_add_to_end(&headers, s);
448 } else if (0 == strncasecmp("Bcc: ", s, 5)) { 452 } else if (0 == strncasecmp("Bcc: ", s, 5)) {
449 rcptto(sane(s+5)); 453 rcptto(sane(s+5));
450 if (ENABLE_FEATURE_CLEAN_UP) 454 free(s);
451 free(s);
452 // N.B. Bcc vanishes from headers! 455 // N.B. Bcc vanishes from headers!
453/* } else if (0 == strncmp("From: ", s, 6)) { 456 } else if (0 == strncmp("Subject: ", s, 9)) {
454 opt_from = s+6; 457 // we read subject -> use it verbatim unless it is specified
455 opts |= OPTS_f; 458 // on command line
456*/ } else if (0 == strncmp("Subject: ", s, 9)) { 459 if (!(opts & OPTS_s))
457 opt_subject = s+9; 460 llist_add_to_end(&headers, s);
458 opts |= OPTS_s; 461 else
462 free(s);
459 } else if (s[0]) { 463 } else if (s[0]) {
460 // misc header 464 // misc header
461 llist_add_to_end(&headers, s); 465 llist_add_to_end(&headers, s);
462 } else { 466 } else {
463 free(s); 467 free(s);
464 break; // empty line 468 break; // stop on the first empty line
465 } 469 }
466 } 470 }
467 } 471 }
@@ -476,18 +480,27 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
476 free(l->data); 480 free(l->data);
477 } 481 }
478 482
479 // put address header 483 // put (possibly encoded) subject
480 printf("From: %s\r\n", opt_from);
481
482 // put encoded subject
483 if (opts & OPTS_c) 484 if (opts & OPTS_c)
484 sane((char *)opt_charset); 485 sane((char *)opt_charset);
485 if (opts & OPTS_s) { 486 if (opts & OPTS_s) {
486 printf("Subject: =?%s?B?", opt_charset); 487 printf("Subject: ");
487 uuencode(NULL, opt_subject); 488 if (opts & OPTS_c) {
488 printf("?=\r\n"); 489 printf("=?%s?B?", opt_charset);
490 uuencode(NULL, opt_subject);
491 printf("?=");
492 } else {
493 printf("%s", opt_subject);
494 }
495 printf("\r\n");
489 } 496 }
490 497
498 // put sender name, $NAME is the default
499 if (!(opts & OPTS_F))
500 opt_fullname = getenv("NAME");
501 if (opt_fullname)
502 printf("From: \"%s\" <%s>\r\n", opt_fullname, opt_from);
503
491 // put notification 504 // put notification
492 if (opts & OPTS_N) 505 if (opts & OPTS_N)
493 printf("Disposition-Notification-To: %s\r\n", opt_from); 506 printf("Disposition-Notification-To: %s\r\n", opt_from);
@@ -496,58 +509,92 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
496 srand(monotonic_us()); 509 srand(monotonic_us());
497 boundary = xasprintf("%d-%d-%d", rand(), rand(), rand()); 510 boundary = xasprintf("%d-%d-%d", rand(), rand(), rand());
498 511
499 // put common headers and body start 512 // put common headers
500 printf( 513 // TODO: do we really need this?
501 "Message-ID: <%s>\r\n" 514// printf("Message-ID: <%s>\r\n", boundary);
502 "Mime-Version: 1.0\r\n" 515
503 "%smultipart/mixed; boundary=\"%s\"\r\n" 516#if ENABLE_FEATURE_SENDMAIL_MAILX
504 , boundary 517 // have attachments? -> compose multipart MIME
505 , "Content-Type: " 518 if (opt_attachments) {
506 , boundary 519 const char *fmt;
507 ); 520 const char *p;
508 521 char *q;
509 // put body + attachment(s) 522
510 // N.B. all these weird things just to be tiny
511 // by reusing string patterns!
512 fmt =
513 "\r\n--%s\r\n"
514 "%stext/plain; charset=%s\r\n"
515 "%s%s\r\n"
516 "%s"
517 ;
518 p = opt_charset;
519 q = (char *)"";
520 l = opt_attachments;
521 while (l) {
522 printf( 523 printf(
523 fmt 524 "Mime-Version: 1.0\r\n"
524 , boundary 525 "%smultipart/mixed; boundary=\"%s\"\r\n"
525 , "Content-Type: " 526 , "Content-Type: "
526 , p 527 , boundary
527 , "Content-Disposition: inline"
528 , q
529 , "Content-Transfer-Encoding: base64\r\n"
530 ); 528 );
531 p = ""; 529
530 // body is pseudo attachment read from stdin in first turn
531 llist_add_to(&opt_attachments, (char *)"-");
532
533 // put body + attachment(s)
534 // N.B. all these weird things just to be tiny
535 // by reusing string patterns!
532 fmt = 536 fmt =
533 "\r\n--%s\r\n" 537 "\r\n--%s\r\n"
534 "%sapplication/octet-stream%s\r\n" 538 "%stext/plain; charset=%s\r\n"
535 "%s; filename=\"%s\"\r\n" 539 "%s%s\r\n"
536 "%s" 540 "%s"
537 ; 541 ;
538 uuencode(l->data, NULL); 542 p = opt_charset;
539 l = l->link; 543 q = (char *)"";
540 if (l) 544 l = opt_attachments;
541 q = bb_get_last_path_component_strip(l->data); 545 while (l) {
542 } 546 printf(
547 fmt
548 , boundary
549 , "Content-Type: "
550 , p
551 , "Content-Disposition: inline"
552 , q
553 , "Content-Transfer-Encoding: base64\r\n"
554 );
555 p = "";
556 fmt =
557 "\r\n--%s\r\n"
558 "%sapplication/octet-stream%s\r\n"
559 "%s; filename=\"%s\"\r\n"
560 "%s"
561 ;
562 uuencode(l->data, NULL);
563 l = l->link;
564 if (l)
565 q = bb_get_last_path_component_strip(l->data);
566 }
567
568 // put message terminator
569 printf("\r\n--%s--\r\n" "\r\n", boundary);
543 570
544 // put message terminator 571 // no attachments? -> just dump message
545 printf("\r\n--%s--\r\n" "\r\n", boundary); 572 } else
573#endif
574 {
575 char *s;
576 // terminate headers
577 printf("\r\n");
578 // put plain text respecting leading dots
579 while ((s = xmalloc_fgetline(fp0)) != NULL) {
580 // escape leading dots
581 // N.B. this feature is implied even if no -i switch given
582 // N.B. we need to escape the leading dot regardless of
583 // whether it is single or not character on the line
584 if (/*(opts & OPTS_i) && */ '.' == s[0] /*&& '\0' == s[1] */)
585 printf(".");
586 // dump read line
587 printf("%s\r\n", s);
588 }
589 }
546 590
547 // leave "put message" mode 591 // leave "put message" mode
548 smtp_check(".", 250); 592 smtp_check(".", 250);
549 // ... and say goodbye 593 // ... and say goodbye
550 smtp_check("QUIT", 221); 594 smtp_check("QUIT", 221);
595 // cleanup
596 if (ENABLE_FEATURE_CLEAN_UP)
597 fclose(fp0);
551 } 598 }
552#if ENABLE_FETCHMAIL 599#if ENABLE_FETCHMAIL
553/*************************************************** 600/***************************************************
@@ -671,5 +718,5 @@ int sendgetmail_main(int argc UNUSED_PARAM, char **argv)
671 } 718 }
672#endif // ENABLE_FETCHMAIL 719#endif // ENABLE_FETCHMAIL
673 720
674 return 0; 721 return EXIT_SUCCESS;
675} 722}