Thanks Jared,
I will read it more carefully and test it on various setups in a few
hours when I reach home. We'll see how it goes :-)
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