X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=postfix.c;h=46d2708a73e05ac10f2eae9085c9c1c21083e45d;hb=14330fbdf398c3786803a001f0130b0d9ab70b46;hp=83d7c4d58e5684d60c0ba29ced109828e09ba83e;hpb=8f6739048c2593e196aceb654b4b96e1426e57d5;p=apps%2Fpfixtools.git diff --git a/postfix.c b/postfix.c index 83d7c4d..46d2708 100644 --- a/postfix.c +++ b/postfix.c @@ -34,62 +34,139 @@ */ #include +#include #include +#include #include #include "job.h" #include "postfix.h" +#include "buffer.h" +#include "tokens.h" struct jpriv_t { buffer_t ibuf; buffer_t obuf; }; -void postfix_start(job_t *job, query_t *query) +static jpriv_t *postfix_jpriv_init(jpriv_t *jp) { + buffer_init(&jp->ibuf); + buffer_init(&jp->obuf); + return jp; } +static 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_stop(job_t *job) +static void postfix_stop(job_t *job) { + postfix_jpriv_delete(&job->jdata); } -void postfix_process(job_t *job) +static int postfix_parsejob(job_t *job) { - if (job->state & JOB_LISTEN) { - /* TODO check return code */ - job_accept(job, JOB_READ); + const char *p = skipspaces(job->jdata->ibuf.data); + + for (;;) { + const char *k, *v; + int klen, vlen; + + while (*p == ' ' || *p == '\t') + p++; + p = strchrnul(k = p, '='); + if (!*p) + return -1; + for (klen = p - k; k[klen] == ' ' || k[klen] == '\t'; klen--); + p += 1; /* skip = */ + + while (*p == ' ' || *p == '\t') + p++; + p = strstr(v = p, "\r\n"); + if (!p) + return -1; + for (vlen = p - v; v[vlen] == ' ' || v[vlen] == '\t'; vlen--); + p += 2; /* skip \r\n */ + + /* do sth with (k,v) */ + + assert (p[0] && p[1]); + if (p[0] == '\r' && p[1] == '\n') + break; } - if (job->state & JOB_WRITE) { - int nbwritten; + return -1; +} - nbwritten = write(job->fd, job->jdata->obuf.data, job->jdata->obuf.len); - if (nbwritten < 0) { - job->error = errno != EINTR && errno != EAGAIN; +static void postfix_process(job_t *job) +{ + int nb; + + switch (job->mode) { + case JOB_LISTEN: + if ((job = job_accept(job, JOB_READ))) { + job->jdata = postfix_jpriv_new(); + job->process = &postfix_process; + job->stop = &postfix_stop; + } + return; + + case JOB_WRITE: + nb = write(job->fd, job->jdata->obuf.data, job->jdata->obuf.len); + if (nb < 0) { + if ((job->error = errno != EINTR && errno != EAGAIN)) { + syslog(LOG_ERR, "unexpected problem on the socket: %m"); + } 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_mode(job, JOB_READ); - nbread = buffer_read(&job->jdata->ibuf, job->fd, -1); - if (nbread < 0) { - job->error = errno != EINTR && errno != EAGAIN; + /* fall through */ + + case JOB_READ: + nb = buffer_read(&job->jdata->ibuf, job->fd, -1); + if (nb < 0) { + if ((job->error = errno != EINTR && errno != EAGAIN)) { + syslog(LOG_ERR, "unexpected problem on the socket: %m"); + } return; } - if (nbread == 0) { + if (nb == 0) { + syslog(LOG_ERR, "unexpected eof"); job->error = true; return; } - if (!strstr(job->jdata->ibuf.data, "\r\n\r\n")) + if (!strstr(skipspaces(job->jdata->ibuf.data), "\r\n\r\n")) { + if (job->jdata->ibuf.len > SHRT_MAX) { + syslog(LOG_ERR, "too much data without CRLFCRLF"); + job->error = true; + } + return; + } + + if (postfix_parsejob(job) < 0) { + syslog(LOG_ERR, "could not parse postfix request"); + job->error = true; return; + } + + job_update_mode(job, JOB_IDLE); - job->state &= ~JOB_READ; + /* TODO: run the scenario */ + return; - /* TODO: do the parse */ + default: + job->error = true; + return; } }