Gilles Chehade <gil...@poolp.org> writes: >> > Turns out it's a bit more than compat getopt(), we do accept and ignore >> > those flags however. >> > >> > With 'sendmail -bs' MUA expects STMP dialog over stdin/stdout, which >> > means, MUA will wait for the greeting on stdout while smtpctl waits for >> > text on stdin and they are now deadlocked. >> > >> > The following diff bridges the enqueuer fd and stdout/stdin by writing >> > output from fd to stdout and commands from stdin to fd. >> > >> > I can send mails with apline now without any config modifications and >> > also enqueue via plain 'sendmail -bs'. >> > >> > Tests and comments welcome. >> >> Revised diff. Ignore rest of '-b' options instead of returning an error. >> > > I really dislike this but I understand there's not much you can > do to achieve it differently :-/ > > one comment inline
Revised diff to move exit() out of the function. > > did you get a feedback from the original poster ? Not yet. diff --git a/smtpd/enqueue.c b/smtpd/enqueue.c index 3fd7fbd6..c7c008d0 100644 --- a/smtpd/enqueue.c +++ b/smtpd/enqueue.c @@ -31,6 +31,7 @@ #include <grp.h> #include <imsg.h> #include <inttypes.h> +#include <poll.h> #include <pwd.h> #include <stdarg.h> #include <stdio.h> @@ -46,6 +47,7 @@ extern struct imsgbuf *ibuf; void usage(void); static void build_from(char *, struct passwd *); +static void handle_bs(void); static int parse_message(FILE *, int, int, FILE *); static void parse_addr(char *, size_t, int); static void parse_addr_terminal(int); @@ -171,6 +173,7 @@ enqueue(int argc, char *argv[], FILE *ofp) FILE *fp = NULL, *fout; size_t sz = 0, envid_sz = 0; ssize_t len; + int bs_flag = 0; int fd; char sfn[] = "/tmp/smtpd.XXXXXXXXXX"; char *line; @@ -216,10 +219,13 @@ enqueue(int argc, char *argv[], FILE *ofp) case 'V': msg.dsn_envid = optarg; break; + case 'b': + if (strcmp(optarg, "s") == 0) + bs_flag = 1; + break; /* all remaining: ignored, sendmail compat */ case 'A': case 'B': - case 'b': case 'E': case 'e': case 'i': @@ -240,6 +246,11 @@ enqueue(int argc, char *argv[], FILE *ofp) argc -= optind; argv += optind; + if (bs_flag) { + handle_bs(); + exit(EX_OK); + } + if (getmailname(host, sizeof(host)) == -1) errx(EX_NOHOST, "getmailname"); if (no_getlogin) { @@ -458,6 +469,54 @@ fail: exit(EX_SOFTWARE); } +/* + * sendmail -bs requires STMP dialog over stdin/stdout. + * Bridge stdin/stdout with enqueuer fd. + */ +static void +handle_bs(void) +{ + char buf[LINE_MAX]; + struct pollfd pfd[2]; + nfds_t nfds; + size_t i; + ssize_t nr; + int fd, nready, outfd; + + if (!srv_connected()) + errx(EX_UNAVAILABLE, "Server offline"); + + if ((fd = open_connection()) == -1) + errx(EX_UNAVAILABLE, "server too busy"); + + pfd[0].fd = STDIN_FILENO; + pfd[1].fd = fd; + pfd[0].events = pfd[1].events = POLLIN; + nfds = 2; + while ((nready = poll(pfd, nfds, INFTIM))) { + if (nready == -1) + err(1, "poll"); + + for (i = 0; i < nfds; i++) { + if (pfd[i].revents & (POLLERR|POLLNVAL)) + errx(1, "bsd fd %d", pfd[i].fd); + + if ((pfd[i].revents & (POLLIN|POLLHUP))) { + nr = read(pfd[i].fd, buf, sizeof buf); + if (nr == -1) + err(1, "read"); + else if (nr == 0) + return; + + outfd = pfd[i].fd == STDIN_FILENO ? + fd : STDOUT_FILENO; + if (write(outfd, buf, nr) == -1) + err(1, "write"); + } + } + } +} + static int get_responses(FILE *fin, int n) { -- You received this mail because you are subscribed to misc@opensmtpd.org To unsubscribe, send a mail to: misc+unsubscr...@opensmtpd.org