Sunil Nimmagadda <[email protected]> writes:

> Gilles Chehade <[email protected]> writes:
>
>> On Fri, Jan 06, 2017 at 08:20:05AM +0100, Antoine Jacoutot wrote:
>>> On Fri, Jan 06, 2017 at 02:35:46PM +1100, Damian McGuckin wrote:
>>> >
>>> > Does the FAQ need a section of tweaks for email clients?
>>> >
>>> > I tried to use 'alpine' on OpenBSD 6.0 with the standard SMTPD therein.
>>> >
>>> > A pkg_add'ed 'alpine' just sits there trying and trying until you go into
>>> >
>>> >   Main-Menu -> Setup -> Config
>>> >
>>> > and change the SMTP server to 'localhost'. I have never had to do that
>>> > in my life with 'alpine' on any other system that has used sendmail or
>>> > postfix.
>>> >
>>> > How many other email clients need tweaking for OpenSMTPD?
>>>
>>> It's probably due to the default sendmail flags used by alpine :
>>> smtp_msa_flags="-bs -odb -oem"
>>>
>>
>> ok, it is indeed due to these flags, OP should open a bug report on our
>> tracker and one of us will add compat to the enqueuer so it doesn't
>> choke on these.
>>
>>
>>> I'll have a look at the port today, there's a configure option to change the
>>> defaults.
>>>
>>
>> that would make it work out of the box on openbsd but still, we should
>> have the compat getopt() imo
>
> 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.

diff --git a/smtpd/enqueue.c b/smtpd/enqueue.c
index 3fd7fbd6..036a97c7 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,9 @@ enqueue(int argc, char *argv[], FILE *ofp)
        argc -= optind;
        argv += optind;

+       if (bs_flag)
+               handle_bs();
+
        if (getmailname(host, sizeof(host)) == -1)
                errx(EX_NOHOST, "getmailname");
        if (no_getlogin) {
@@ -458,6 +467,57 @@ 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)
+                                       goto done;
+
+                               outfd = pfd[i].fd == STDIN_FILENO ?
+                                   fd : STDOUT_FILENO;
+                               if (write(outfd, buf, nr) == -1)
+                                       err(1, "write");
+                       }
+               }
+       }
+
+ done:
+       exit(EX_OK);
+}
+
 static int
 get_responses(FILE *fin, int n)
 {

-- 
You received this mail because you are subscribed to [email protected]
To unsubscribe, send a mail to: [email protected]

Reply via email to