mailutils/*: add verbose option to sendmail; remove -m and -j from makemime
No binary (build failed)
—
(log yok)
| @@ -3211,36 +3211,6 @@ INSERT | |
| #define selinuxenabled_trivial_usage NOUSAGE_STR | |
| #define selinuxenabled_full_usage "" | |
| - | #define sendmail_trivial_usage \ |
| - | "[OPTIONS] [RECIPIENT_EMAIL]..." |
| - | #define sendmail_full_usage "\n\n" \ |
| - | "Read email from stdin and send it\n" \ |
| - | "\nStandard options:" \ |
| - | "\n -t Read additional recipients from message body" \ |
| - | "\n -f sender Sender (required)" \ |
| - | "\n -o options Various options. -oi implied, others are ignored" \ |
| - | "\n -i -oi synonym. implied and ignored" \ |
| - | "\n" \ |
| - | "\nBusybox specific options:" \ |
| - | "\n -w seconds Network timeout" \ |
| - | "\n -H 'PROG ARGS' Run connection helper" \ |
| - | "\n Examples:" \ |
| - | "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" \ |
| - | "\n -connect smtp.gmail.com:25' <email.txt" \ |
| - | "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" \ |
| - | "\n -H 'exec openssl s_client -quiet -tls1" \ |
| - | "\n -connect smtp.gmail.com:465' <email.txt" \ |
| - | "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" \ |
| - | "\n -S server[:port] Server" \ |
| - | "\n -au<username> Username for AUTH LOGIN" \ |
| - | "\n -ap<password> Password for AUTH LOGIN" \ |
| - | "\n -am<method> Authentication method. Ignored. LOGIN is implied" \ |
| - | "\n" \ |
| - | "\nOther options are silently ignored; -oi -t is implied" \ |
| - | IF_MAKEMIME( \ |
| - | "\nUse makemime applet to create message with attachments" \ |
| - | ) |
| - | |
| #define seq_trivial_usage \ | |
| "[-w] [-s SEP] [FIRST [INC]] LAST" | |
| #define seq_full_usage "\n\n" \ | |
| @@ -75,13 +75,16 @@ void FAST_FUNC launch_helper(const char **argv) | |
| atexit(kill_helper); | |
| } | |
| - | const FAST_FUNC char *command(const char *fmt, const char *param) |
| + | char* FAST_FUNC send_mail_command(const char *fmt, const char *param) |
| { | |
| - | const char *msg = fmt; |
| + | char *msg; |
| if (timeout) | |
| alarm(timeout); | |
| - | if (msg) { |
| + | msg = (char*)fmt; |
| + | if (fmt) { |
| msg = xasprintf(fmt, param); | |
| + | if (verbose) |
| + | bb_error_msg("send:'%s'", msg); |
| printf("%s\r\n", msg); | |
| } | |
| fflush_all(); | |
| @@ -90,7 +93,7 @@ const FAST_FUNC char *command(const char *fmt, const char *param) | |
| // NB: parse_url can modify url[] (despite const), but only if '@' is there | |
| /* | |
| - | static char FAST_FUNC *parse_url(char *url, char **user, char **pass) |
| + | static char* FAST_FUNC parse_url(char *url, char **user, char **pass) |
| { | |
| // parse [user[:pass]@]host | |
| // return host | |
| @@ -1,7 +1,16 @@ | |
| + | /* vi: set sw=4 ts=4: */ |
| + | /* |
| + | * helper routines |
| + | * |
| + | * Copyright (C) 2008 by Vladimir Dronnikov <[email protected]> |
| + | * |
| + | * Licensed under GPLv2, see file LICENSE in this source tree. |
| + | */ |
| struct globals { | |
| pid_t helper_pid; | |
| unsigned timeout; | |
| + | unsigned verbose; |
| unsigned opts; | |
| char *user; | |
| char *pass; | |
| @@ -12,6 +21,7 @@ struct globals { | |
| #define G (*ptr_to_globals) | |
| #define timeout (G.timeout ) | |
| + | #define verbose (G.verbose ) |
| #define opts (G.opts ) | |
| //#define user (G.user ) | |
| //#define pass (G.pass ) | |
| @@ -26,9 +36,9 @@ struct globals { | |
| //char FAST_FUNC *parse_url(char *url, char **user, char **pass); | |
| - | void FAST_FUNC launch_helper(const char **argv); |
| - | void FAST_FUNC get_cred_or_die(int fd); |
| + | void launch_helper(const char **argv) FAST_FUNC; |
| + | void get_cred_or_die(int fd) FAST_FUNC; |
| - | const FAST_FUNC char *command(const char *fmt, const char *param); |
| + | char *send_mail_command(const char *fmt, const char *param) FAST_FUNC; |
| - | void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol); |
| + | void encode_base64(char *fname, const char *text, const char *eol) FAST_FUNC; |
| @@ -99,6 +99,28 @@ Content-Transfer-Encoding: 7bit | |
| ...random junk added by mailing list robots and such... | |
| */ | |
| + | /* man makemime: |
| + | |
| + | * -c TYPE: create a (non-multipart) MIME section with Content-Type: TYPE |
| + | * makemime -c TYPE [-e ENCODING] [-o OUTFILE] [-C CHARSET] [-N NAME] [-a HEADER...] FILE |
| + | * The -C option sets the MIME charset attribute for text/plain content. |
| + | * The -N option sets the name attribute for Content-Type: |
| + | * Encoding must be one of the following: 7bit, 8bit, quoted-printable, or base64. |
| + | |
| + | * -m multipart/TYPE: create a multipart MIME collection with Content-Type: multipart/TYPE |
| + | * makemime -m multipart/TYPE [-e ENCODING] [-o OUTFILE] [-a HEADER...] FILE |
| + | * Type must be either "multipart/mixed", "multipart/alternative", or some other MIME multipart content type. |
| + | * Additionally, encoding can only be "7bit" or "8bit", and will default to "8bit" if not specified. |
| + | * Finally, filename must be a MIME-formatted section, NOT a regular file. |
| + | * The -m option creates an initial multipart MIME collection, that contains only one MIME section, taken from filename. |
| + | * The collection is written to standard output, or the pipe or to outputfile. |
| + | |
| + | * -j FILE1: add a section to a multipart MIME collection |
| + | * makemime -j FILE1 [-o OUTFILE] FILE2 |
| + | * FILE1 must be a MIME collection that was previously created by the -m option. |
| + | * FILE2 must be a MIME section that was previously created by the -c option. |
| + | * The -j options adds the MIME section in FILE2 to the MIME collection in FILE1. |
| + | */ |
| int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int makemime_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| @@ -107,14 +129,14 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) | |
| #define boundary opt_output | |
| enum { | |
| - | OPT_c = 1 << 0, // Content-Type: |
| + | OPT_c = 1 << 0, // create (non-multipart) section |
| OPT_e = 1 << 1, // Content-Transfer-Encoding. Ignored. Assumed base64 | |
| OPT_o = 1 << 2, // output to | |
| OPT_C = 1 << 3, // charset | |
| OPT_N = 1 << 4, // COMPAT | |
| OPT_a = 1 << 5, // additional headers | |
| - | OPT_m = 1 << 6, // COMPAT |
| - | OPT_j = 1 << 7, // COMPAT |
| + | //OPT_m = 1 << 6, // create mutipart section |
| + | //OPT_j = 1 << 7, // join section to multipart section |
| }; | |
| INIT_G(); | |
| @@ -122,8 +144,8 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) | |
| // parse options | |
| opt_complementary = "a::"; | |
| opts = getopt32(argv, | |
| - | "c:e:o:C:N:a:m:j:", |
| - | &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers, NULL, NULL |
| + | "c:e:o:C:N:a", //:m:j:", |
| + | &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL |
| ); | |
| //argc -= optind; | |
| argv += optind; | |
| @@ -14,9 +14,10 @@ | |
| static void pop3_checkr(const char *fmt, const char *param, char **ret) | |
| { | |
| - | const char *msg = command(fmt, param); |
| + | char *msg = send_mail_command(fmt, param); |
| char *answer = xmalloc_fgetline(stdin); | |
| if (answer && '+' == answer[0]) { | |
| + | free(msg); |
| if (timeout) | |
| alarm(0); | |
| if (ret) { | |
| @@ -27,7 +28,7 @@ static void pop3_checkr(const char *fmt, const char *param, char **ret) | |
| free(answer); | |
| return; | |
| } | |
| - | bb_error_msg_and_die("%s failed: %s", msg, answer); |
| + | bb_error_msg_and_die("%s failed, reply was: %s", msg, answer); |
| } | |
| static void pop3_check(const char *fmt, const char *param) | |
| @@ -6,6 +6,38 @@ | |
| * | |
| * Licensed under GPLv2, see file LICENSE in this source tree. | |
| */ | |
| + | |
| + | //usage:#define sendmail_trivial_usage |
| + | //usage: "[OPTIONS] [RECIPIENT_EMAIL]..." |
| + | //usage:#define sendmail_full_usage "\n\n" |
| + | //usage: "Read email from stdin and send it\n" |
| + | //usage: "\nStandard options:" |
| + | //usage: "\n -t Read additional recipients from message body" |
| + | //usage: "\n -f SENDER Sender (required)" |
| + | //usage: "\n -o OPTIONS Various options. -oi implied, others are ignored" |
| + | //usage: "\n -i -oi synonym. implied and ignored" |
| + | //usage: "\n" |
| + | //usage: "\nBusybox specific options:" |
| + | //usage: "\n -v Verbose" |
| + | //usage: "\n -w SECS Network timeout" |
| + | //usage: "\n -H 'PROG ARGS' Run connection helper" |
| + | //usage: "\n Examples:" |
| + | //usage: "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" |
| + | //usage: "\n -connect smtp.gmail.com:25' <email.txt" |
| + | //usage: "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" |
| + | //usage: "\n -H 'exec openssl s_client -quiet -tls1" |
| + | //usage: "\n -connect smtp.gmail.com:465' <email.txt" |
| + | //usage: "\n [4<username_and_passwd.txt | -au<username> -ap<password>]" |
| + | //usage: "\n -S HOST[:PORT] Server" |
| + | //usage: "\n -au<username> Username for AUTH LOGIN" |
| + | //usage: "\n -ap<password> Password for AUTH LOGIN" |
| + | //usage: "\n -am<method> Authentication method. Ignored. LOGIN is implied" |
| + | //usage: "\n" |
| + | //usage: "\nOther options are silently ignored; -oi -t is implied" |
| + | //usage: IF_MAKEMIME( |
| + | //usage: "\nUse makemime applet to create message with attachments" |
| + | //usage: ) |
| + | |
| #include "libbb.h" | |
| #include "mail.h" | |
| @@ -13,23 +45,35 @@ | |
| // set to 0 to not limit | |
| #define MAX_HEADERS 256 | |
| + | static void send_r_n(const char *s) |
| + | { |
| + | if (verbose) |
| + | bb_error_msg("send:'%s'", s); |
| + | printf("%s\r\n", s); |
| + | } |
| + | |
| static int smtp_checkp(const char *fmt, const char *param, int code) | |
| { | |
| char *answer; | |
| - | const char *msg = command(fmt, param); |
| + | char *msg = send_mail_command(fmt, param); |
| // read stdin | |
| - | // if the string has a form \d\d\d- -- read next string. E.g. EHLO response |
| + | // if the string has a form NNN- -- read next string. E.g. EHLO response |
| // parse first bytes to a number | |
| // if code = -1 then just return this number | |
| // if code != -1 then checks whether the number equals the code | |
| // if not equal -> die saying msg | |
| - | while ((answer = xmalloc_fgetline(stdin)) != NULL) |
| + | while ((answer = xmalloc_fgetline(stdin)) != NULL) { |
| + | // if (verbose) |
| + | bb_error_msg("recv:'%.*s' %d", (int)(strchrnul(answer, '\r') - answer), answer, verbose); |
| if (strlen(answer) <= 3 || '-' != answer[3]) | |
| break; | |
| + | free(answer); |
| + | } |
| if (answer) { | |
| int n = atoi(answer); | |
| if (timeout) | |
| alarm(0); | |
| + | free(msg); |
| free(answer); | |
| if (-1 == code || n == code) | |
| return n; | |
| @@ -86,6 +130,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_H = 1 << 5, // use external connection helper | |
| OPT_S = 1 << 6, // specify connection string | |
| OPT_a = 1 << 7, // authentication tokens | |
| + | OPT_v = 1 << 8, // verbosity |
| }; | |
| // init global variables | |
| @@ -96,12 +141,13 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| G.fp0 = xfdopen_for_read(3); | |
| // parse options | |
| - | // -f is required. -H and -S are mutually exclusive |
| - | opt_complementary = "f:w+:H--S:S--H:a::"; |
| + | // -v is a counter, -f is required. -H and -S are mutually exclusive, -a is a list |
| + | opt_complementary = "vv:f:w+:H--S:S--H:a::"; |
| // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect | |
| // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, | |
| // it is still under development. | |
| - | opts = getopt32(argv, "tf:o:iw:H:S:a::", &opt_from, NULL, &timeout, &opt_connect, &opt_connect, &list); |
| + | opts = getopt32(argv, "tf:o:iw:H:S:a::v", &opt_from, NULL, |
| + | &timeout, &opt_connect, &opt_connect, &list, &verbose); |
| //argc -= optind; | |
| argv += optind; | |
| @@ -214,7 +260,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| if ('.' == s[0] /*&& '\0' == s[1] */) | |
| printf("."); | |
| // dump read line | |
| - | printf("%s\r\n", s); |
| + | send_r_n(s); |
| free(s); | |
| continue; | |
| } | |
| @@ -261,14 +307,14 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| goto bail; | |
| // dump the headers | |
| while (list) { | |
| - | printf("%s\r\n", (char *) llist_pop(&list)); |
| + | send_r_n((char *) llist_pop(&list)); |
| } | |
| // stop analyzing headers | |
| code++; | |
| // N.B. !s means: we read nothing, and nothing to be read in the future. | |
| // just dump empty line and break the loop | |
| if (!s) { | |
| - | puts("\r"); |
| + | send_r_n(""); |
| break; | |
| } | |
| // go dump message body | |