diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-27 21:24:08 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-27 21:24:08 +0000 |
commit | 3dee8e2bac464eb66b14ac42806c8611b6fb6a19 (patch) | |
tree | 5a5e72afc287b48be2659754c8692d020d06f976 | |
parent | bbd55c9ec71f6a65ea876951b8c51df7df8b8da6 (diff) | |
download | busybox-w32-3dee8e2bac464eb66b14ac42806c8611b6fb6a19.tar.gz busybox-w32-3dee8e2bac464eb66b14ac42806c8611b6fb6a19.tar.bz2 busybox-w32-3dee8e2bac464eb66b14ac42806c8611b6fb6a19.zip |
sendmail: update from maintainer
-rw-r--r-- | include/applets.h | 2 | ||||
-rw-r--r-- | include/usage.h | 15 | ||||
-rw-r--r-- | networking/sendmail.c | 130 |
3 files changed, 89 insertions, 58 deletions
diff --git a/include/applets.h b/include/applets.h index e7fc3c03c..591d715c8 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -306,7 +306,7 @@ USE_RX(APPLET(rx, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |||
306 | USE_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 306 | USE_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
307 | USE_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) | 307 | USE_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) |
308 | USE_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 308 | USE_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
309 | USE_SENDMAIL(APPLET_ODDNAME(sendmail, sendgetmail, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sendmail)) | 309 | USE_SENDMAIL(APPLET_ODDNAME(sendmail, sendgetmail, _BB_DIR_USR_SBIN, _BB_SUID_NEVER, sendmail)) |
310 | USE_SEQ(APPLET_NOFORK(seq, seq, _BB_DIR_USR_BIN, _BB_SUID_NEVER, seq)) | 310 | USE_SEQ(APPLET_NOFORK(seq, seq, _BB_DIR_USR_BIN, _BB_SUID_NEVER, seq)) |
311 | USE_SESTATUS(APPLET(sestatus, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 311 | USE_SESTATUS(APPLET(sestatus, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
312 | USE_SETARCH(APPLET(setarch, _BB_DIR_BIN, _BB_SUID_NEVER)) | 312 | USE_SETARCH(APPLET(setarch, _BB_DIR_BIN, _BB_SUID_NEVER)) |
diff --git a/include/usage.h b/include/usage.h index df8958060..dd66728be 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -1088,11 +1088,12 @@ | |||
1088 | "\n -S SECTORS" \ | 1088 | "\n -S SECTORS" \ |
1089 | 1089 | ||
1090 | #define fetchmail_trivial_usage \ | 1090 | #define fetchmail_trivial_usage \ |
1091 | "[-w timeout] [-U user] -P password [-X] [-t] [-z] server[:port] maildir [prog]" | 1091 | "[-w timeout] [-H server[:port]] [-U user] -P password [-X] [-t] [-z] maildir [prog]" |
1092 | #define fetchmail_full_usage "\n\n" \ | 1092 | #define fetchmail_full_usage "\n\n" \ |
1093 | "Fetch content of remote mailbox to local Maildir.\n" \ | 1093 | "Fetch content of remote mailbox to local Maildir.\n" \ |
1094 | "\nOptions:" \ | 1094 | "\nOptions:" \ |
1095 | "\n -w timeout Set timeout on network operations" \ | 1095 | "\n -w timeout Set timeout on network operations" \ |
1096 | "\n -H server[:port] Set server" \ | ||
1096 | "\n -U username Authenticate with specified username/password" \ | 1097 | "\n -U username Authenticate with specified username/password" \ |
1097 | "\n -P password" \ | 1098 | "\n -P password" \ |
1098 | "\n -X Use openssl connection helper for secured servers" \ | 1099 | "\n -X Use openssl connection helper for secured servers" \ |
@@ -3425,19 +3426,23 @@ | |||
3425 | #define selinuxenabled_full_usage "" | 3426 | #define selinuxenabled_full_usage "" |
3426 | 3427 | ||
3427 | #define sendmail_trivial_usage \ | 3428 | #define sendmail_trivial_usage \ |
3428 | "[-w timeout] [-U user] [-P password] [-X]\n" \ | 3429 | "[-w timeout] [-H server[:port]] [-U user] [-P password] [-X]\n" \ |
3429 | "-t to [-t to]... [-n] [-s subject] [-c charset] server[:port] from [body] [attachment ...]" | 3430 | "[-c charset] [-n] [-i] [-s subject] [-a attach]... [-t] [-f sender] [rcpt]..." |
3430 | #define sendmail_full_usage "\n\n" \ | 3431 | #define sendmail_full_usage "\n\n" \ |
3431 | "Send an email.\n" \ | 3432 | "Send an email.\n" \ |
3432 | "\nOptions:" \ | 3433 | "\nOptions:" \ |
3433 | "\n -w timeout Set timeout on network operations" \ | 3434 | "\n -w timeout Set timeout on network operations" \ |
3435 | "\n -H server[:port] Set server" \ | ||
3434 | "\n -U username Authenticate with specified username/password" \ | 3436 | "\n -U username Authenticate with specified username/password" \ |
3435 | "\n -P password" \ | 3437 | "\n -P password" \ |
3436 | "\n -t address Recipient(s). May be repeated" \ | ||
3437 | "\n -X Use openssl connection helper for secured servers" \ | 3438 | "\n -X Use openssl connection helper for secured servers" \ |
3439 | "\n -c charset Assumed charset for body and subject [utf-8]" \ | ||
3438 | "\n -n Request delivery notification to sender" \ | 3440 | "\n -n Request delivery notification to sender" \ |
3441 | "\n -i Ignore single dots in mail body. Implied" \ | ||
3439 | "\n -s subject Subject" \ | 3442 | "\n -s subject Subject" \ |
3440 | "\n -c charset Assumed charset for body and subject [utf-8]" \ | 3443 | "\n -a file File to attach. May be multiple" \ |
3444 | "\n -t Read recipients and subject from body" \ | ||
3445 | "\n -f Set sender address" \ | ||
3441 | 3446 | ||
3442 | #define seq_trivial_usage \ | 3447 | #define seq_trivial_usage \ |
3443 | "[first [increment]] last" | 3448 | "[first [increment]] last" |
diff --git a/networking/sendmail.c b/networking/sendmail.c index 027656dd8..071d9d62d 100644 --- a/networking/sendmail.c +++ b/networking/sendmail.c | |||
@@ -61,6 +61,8 @@ static void uuencode(char *fname, const char *text) | |||
61 | } | 61 | } |
62 | if (fname) | 62 | if (fname) |
63 | close(fd); | 63 | close(fd); |
64 | #undef src_buf | ||
65 | #undef len | ||
64 | } | 66 | } |
65 | 67 | ||
66 | struct globals { | 68 | struct globals { |
@@ -82,7 +84,7 @@ struct globals { | |||
82 | xargs[1] = "s_client"; \ | 84 | xargs[1] = "s_client"; \ |
83 | xargs[2] = "-quiet"; \ | 85 | xargs[2] = "-quiet"; \ |
84 | xargs[3] = "-connect"; \ | 86 | xargs[3] = "-connect"; \ |
85 | /*xargs[4] = "server[:port]";*/ \ | 87 | /*xargs[4] = "localhost";*/ \ |
86 | xargs[5] = "-tls1"; \ | 88 | xargs[5] = "-tls1"; \ |
87 | xargs[6] = "-starttls"; \ | 89 | xargs[6] = "-starttls"; \ |
88 | xargs[7] = "smtp"; \ | 90 | xargs[7] = "smtp"; \ |
@@ -115,6 +117,16 @@ static void signal_handler(int signo) | |||
115 | if (wait_any_nohang(&err) > 0) | 117 | if (wait_any_nohang(&err) > 0) |
116 | if (WIFEXITED(err) && WEXITSTATUS(err)) | 118 | if (WIFEXITED(err) && WEXITSTATUS(err)) |
117 | bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err)); | 119 | bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err)); |
120 | #undef err | ||
121 | } | ||
122 | |||
123 | /* libbb candidate */ | ||
124 | static pid_t vfork_or_die(void) | ||
125 | { | ||
126 | pid_t pid = vfork(); | ||
127 | if (pid < 0) | ||
128 | bb_perror_msg_and_die("vfork"); | ||
129 | return pid; | ||
118 | } | 130 | } |
119 | 131 | ||
120 | static void launch_helper(const char **argv) | 132 | static void launch_helper(const char **argv) |
@@ -122,12 +134,11 @@ static void launch_helper(const char **argv) | |||
122 | // setup vanilla unidirectional pipes interchange | 134 | // setup vanilla unidirectional pipes interchange |
123 | int idx; | 135 | int idx; |
124 | int pipes[4]; | 136 | int pipes[4]; |
137 | |||
125 | xpipe(pipes); | 138 | xpipe(pipes); |
126 | xpipe(pipes+2); | 139 | xpipe(pipes+2); |
127 | helper_pid = vfork(); | 140 | helper_pid = vfork_or_die(); |
128 | if (helper_pid < 0) | 141 | idx = (!helper_pid) * 2; |
129 | bb_perror_msg_and_die("vfork"); | ||
130 | idx = (!helper_pid)*2; | ||
131 | xdup2(pipes[idx], STDIN_FILENO); | 142 | xdup2(pipes[idx], STDIN_FILENO); |
132 | xdup2(pipes[3-idx], STDOUT_FILENO); | 143 | xdup2(pipes[3-idx], STDOUT_FILENO); |
133 | if (ENABLE_FEATURE_CLEAN_UP) | 144 | if (ENABLE_FEATURE_CLEAN_UP) |
@@ -255,29 +266,31 @@ int sendgetmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
255 | int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | 266 | int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) |
256 | { | 267 | { |
257 | llist_t *opt_recipients = NULL; | 268 | llist_t *opt_recipients = NULL; |
258 | 269 | llist_t *opt_attachments = NULL; | |
270 | char *opt_from; | ||
259 | const char *opt_user; | 271 | const char *opt_user; |
260 | const char *opt_pass; | 272 | const char *opt_pass; |
261 | |||
262 | enum { | 273 | enum { |
263 | OPT_w = 1 << 0, // network timeout | 274 | OPT_w = 1 << 0, // network timeout |
264 | OPT_U = 1 << 1, // user | 275 | OPT_H = 1 << 1, // server[:port] |
265 | OPT_P = 1 << 2, // password | 276 | OPT_U = 1 << 2, // user |
266 | OPT_X = 1 << 3, // connect using openssl s_client helper | 277 | OPT_P = 1 << 3, // password |
278 | OPT_X = 1 << 4, // connect using openssl s_client helper | ||
267 | 279 | ||
268 | OPTS_n = 1 << 4, // sendmail: request notification | 280 | OPTS_t = 1 << 5, // sendmail: read addresses from body |
269 | OPTF_t = 1 << 4, // fetchmail: use "TOP" not "RETR" | 281 | OPTF_t = 1 << 5, // fetchmail: use "TOP" not "RETR" |
270 | 282 | ||
271 | OPTS_s = 1 << 5, // sendmail: subject | 283 | OPTS_s = 1 << 6, // sendmail: subject |
272 | OPTF_z = 1 << 5, // fetchmail: delete from server | 284 | OPTF_z = 1 << 6, // fetchmail: delete from server |
273 | 285 | ||
274 | OPTS_c = 1 << 6, // sendmail: assumed charset | 286 | OPTS_c = 1 << 7, // sendmail: assumed charset |
275 | OPTS_t = 1 << 7, // sendmail: recipient(s) | 287 | OPTS_a = 1 << 8, // sendmail: attachment(s) |
276 | OPTS_i = 1 << 8, // sendmail: ignore lone dots in message body (implied) | 288 | OPTS_i = 1 << 9, // sendmail: ignore lone dots in message body (implied) |
277 | }; | ||
278 | 289 | ||
290 | OPTS_n = 1 << 10, // sendmail: request notification | ||
291 | }; | ||
279 | const char *options; | 292 | const char *options; |
280 | unsigned opts; | 293 | int opts; |
281 | 294 | ||
282 | // init global variables | 295 | // init global variables |
283 | INIT_G(); | 296 | INIT_G(); |
@@ -289,25 +302,30 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
289 | // SENDMAIL | 302 | // SENDMAIL |
290 | // save initial stdin (body or attachements can be piped!) | 303 | // save initial stdin (body or attachements can be piped!) |
291 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); | 304 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); |
292 | opt_complementary = "-2:w+:t::"; | 305 | opt_complementary = "w+:a::"; |
293 | options = "w:U:P:X" "ns:c:t:i"; | 306 | options = "w:H:U:P:Xt" "s:c:a:inf:"; |
307 | // body is pseudo attachment read from stdin | ||
308 | llist_add_to_end(&opt_attachments, (char *)"-"); | ||
294 | } else { | 309 | } else { |
295 | // FETCHMAIL | 310 | // FETCHMAIL |
296 | opt_after_connect = NULL; | 311 | opt_after_connect = NULL; |
297 | opt_complementary = "-2:w+:P"; | 312 | opt_complementary = "-1:w+:P"; |
298 | options = "w:U:P:X" "tz"; | 313 | options = "w:H:U:P:Xt" "z"; |
299 | } | 314 | } |
300 | opts = getopt32(argv, options, | 315 | opts = getopt32(argv, options, |
301 | &timeout, &opt_user, &opt_pass, | 316 | &timeout, &opt_connect, &opt_user, &opt_pass, |
302 | &opt_subject, &opt_charset, &opt_recipients | 317 | &opt_subject, &opt_charset, &opt_attachments, &opt_from |
303 | ); | 318 | ); |
304 | //argc -= optind; | 319 | //argc -= optind; |
305 | argv += optind; | 320 | argv += optind; |
306 | 321 | ||
307 | // first argument is remote server[:port] | ||
308 | opt_connect = *argv++; | ||
309 | |||
310 | // connect to server | 322 | // connect to server |
323 | // host[:port] not specified ? -> use $HOST. no $HOST ? -> use localhost | ||
324 | if (!(opts & OPT_H)) { | ||
325 | opt_connect = getenv("HOST"); | ||
326 | if (!opt_connect) | ||
327 | opt_connect = "127.0.0.1"; | ||
328 | } | ||
311 | // SSL ordered? -> | 329 | // SSL ordered? -> |
312 | if (opts & OPT_X) { | 330 | if (opts & OPT_X) { |
313 | // ... use openssl helper | 331 | // ... use openssl helper |
@@ -323,20 +341,27 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
323 | } | 341 | } |
324 | 342 | ||
325 | #if ENABLE_FETCHMAIL | 343 | #if ENABLE_FETCHMAIL |
326 | // we are sendmail? | 344 | // are we sendmail? |
327 | if (opt_after_connect) | 345 | if (opt_after_connect) |
328 | #endif | 346 | #endif |
329 | { | ||
330 | /*************************************************** | 347 | /*************************************************** |
331 | * SENDMAIL | 348 | * SENDMAIL |
332 | ***************************************************/ | 349 | ***************************************************/ |
333 | 350 | { | |
334 | char *opt_from; | ||
335 | int code; | 351 | int code; |
336 | char *boundary; | 352 | char *boundary; |
337 | const char *fmt; | 353 | const char *fmt; |
338 | const char *p; | 354 | const char *p; |
339 | char *q; | 355 | char *q; |
356 | llist_t *l; | ||
357 | |||
358 | // recipients specified as arguments | ||
359 | while (*argv) { | ||
360 | // loose test on email address validity | ||
361 | if (strchr(sane(*argv), '@')) | ||
362 | llist_add_to_end(&opt_recipients, *argv); | ||
363 | argv++; | ||
364 | } | ||
340 | 365 | ||
341 | // we didn't use SSL helper? -> | 366 | // we didn't use SSL helper? -> |
342 | if (!(opts & OPT_X)) { | 367 | if (!(opts & OPT_X)) { |
@@ -344,13 +369,13 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
344 | smtp_check(NULL, 220); | 369 | smtp_check(NULL, 220); |
345 | } | 370 | } |
346 | 371 | ||
347 | // get the sender | 372 | // if -t specified or no recipients specified -> enter all-included mode |
348 | opt_from = sane(*argv++); | ||
349 | |||
350 | // if no recipients _and_ no body files specified -> enter all-included mode | ||
351 | // i.e. scan stdin for To: and Subject: lines ... | 373 | // i.e. scan stdin for To: and Subject: lines ... |
352 | // ... and then use the rest of stdin as message body | 374 | // ... and then use the rest of stdin as message body |
353 | if (!opt_recipients && !*argv) { | 375 | // N.B. subject read from body has priority |
376 | // over that specified on command line. | ||
377 | // recipients are merged | ||
378 | if (opts & OPTS_t || !opt_recipients) { | ||
354 | // fetch recipients and (optionally) subject | 379 | // fetch recipients and (optionally) subject |
355 | char *s; | 380 | char *s; |
356 | while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { | 381 | while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { |
@@ -366,13 +391,11 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
366 | break; // empty line | 391 | break; // empty line |
367 | } | 392 | } |
368 | } | 393 | } |
369 | // order to read body from stdin | ||
370 | *--argv = (char *)"-"; | ||
371 | } | 394 | } |
372 | 395 | ||
373 | // introduce to server | 396 | // introduce to server |
374 | // we should start with modern EHLO | 397 | // we should start with modern EHLO |
375 | if (250 != smtp_checkp("EHLO %s", opt_from, -1)) { | 398 | if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) { |
376 | smtp_checkp("HELO %s", opt_from, 250); | 399 | smtp_checkp("HELO %s", opt_from, 250); |
377 | } | 400 | } |
378 | 401 | ||
@@ -404,8 +427,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
404 | } | 427 | } |
405 | 428 | ||
406 | // set recipients | 429 | // set recipients |
407 | for (llist_t *to = opt_recipients; to; to = to->link) { | 430 | for (l = opt_recipients; l; l = l->link) { |
408 | smtp_checkp("RCPT TO:<%s>", sane(to->data), 250); | 431 | smtp_checkp("RCPT TO:<%s>", sane(l->data), 250); |
409 | } | 432 | } |
410 | 433 | ||
411 | // enter "put message" mode | 434 | // enter "put message" mode |
@@ -413,8 +436,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
413 | 436 | ||
414 | // put address headers | 437 | // put address headers |
415 | printf("From: %s\r\n", opt_from); | 438 | printf("From: %s\r\n", opt_from); |
416 | for (llist_t *to = opt_recipients; to; to = to->link) { | 439 | for (l = opt_recipients; l; l = l->link) { |
417 | printf("To: %s\r\n", to->data); | 440 | printf("To: %s\r\n", l->data); |
418 | } | 441 | } |
419 | 442 | ||
420 | // put encoded subject | 443 | // put encoded subject |
@@ -455,7 +478,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
455 | ; | 478 | ; |
456 | p = opt_charset; | 479 | p = opt_charset; |
457 | q = (char *)""; | 480 | q = (char *)""; |
458 | while (*argv) { | 481 | l = opt_attachments; |
482 | while (l) { | ||
459 | printf( | 483 | printf( |
460 | fmt | 484 | fmt |
461 | , boundary | 485 | , boundary |
@@ -472,9 +496,10 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
472 | "%s; filename=\"%s\"\r\n" | 496 | "%s; filename=\"%s\"\r\n" |
473 | "%s" | 497 | "%s" |
474 | ; | 498 | ; |
475 | uuencode(*argv, NULL); | 499 | uuencode(l->data, NULL); |
476 | if (*(++argv)) | 500 | l = l->link; |
477 | q = bb_get_last_path_component_strip(*argv); | 501 | if (l) |
502 | q = bb_get_last_path_component_strip(l->data); | ||
478 | } | 503 | } |
479 | 504 | ||
480 | // put message terminator | 505 | // put message terminator |
@@ -484,12 +509,12 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
484 | smtp_check(".", 250); | 509 | smtp_check(".", 250); |
485 | // ... and say goodbye | 510 | // ... and say goodbye |
486 | smtp_check("QUIT", 221); | 511 | smtp_check("QUIT", 221); |
487 | 512 | } | |
488 | #if ENABLE_FETCHMAIL | 513 | #if ENABLE_FETCHMAIL |
489 | } else { | ||
490 | /*************************************************** | 514 | /*************************************************** |
491 | * FETCHMAIL | 515 | * FETCHMAIL |
492 | ***************************************************/ | 516 | ***************************************************/ |
517 | else { | ||
493 | 518 | ||
494 | char *buf; | 519 | char *buf; |
495 | unsigned nmsg; | 520 | unsigned nmsg; |
@@ -570,7 +595,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
570 | for (; nmsg; nmsg--) { | 595 | for (; nmsg; nmsg--) { |
571 | 596 | ||
572 | // generate unique filename | 597 | // generate unique filename |
573 | char *filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), pid, hostname); | 598 | char *filename = xasprintf("tmp/%llu.%u.%s", |
599 | monotonic_us(), (unsigned)pid, hostname); | ||
574 | char *target; | 600 | char *target; |
575 | int rc; | 601 | int rc; |
576 | 602 | ||
@@ -604,8 +630,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
604 | 630 | ||
605 | // Bye | 631 | // Bye |
606 | pop3_check("QUIT", NULL); | 632 | pop3_check("QUIT", NULL); |
607 | #endif // ENABLE_FETCHMAIL | ||
608 | } | 633 | } |
634 | #endif // ENABLE_FETCHMAIL | ||
609 | 635 | ||
610 | return 0; | 636 | return 0; |
611 | } | 637 | } |