Hi Jared,

Sorry for the delaying. I have tested the diff and stressed it; it
works fine for me so I'll commit it in a minute.

Gilles

On Tue, Mar 22, 2011 at 05:28:21PM -0400, Jared Yanovich wrote:
> 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;
> 

-- 
Gilles Chehade

                   http://www.poolp.org

Reply via email to