sendmail: update from maintainer

diff --git a/networking/sendmail.c b/networking/sendmail.c
index 027656d..071d9d6 100644
--- a/networking/sendmail.c
+++ b/networking/sendmail.c
@@ -61,6 +61,8 @@
 	}
 	if (fname)
 		close(fd);
+#undef src_buf
+#undef len
 }
 
 struct globals {
@@ -82,7 +84,7 @@
 	xargs[1] = "s_client"; \
 	xargs[2] = "-quiet"; \
 	xargs[3] = "-connect"; \
-	/*xargs[4] = "server[:port]";*/ \
+	/*xargs[4] = "localhost";*/ \
 	xargs[5] = "-tls1"; \
 	xargs[6] = "-starttls"; \
 	xargs[7] = "smtp"; \
@@ -115,6 +117,16 @@
 	if (wait_any_nohang(&err) > 0)
 		if (WIFEXITED(err) && WEXITSTATUS(err))
 			bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err));
+#undef err
+}
+
+/* libbb candidate */
+static pid_t vfork_or_die(void)
+{
+	pid_t pid = vfork();
+	if (pid < 0)
+		bb_perror_msg_and_die("vfork");
+	return pid;
 }
 
 static void launch_helper(const char **argv)
@@ -122,12 +134,11 @@
 	// setup vanilla unidirectional pipes interchange
 	int idx;
 	int pipes[4];
+
 	xpipe(pipes);
 	xpipe(pipes+2);
-	helper_pid = vfork();
-	if (helper_pid < 0)
-		bb_perror_msg_and_die("vfork");
-	idx = (!helper_pid)*2;
+	helper_pid = vfork_or_die();
+	idx = (!helper_pid) * 2;
 	xdup2(pipes[idx], STDIN_FILENO);
 	xdup2(pipes[3-idx], STDOUT_FILENO);
 	if (ENABLE_FEATURE_CLEAN_UP)
@@ -255,29 +266,31 @@
 int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
 {
 	llist_t *opt_recipients = NULL;
-
+	llist_t *opt_attachments = NULL;
+	char *opt_from;
 	const char *opt_user;
 	const char *opt_pass;
-
 	enum {
 		OPT_w = 1 << 0,         // network timeout
-		OPT_U = 1 << 1,         // user
-		OPT_P = 1 << 2,         // password
-		OPT_X = 1 << 3,         // connect using openssl s_client helper
+		OPT_H = 1 << 1,         // server[:port]
+		OPT_U = 1 << 2,         // user
+		OPT_P = 1 << 3,         // password
+		OPT_X = 1 << 4,         // connect using openssl s_client helper
 
-		OPTS_n = 1 << 4,        // sendmail: request notification
-		OPTF_t = 1 << 4,        // fetchmail: use "TOP" not "RETR"
+		OPTS_t = 1 << 5,        // sendmail: read addresses from body
+		OPTF_t = 1 << 5,        // fetchmail: use "TOP" not "RETR"
 
-		OPTS_s = 1 << 5,        // sendmail: subject
-		OPTF_z = 1 << 5,        // fetchmail: delete from server
+		OPTS_s = 1 << 6,        // sendmail: subject
+		OPTF_z = 1 << 6,        // fetchmail: delete from server
 
-		OPTS_c = 1 << 6,        // sendmail: assumed charset
-		OPTS_t = 1 << 7,        // sendmail: recipient(s)
-		OPTS_i = 1 << 8,        // sendmail: ignore lone dots in message body (implied)
+		OPTS_c = 1 << 7,        // sendmail: assumed charset
+		OPTS_a = 1 << 8,        // sendmail: attachment(s)
+		OPTS_i = 1 << 9,        // sendmail: ignore lone dots in message body (implied)
+
+		OPTS_n = 1 << 10,       // sendmail: request notification
 	};
-
 	const char *options;
-	unsigned opts;
+	int opts;
 
 	// init global variables
 	INIT_G();
@@ -289,25 +302,30 @@
 		// SENDMAIL
 		// save initial stdin (body or attachements can be piped!)
 		xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO);
-		opt_complementary = "-2:w+:t::";
-		options = "w:U:P:X" "ns:c:t:i";
+		opt_complementary = "w+:a::";
+		options = "w:H:U:P:Xt" "s:c:a:inf:";
+		// body is pseudo attachment read from stdin
+		llist_add_to_end(&opt_attachments, (char *)"-");
 	} else {
 		// FETCHMAIL
 		opt_after_connect = NULL;
-		opt_complementary = "-2:w+:P";
-		options = "w:U:P:X" "tz";
+		opt_complementary = "-1:w+:P";
+		options = "w:H:U:P:Xt" "z";
 	}
 	opts = getopt32(argv, options,
-		&timeout, &opt_user, &opt_pass,
-		&opt_subject, &opt_charset, &opt_recipients
+		&timeout, &opt_connect, &opt_user, &opt_pass,
+		&opt_subject, &opt_charset, &opt_attachments, &opt_from
 	);
 	//argc -= optind;
 	argv += optind;
 
-	// first argument is remote server[:port]
-	opt_connect = *argv++;
-
 	// connect to server
+	// host[:port] not specified ? -> use $HOST. no $HOST ? -> use localhost
+	if (!(opts & OPT_H)) {
+		opt_connect = getenv("HOST");
+		if (!opt_connect)
+			opt_connect = "127.0.0.1";
+	}
 	// SSL ordered? ->
 	if (opts & OPT_X) {
 		// ... use openssl helper
@@ -323,20 +341,27 @@
 	}
 
 #if ENABLE_FETCHMAIL
-	// we are sendmail?
+	// are we sendmail?
 	if (opt_after_connect)
 #endif
-	{
 /***************************************************
  * SENDMAIL
  ***************************************************/
-
-		char *opt_from;
+	{
 		int code;
 		char *boundary;
 		const char *fmt;
 		const char *p;
 		char *q;
+		llist_t *l;
+
+		// recipients specified as arguments
+		while (*argv) {
+			// loose test on email address validity
+			if (strchr(sane(*argv), '@'))
+				llist_add_to_end(&opt_recipients, *argv);
+			argv++;
+		}
 
 		// we didn't use SSL helper? ->
 		if (!(opts & OPT_X)) {
@@ -344,13 +369,13 @@
 			smtp_check(NULL, 220);
 		}
 
-		// get the sender
-		opt_from = sane(*argv++);
-
-		// if no recipients _and_ no body files specified -> enter all-included mode
+		// if -t specified or no recipients specified -> enter all-included mode
 		// i.e. scan stdin for To: and Subject: lines ...
 		// ... and then use the rest of stdin as message body
-		if (!opt_recipients && !*argv) {
+		// N.B. subject read from body has priority
+		// over that specified on command line.
+		// recipients are merged
+		if (opts & OPTS_t || !opt_recipients) {
 			// fetch recipients and (optionally) subject
 			char *s;
 			while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) {
@@ -366,13 +391,11 @@
 						break; // empty line
 				}
 			}
-			// order to read body from stdin
-			*--argv = (char *)"-";
 		}
 
 		// introduce to server
 		// we should start with modern EHLO
-		if (250 != smtp_checkp("EHLO %s", opt_from, -1)) {
+		if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) {
 			smtp_checkp("HELO %s", opt_from, 250);
 		}
 
@@ -404,8 +427,8 @@
 		}
 
 		// set recipients
-		for (llist_t *to = opt_recipients; to; to = to->link) {
-			smtp_checkp("RCPT TO:<%s>", sane(to->data), 250);
+		for (l = opt_recipients; l; l = l->link) {
+			smtp_checkp("RCPT TO:<%s>", sane(l->data), 250);
 		}
 
 		// enter "put message" mode
@@ -413,8 +436,8 @@
 
 		// put address headers
 		printf("From: %s\r\n", opt_from);
-		for (llist_t *to = opt_recipients; to; to = to->link) {
-			printf("To: %s\r\n", to->data);
+		for (l = opt_recipients; l; l = l->link) {
+			printf("To: %s\r\n", l->data);
 		}
 
 		// put encoded subject
@@ -455,7 +478,8 @@
 		;
 		p = opt_charset;
 		q = (char *)"";
-		while (*argv) {
+		l = opt_attachments;
+		while (l) {
 			printf(
 				fmt
 				, boundary
@@ -472,9 +496,10 @@
 				"%s; filename=\"%s\"\r\n"
 				"%s"
 			;
-			uuencode(*argv, NULL);
-			if (*(++argv))
-				q = bb_get_last_path_component_strip(*argv);
+			uuencode(l->data, NULL);
+			l = l->link;
+			if (l)
+				q = bb_get_last_path_component_strip(l->data);
 		}
 
 		// put message terminator
@@ -484,12 +509,12 @@
 		smtp_check(".", 250);
 		// ... and say goodbye
 		smtp_check("QUIT", 221);
-
+	}
 #if ENABLE_FETCHMAIL
-	} else {
 /***************************************************
  * FETCHMAIL
  ***************************************************/
+	else {
 
 		char *buf;
 		unsigned nmsg;
@@ -570,7 +595,8 @@
 		for (; nmsg; nmsg--) {
 
 			// generate unique filename
-			char *filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), pid, hostname);
+			char *filename = xasprintf("tmp/%llu.%u.%s",
+					monotonic_us(), (unsigned)pid, hostname);
 			char *target;
 			int rc;
 
@@ -604,8 +630,8 @@
 
 		// Bye
 		pop3_check("QUIT", NULL);
-#endif // ENABLE_FETCHMAIL
 	}
+#endif // ENABLE_FETCHMAIL
 
 	return 0;
 }