simplify some things.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
PROGRAMS = postlicyd
postlicyd_SOURCES = \
- str.h buffer.h job.h postfix.h \
- str.c buffer.c job.c postfix.c \
+ str.h buffer.h job.h postfix.h query.h \
+ str.c buffer.c job.c postfix.c \
postlicyd.c
postlicyd_LIBADD = -ludns
return job;
}
-void job_update_events(job_t *job)
+void job_update_state(job_t *job, int state)
{
struct epoll_event event = { .data.ptr = job, .events = EPOLLRDHUP };
+ if (job->state == state)
+ return;
+
+ job->state = state;
+
if (job->state & JOB_READ || job->state & JOB_LISTEN) {
event.events |= EPOLLIN;
}
#ifndef POSTLICYD_JOB_H
#define POSTLICYD_JOB_H
-#include "buffer.h"
+#include "mem.h"
enum job_state {
JOB_IDLE = 0x00,
typedef struct job_t job_t;
typedef struct jpriv_t jpriv_t;
-typedef struct query_t query_t;
struct job_t {
unsigned state : 6;
int fd;
- void (*stop)(job_t *);
void (*process)(job_t *);
+ void (*stop)(job_t *);
jpriv_t *jdata;
};
}
DO_NEW(job_t, job);
void job_release(job_t **job);
-void job_update_events(job_t *job);
-
-struct query_t {
- unsigned state : 4;
- unsigned esmtp : 1;
-
- const char *helo_name;
- const char *queue_id;
- const char *sender;
- const char *recipient;
- const char *recipient_count;
- const char *client_address;
- const char *client_name;
- const char *rclient_name;
- const char *instance;
-
- /* postfix 2.2+ */
- const char *sasl_method;
- const char *sasl_username;
- const char *sasl_sender;
- const char *size;
- const char *ccert_subject;
- const char *ccert_issuer;
- const char *ccsert_fingerprint;
-
- /* postfix 2.3+ */
- const char *encryption_protocol;
- const char *encryption_cipher;
- const char *encryption_keysize;
- const char *etrn_domain;
-
- buffer_t data;
-
- job_t *postfix;
- job_t *current;
-};
-
-static inline query_t *query_init(query_t *rq) {
- p_clear(rq, 1);
- buffer_init(&rq->data);
- return rq;
-}
-static inline void query_wipe(query_t *rq) {
- buffer_wipe(&rq->data);
-}
-DO_NEW(query_t, query);
-DO_DELETE(query_t, query);
-
-
+void job_update_state(job_t *job, int state);
job_t *job_accept(job_t *listener, int state);
#endif
#include "job.h"
#include "postfix.h"
+#include "buffer.h"
struct jpriv_t {
buffer_t ibuf;
buffer_t obuf;
};
-void postfix_start(job_t *job, query_t *query)
+jpriv_t *postfix_jpriv_init(jpriv_t *jp)
{
+ buffer_init(&jp->ibuf);
+ buffer_init(&jp->obuf);
+ return jp;
+}
+void postfix_jpriv_wipe(jpriv_t *jp)
+{
+ buffer_wipe(&jp->ibuf);
+ buffer_wipe(&jp->obuf);
+}
+DO_NEW(jpriv_t, postfix_jpriv);
+DO_DELETE(jpriv_t, postfix_jpriv);
+
+
+void postfix_start(job_t *listener)
+{
+ job_t *job;
+
+ job = job_accept(listener, JOB_READ);
+ if (!job)
+ return;
+
+ job->jdata = postfix_jpriv_new();
}
void postfix_stop(job_t *job)
{
+ postfix_jpriv_delete(&job->jdata);
}
void postfix_process(job_t *job)
{
- if (job->state & JOB_LISTEN) {
- /* TODO check return code */
- job_accept(job, JOB_READ);
- }
+ int nb;
- if (job->state & JOB_WRITE) {
- int nbwritten;
+ switch (job->state) {
+ case JOB_LISTEN:
+ return postfix_start(job);
- nbwritten = write(job->fd, job->jdata->obuf.data, job->jdata->obuf.len);
- if (nbwritten < 0) {
+ case JOB_WRITE:
+ nb = write(job->fd, job->jdata->obuf.data, job->jdata->obuf.len);
+ if (nb < 0) {
job->error = errno != EINTR && errno != EAGAIN;
return;
}
- buffer_consume(&job->jdata->obuf, nbwritten);
- }
+ buffer_consume(&job->jdata->obuf, nb);
+ if (job->jdata->obuf.len)
+ return;
- if (job->state & JOB_READ) {
- int nbread;
+ job_update_state(job, JOB_READ);
- nbread = buffer_read(&job->jdata->ibuf, job->fd, -1);
- if (nbread < 0) {
+ /* fall through */
+
+ case JOB_READ:
+ nb = buffer_read(&job->jdata->ibuf, job->fd, -1);
+ if (nb < 0) {
job->error = errno != EINTR && errno != EAGAIN;
return;
}
- if (nbread == 0) {
+ if (nb == 0) {
job->error = true;
return;
}
if (!strstr(job->jdata->ibuf.data, "\r\n\r\n"))
return;
- job->state &= ~JOB_READ;
-
/* TODO: do the parse */
+ job_update_state(job, JOB_IDLE);
+ return;
+
+ default:
+ job->error = true;
+ return;
}
}
--- /dev/null
+/******************************************************************************/
+/* postlicyd: a postfix policy daemon with a lot of features */
+/* ~~~~~~~~~ */
+/* ________________________________________________________________________ */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions */
+/* are met: */
+/* */
+/* 1. Redistributions of source code must retain the above copyright */
+/* notice, this list of conditions and the following disclaimer. */
+/* 2. Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* 3. The names of its contributors may not be used to endorse or promote */
+/* products derived from this software without specific prior written */
+/* permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND */
+/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */
+/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
+/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS */
+/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
+/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */
+/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */
+/* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */
+/* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF */
+/* THE POSSIBILITY OF SUCH DAMAGE. */
+/******************************************************************************/
+
+/*
+ * Copyright © 2007 Pierre Habouzit
+ */
+
+#ifndef POSTLICYD_QUERY_H
+#define POSTLICYD_QUERY_H
+
+#include "buffer.h"
+
+typedef struct query_t {
+ unsigned state : 4;
+ unsigned esmtp : 1;
+
+ const char *helo_name;
+ const char *queue_id;
+ const char *sender;
+ const char *recipient;
+ const char *recipient_count;
+ const char *client_address;
+ const char *client_name;
+ const char *rclient_name;
+ const char *instance;
+
+ /* postfix 2.2+ */
+ const char *sasl_method;
+ const char *sasl_username;
+ const char *sasl_sender;
+ const char *size;
+ const char *ccert_subject;
+ const char *ccert_issuer;
+ const char *ccsert_fingerprint;
+
+ /* postfix 2.3+ */
+ const char *encryption_protocol;
+ const char *encryption_cipher;
+ const char *encryption_keysize;
+ const char *etrn_domain;
+
+ buffer_t data;
+} query_t;
+
+static inline query_t *query_init(query_t *rq) {
+ p_clear(rq, 1);
+ buffer_init(&rq->data);
+ return rq;
+}
+static inline void query_wipe(query_t *rq) {
+ buffer_wipe(&rq->data);
+}
+DO_NEW(query_t, query);
+DO_DELETE(query_t, query);
+
+
+job_t *job_accept(job_t *listener, int state);
+
+#endif