+ sigchld = signal(SIGCHLD, SIG_DFL);
+ }
+ else
+ {
+ char *ap, *ctt, options[MSGBUFSIZE];
+ int smtperr;
+
+ /* build a connection to the SMTP listener */
+ if (!ctl->mda && ((sinkfp = smtp_open(ctl)) == NULL))
+ {
+ free_str_list(&xmit_names);
+ error(0, 0, "SMTP connect to %s failed", ctl->smtphost);
+ if (return_path)
+ free(return_path);
+ return(PS_SMTP);
+ }
+
+ /*
+ * Compute ESMTP options. It's a kluge to use nxtaddr()
+ * here because the contents of the Content-Transfer-Encoding
+ * headers isn't semantically an address. But it has the
+ * desired tokenizing effect.
+ */
+ options[0] = '\0';
+ if ((ctl->server.esmtp_options & ESMTP_8BITMIME)
+ && (ctt_offs >= 0)
+ && (ctt = nxtaddr(headers + ctt_offs)))
+ if (!strcasecmp(ctt,"7BIT"))
+ sprintf(options, " BODY=7BIT", ctt);
+ else if (!strcasecmp(ctt,"8BIT"))
+ sprintf(options, " BODY=8BITMIME", ctt);
+ if ((ctl->server.esmtp_options & ESMTP_SIZE) && !delimited)
+ sprintf(options + strlen(options), " SIZE=%d", len);
+
+ /*
+ * If there is a Return-Path address on the message, this was
+ * almost certainly the MAIL FROM address given the originating
+ * sendmail. This is the best thing to use for logging the
+ * message origin (it sets up the right behavior for bounces and
+ * mailing lists). Otherwise, take the From address.
+ *
+ * Try to get the SMTP listener to take the Return-Path or
+ * From address as MAIL FROM . If it won't, fall back on the
+ * calling-user ID. This won't affect replies, which use the
+ * header From address anyway.
+ *
+ * RFC 1123 requires that the domain name part of the
+ * MAIL FROM address be "canonicalized", that is a
+ * FQDN or MX but not a CNAME. We'll assume the From
+ * header is already in this form here (it certainly
+ * is if rewrite is on). RFC 1123 is silent on whether
+ * a nonexistent hostname part is considered canonical.
+ *
+ * This is a potential problem if the MTAs further upstream
+ * didn't pass canonicalized From/Return-Path lines, *and* the
+ * local SMTP listener insists on them.
+ */
+ ap = (char *)NULL;
+ if (return_path)
+ ap = return_path;
+ else if (from_offs == -1 || !(ap = nxtaddr(headers + from_offs)))
+ ap = user;
+ if (SMTP_from(sinkfp, ap, options) != SM_OK)
+ {
+ int smtperr = atoi(smtp_response);
+
+ if (smtperr >= 400)
+ error(0, 0, "SMTP error: %s", smtp_response);
+
+ /*
+ * There's one problem with this flow of control;
+ * there's no way to avoid reading the whole message
+ * off the server, even if the MAIL FROM response
+ * tells us that it's just to be discarded. We could
+ * fix this under IMAP by reading headers first, then
+ * trying to issue the MAIL FROM, and *then* reading
+ * the body...but POP3 can't do this.
+ */
+
+ switch (smtperr)