From: Pierre Habouzit Date: Thu, 23 Aug 2007 21:57:39 +0000 (+0200) Subject: Rewind work, and start in another direction. X-Git-Url: http://git.madism.org/?p=apps%2Fpfixtools.git;a=commitdiff_plain;h=c0cfcd4c414bd423e4766ff6c90850ee25c9b449 Rewind work, and start in another direction. Prepare some administrivia. Signed-off-by: Pierre Habouzit --- diff --git a/Makefile b/Makefile index 3be13e3..117f80d 100644 --- a/Makefile +++ b/Makefile @@ -33,18 +33,18 @@ LDFLAGS += -Wl,--warn-common include mk/cflags.mk -CFLAGS += --std=gnu99 -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 +CFLAGS += --std=gnu99 -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 $(shell pkg-config --cflags lua5.1) PROGRAMS = postlicyd GENERATED = tokens.h tokens.c postlicyd_SOURCES = \ - str.h buffer.h job.h postfix.h \ - str.c buffer.c job.c postfix.c \ + str.h buffer.h daemon.h postfix.h \ + str.c buffer.c daemon.c postfix.c \ postlicyd.c $(GENERATED) -postlicyd_LIBADD = -lpthread +postlicyd_LIBADD = -lpthread $(shell pkg-config --libs lua5.1) # RULES ###################################################################{{{ @@ -76,8 +76,7 @@ headers: .%.o: %.c Makefile $(CC) $(CFLAGS) -MMD -MT ".$*.dep $@" -MF .$*.dep -g -c -o $@ $< -.%.dep: %.c Makefile - $(CC) $(CFLAGS) -MM -MT ".$*.o $@" -MF .$*.dep $< +.%.dep: .%.o .SECONDEXPANSION: diff --git a/daemon.c b/daemon.c new file mode 100644 index 0000000..ec8be65 --- /dev/null +++ b/daemon.c @@ -0,0 +1,89 @@ +/******************************************************************************/ +/* 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 + */ + +#include + +#include "postlicyd.h" +#include "daemon.h" + +int tcp_listen(const struct sockaddr *addr, socklen_t len) +{ + int sock; + + switch (addr->sa_family) { + case AF_UNIX: + unlink(((struct sockaddr_un *)addr)->sun_path); + sock = socket(PF_UNIX, SOCK_STREAM, 0); + break; + case AF_INET: + sock = socket(PF_INET, SOCK_STREAM, 0); + break; + case AF_INET6: + sock = socket(PF_INET6, SOCK_STREAM, 0); + break; + default: + errno = EINVAL; + return -1; + } + + if (sock < 0) { + UNIXERR("socket"); + return -1; + } + + if (addr->sa_family != AF_UNIX) { + int v = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) < 0) { + UNIXERR("setsockopt(SO_REUSEADDR)"); + close(sock); + return -1; + } + } + + if (bind(sock, addr, len) < 0) { + UNIXERR("bind"); + close(sock); + return -1; + } + + if (listen(sock, 0) < 0) { + UNIXERR("bind"); + close(sock); + return -1; + } + + return sock; +} + diff --git a/daemon.h b/daemon.h new file mode 100644 index 0000000..5e3b30f --- /dev/null +++ b/daemon.h @@ -0,0 +1,41 @@ +/******************************************************************************/ +/* 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_DAEMON_H +#define POSTLICYD_DAEMON_H + +int tcp_listen(const struct sockaddr *addr, socklen_t len); + +#endif diff --git a/job.c b/job.c deleted file mode 100644 index 3d99a8f..0000000 --- a/job.c +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************/ -/* 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef EPOLLRDHUP -# include -# ifdef POLLRDHUP -# define EPOLLRDHUP POLLRDHUP -# else -# define EPOLLRDHUP 0 -# endif -#endif - -#include "job.h" - -static int epollfd = -1; -static bool sigint = false; - -void job_delete(job_t **job) -{ - if (*job) { - if ((*job)->stop) { - (*job)->stop(*job); - } - if ((*job)->fd >= 0) { - close((*job)->fd); - } - p_delete(job); - } -} - -static job_t *job_register_fd(job_t *job) -{ - struct epoll_event event = { .data.ptr = job, .events = EPOLLRDHUP }; - - if (job->mode & (JOB_READ | JOB_LISTEN)) { - event.events |= EPOLLIN; - } - - if (job->mode & (JOB_WRITE | JOB_CONN)) { - event.events |= EPOLLOUT; - } - - if (epoll_ctl(epollfd, EPOLL_CTL_ADD, job->fd, &event) < 0) { - syslog(LOG_ERR, "epoll_ctl error: %m"); - job->error = true; - job_delete(&job); - } - - return job; -} - -void job_update_mode(job_t *job, int mode) -{ - struct epoll_event event = { .data.ptr = job, .events = EPOLLRDHUP }; - - if (job->mode == mode) - return; - - job->mode = mode; - if (job->mode & (JOB_READ | JOB_LISTEN)) { - event.events |= EPOLLIN; - } - - if (job->mode & (JOB_WRITE | JOB_CONN)) { - event.events |= EPOLLOUT; - } - - if (epoll_ctl(epollfd, EPOLL_CTL_MOD, job->fd, &event) < 0) { - syslog(LOG_ERR, "epoll_ctl error: %m"); - job->error = true; - } -} - -job_t *job_accept(job_t *listener, int mode) -{ - int sock; - job_t *res; - - if ((sock = accept(listener->fd, NULL, 0)) < 0) { - syslog(LOG_ERR, "accept error: %m"); - return NULL; - } - - if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK)) { - syslog(LOG_ERR, "fcntl error: %m"); - return NULL; - } - - res = job_new(); - res->fd = sock; - res->mode = mode; - res->process = listener->process; - res->stop = listener->stop; - return job_register_fd(res); -} - -static void job_sighandler(int sig) -{ - static time_t lastintr = 0; - time_t now = time(NULL); - - switch (sig) { - case SIGINT: - if (sigint) { - if (now - lastintr >= 1) - break; - } else { - lastintr = now; - sigint = true; - } - return; - - case SIGTERM: - break; - - default: - return; - } - - syslog(LOG_ERR, "Killed..."); - exit(-1); -} - -void job_initialize(void) -{ - signal(SIGPIPE, SIG_IGN); - signal(SIGINT, &job_sighandler); - signal(SIGTERM, &job_sighandler); - - epollfd = epoll_create(128); - if (epollfd < 0) { - syslog(LOG_ERR, "epoll_create error: %m"); - exit(EX_OSERR); - } -} - -void job_loop(void) -{ - while (!sigint) { - struct epoll_event events[FD_SETSIZE]; - int todo = epoll_wait(epollfd, events, countof(events), -1); - - if (todo < 0) { - if (errno == EAGAIN || errno == EINTR) - continue; - syslog(LOG_ERR, "epoll_wait error: %m"); - exit(EX_OSERR); - } - - while (todo) { - job_t *job = events[--todo].data.ptr; - - assert (job->process); - job->process(job); - - if (job->error || job->done) { - job_delete(&job); - } - } - } -} - -void job_shutdown(void) -{ - if (epollfd >= 0) { - close(epollfd); - epollfd = -1; - } -} diff --git a/mk/cflags.mk b/mk/cflags.mk index be09ba3..598aedd 100644 --- a/mk/cflags.mk +++ b/mk/cflags.mk @@ -66,7 +66,7 @@ CFLAGS += -Wno-unused-parameter # warn about variable use before initialization CFLAGS += -Wuninitialized # warn about variables which are initialized with themselves -CFLAGS += -Winit-self +CFLAGS += $(if $(GCC4),-Winit-self) # warn about pointer arithmetic on void* and function pointers CFLAGS += -Wpointer-arith # warn about multiple declarations @@ -75,10 +75,7 @@ CFLAGS += -Wredundant-decls CFLAGS += -Wformat-nonliteral # do not warn about zero-length formats. CFLAGS += -Wno-format-zero-length -# missing prototypes -CFLAGS += -Wmissing-prototypes +# do not warn about strftime format with y2k issues +CFLAGS += -Wno-format-y2k # warn about functions without format attribute that should have one CFLAGS += -Wmissing-format-attribute -# barf if we change constness -#CFLAGS += -Wcast-qual - diff --git a/postfix.c b/postfix.c index e9cea6a..4086deb 100644 --- a/postfix.c +++ b/postfix.c @@ -33,24 +33,20 @@ * Copyright © 2006-2007 Pierre Habouzit */ -#include -#include -#include -#include -#include - -#include "job.h" +#include "postlicyd.h" #include "postfix.h" #include "buffer.h" #include "tokens.h" +#if 0 + #define ishspace(c) ((c) == ' ' || (c) == '\t') -struct jpriv_t { +typedef struct jpriv_t { buffer_t ibuf; buffer_t obuf; query_t query; -}; +} jpriv_t; static jpriv_t *postfix_jpriv_init(jpriv_t *jp) { @@ -68,11 +64,6 @@ static void postfix_jpriv_wipe(jpriv_t *jp) DO_NEW(jpriv_t, postfix_jpriv); DO_DELETE(jpriv_t, postfix_jpriv); -static void postfix_stop(job_t *job) -{ - postfix_jpriv_delete(&job->jdata); -} - static int postfix_parsejob(query_t *query) { #define PARSE_CHECK(expr, error, ...) \ @@ -195,8 +186,6 @@ static void postfix_process(job_t *job) if (job->jdata->obuf.len) return; - job_update_mode(job, JOB_READ); - /* fall through */ case JOB_READ: @@ -233,8 +222,6 @@ static void postfix_process(job_t *job) return; } - job_update_mode(job, JOB_IDLE); - /* TODO: run the scenario */ return; @@ -243,3 +230,4 @@ static void postfix_process(job_t *job) return; } } +#endif diff --git a/postlicyd.c b/postlicyd.c index ebf8260..bc8eeea 100644 --- a/postlicyd.c +++ b/postlicyd.c @@ -30,29 +30,73 @@ /******************************************************************************/ /* - * Copyright © 2006 Pierre Habouzit + * Copyright © 2006-2007 Pierre Habouzit */ -#include -#include -#include -#include +#include +#include +#include -#include "job.h" +#include "postlicyd.h" -bool cleanexit = false; +static bool cleanexit = false; +static bool sigint = false; + +static void main_sighandler(int sig) +{ + static time_t lastintr = 0; + time_t now = time(NULL); + + switch (sig) { + case SIGINT: + if (sigint) { + if (now - lastintr >= 1) + break; + } else { + lastintr = now; + sigint = true; + } + return; + + case SIGTERM: + break; + + default: + return; + } + + syslog(LOG_ERR, "Killed..."); + exit(-1); +} static void main_initialize(void) { openlog("postlicyd", LOG_PID, LOG_MAIL); - job_initialize(); + signal(SIGPIPE, SIG_IGN); + signal(SIGINT, &main_sighandler); + signal(SIGTERM, &main_sighandler); syslog(LOG_INFO, "Starting..."); } +static void main_loop(void) +{ + while (!sigint) { + int fd = accept(-1, NULL, 0); + + if (fd < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + syslog(LOG_ERR, "accept error: %m"); + return; + } + + //pthread_create(NULL, NULL, job_run, (intptr_t)fd); + } +} + static void main_shutdown(void) { syslog(LOG_INFO, cleanexit ? "Stopping..." : "Unclean exit..."); - job_shutdown(); closelog(); } @@ -60,14 +104,12 @@ int main(void) { if (atexit(main_shutdown)) { fputs("Cannot hook my atexit function, quitting !\n", stderr); - return EX_CONFIG; + return EXIT_FAILURE; } main_initialize(); - - job_loop(); - + main_loop(); cleanexit = true; main_shutdown(); - return 0; + return EXIT_SUCCESS; } diff --git a/job.h b/postlicyd.h similarity index 74% rename from job.h rename to postlicyd.h index 7246ef9..3c6003c 100644 --- a/job.h +++ b/postlicyd.h @@ -33,47 +33,23 @@ * Copyright © 2007 Pierre Habouzit */ -#ifndef POSTLICYD_JOB_H -#define POSTLICYD_JOB_H - -#include "mem.h" - -enum job_mode { - JOB_IDLE = 0x00, - JOB_READ = 0x01, - JOB_WRITE = 0x02, - JOB_RDWR = JOB_READ | JOB_WRITE, - JOB_LISTEN = 0x04, - JOB_CONN = 0x08, -}; - -typedef struct jpriv_t jpriv_t; -typedef struct job_t { - unsigned mode : 6; /* 4 are enough, 2 used as padding */ - unsigned done : 1; - unsigned error : 1; - unsigned state : 24; - - int fd; - - void (*process)(struct job_t *); - void (*stop)(struct job_t *); - - jpriv_t *jdata; -} job_t; - -static inline job_t *job_new(void) { - job_t *job = p_new(job_t, 1); - job->fd = -1; - return job; -} -void job_delete(job_t **job); - -void job_update_mode(job_t *job, int mode); -job_t *job_accept(job_t *listener, int mode); - -void job_initialize(void); -void job_loop(void); -void job_shutdown(void); +#ifndef POSTLICYD_H +#define POSTLICYD_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UNIXERR(fun) \ + syslog(LOG_ERR, "%s:%d:%s: %s: %m", \ + __FILE__, __LINE__, __func__, fun) #endif