On Tue, Mar 22, 2011 at 10:23:27AM +0100, Gilles Chehade wrote:

> Jared, care to write a diff ? :-)

In our setup, we only use smtpd for relay, so this patch has not been tested in
code paths outside the main relay engine.

Index: bounce.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/bounce.c,v
retrieving revision 1.25
diff -N -u -p bounce.c
--- bounce.c    21 Mar 2011 13:06:25 -0000      1.25
+++ bounce.c    22 Mar 2011 13:36:46 -0000
@@ -43,6 +43,7 @@ struct client_ctx {
        struct message           m;
        struct smtp_client      *pcb;
        struct smtpd            *env;
+       FILE                    *msgfp;
 };
 
 int
@@ -51,19 +52,22 @@ bounce_session(struct smtpd *env, int fd, struct messa
        struct client_ctx       *cc = NULL;
        int                      msgfd = -1;
        char                    *reason;
+       FILE                    *msgfp = NULL;
 
        /* get message content */
        if ((msgfd = queue_open_message_file(messagep->message_id)) == -1)
                goto fail;
+       msgfp = fdopen(msgfd, "r");
+       if (msgfp == NULL)
+               fatal("fdopen");
        
        /* init smtp session */
-       if ((cc = calloc(1, sizeof(*cc))) == NULL) {
-               close(msgfd);
+       if ((cc = calloc(1, sizeof(*cc))) == NULL) 
                goto fail;
-       }
-       cc->pcb = client_init(fd, msgfd, env->sc_hostname, 1);
+       cc->pcb = client_init(fd, msgfp, env->sc_hostname, 1);
        cc->env = env;
        cc->m = *messagep;
+       cc->msgfp = msgfp;
 
        client_ssl_optional(cc->pcb);
        client_sender(cc->pcb, "");
@@ -107,8 +111,10 @@ bounce_session(struct smtpd *env, int fd, struct messa
 
        return 1;
 fail:
-       if (cc && cc->pcb)
-               client_close(cc->pcb);
+       if (cc)
+               fclose(cc->msgfp);
+       else if (msgfd != -1)
+               close(msgfd);
        free(cc);
        return 0;
 }
@@ -154,6 +160,7 @@ out:
        cc->env->stats->runner.active--;
        cc->env->stats->runner.bounces_active--;
        client_close(cc->pcb);
+       fclose(cc->msgfp);
        free(cc);
        return;
 
Index: client.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/client.c,v
retrieving revision 1.34
diff -N -u -p client.c
--- client.c    21 Mar 2011 09:21:57 -0000      1.34
+++ client.c    22 Mar 2011 13:36:47 -0000
@@ -50,7 +50,7 @@ int            ssl_buf_write(SSL *, struct msgbuf *);
  * Initialize SMTP session.
  */
 struct smtp_client *
-client_init(int fd, int body, char *ehlo, int verbose)
+client_init(int fd, FILE *body, char *ehlo, int verbose)
 {
        struct smtp_client      *sp = NULL;
        struct client_cmd       *c;
@@ -76,8 +76,7 @@ client_init(int fd, int body, char *ehlo, int verbose)
                sp->verbose = stdout;
        else if ((sp->verbose = fopen("/dev/null", "a")) == NULL)
                fatal("client_init: fopen");
-       if ((sp->body = fdopen(body, "r")) == NULL)
-               fatal("client_init: fdopen");
+       sp->body = body;
        sp->timeout.tv_sec = 300;
        msgbuf_init(&sp->w);
        sp->w.fd = fd;
Index: client.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/client.h,v
retrieving revision 1.13
diff -N -u -p client.h
--- client.h    28 Nov 2010 13:56:43 -0000      1.13
+++ client.h    22 Mar 2011 13:36:47 -0000
@@ -103,7 +103,7 @@ struct smtp_client {
        char                     status[1024];
 };
 
-struct smtp_client     *client_init(int, int, char *, int);
+struct smtp_client     *client_init(int, FILE *, char *, int);
 void                    client_ssl_smtps(struct smtp_client *);
 void                    client_ssl_optional(struct smtp_client *);
 void                    client_certificate(struct smtp_client *, char *,
Index: enqueue.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/enqueue.c,v
retrieving revision 1.41
diff -N -u -p enqueue.c
--- enqueue.c   28 Nov 2010 14:35:58 -0000      1.41
+++ enqueue.c   22 Mar 2011 13:36:47 -0000
@@ -196,7 +196,7 @@ enqueue(int argc, char *argv[])
 
        /* init session */
        rewind(fp);
-       msg.pcb = client_init(msg.fd, fileno(fp), "localhost", verbose);
+       msg.pcb = client_init(msg.fd, fp, "localhost", verbose);
 
        /* set envelope from */
        client_sender(msg.pcb, "%s", msg.from);
@@ -237,6 +237,7 @@ enqueue(int argc, char *argv[])
                err(1, "event_dispatch");
 
        client_close(msg.pcb);
+       fclose(fp);
        exit(0);
 }
 
Index: mta.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mta.c,v
retrieving revision 1.98
diff -N -u -p mta.c
--- mta.c       21 Mar 2011 13:02:52 -0000      1.98
+++ mta.c       22 Mar 2011 13:36:47 -0000
@@ -76,7 +76,6 @@ mta_imsg(struct smtpd *env, struct imsgev *iev, struct
                        s->id = b->id;
                        s->state = MTA_INIT;
                        s->env = env;
-                       s->datafd = -1;
 
                        /* establish host name */
                        if (b->rule.r_action == A_RELAYVIA) {
@@ -444,7 +443,7 @@ mta_enter_state(struct mta_session *s, int newstate, v
                 */
                log_debug("mta: entering smtp phase");
 
-               pcb = client_init(s->fd, s->datafd, s->env->sc_hostname, 1);
+               pcb = client_init(s->fd, s->datafp, s->env->sc_hostname, 1);
 
                /* lookup SSL certificate */
                if (s->cert) {
@@ -513,6 +512,7 @@ mta_enter_state(struct mta_session *s, int newstate, v
                        TAILQ_REMOVE(&s->relays, relay, entry);
                        free(relay);
                }
+               fclose(s->datafp);
                free(s->secret);
                free(s->host);
                free(s->cert);
@@ -567,11 +567,12 @@ mta_pickup(struct mta_session *s, void *p)
 
        case MTA_DATA:
                /* QUEUE replied to body fd request. */
-               s->datafd = *(int *)p;
-               if (s->datafd == -1)
+               if (*(int *)p == -1)
                        fatalx("mta cannot obtain msgfd");
-               else
-                       mta_enter_state(s, MTA_CONNECT, NULL);
+               s->datafp = fdopen(*(int *)p, "r");
+               if (s->datafp == NULL)
+                       fatal("fdopen");
+               mta_enter_state(s, MTA_CONNECT, NULL);
                break;
 
        case MTA_CONNECT:
Index: smtpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v
retrieving revision 1.202
diff -N -u -p smtpd.h
--- smtpd.h     15 Mar 2011 19:24:55 -0000      1.202
+++ smtpd.h     22 Mar 2011 13:36:47 -0000
@@ -853,7 +853,7 @@ struct mta_session {
        objid_t                  secmapid;
        char                    *secret;
        int                      fd;
-       int                      datafd;
+       FILE                    *datafp;
        struct event             ev;
        char                    *cert;
        void                    *pcb;

Reply via email to