diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-12-22 21:39:23 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-12-22 21:54:43 +0200 |
commit | 67a64a6a7809c183516740696e15ab88f82d7ef0 (patch) | |
tree | b58f30a8cee98bac7c9f4bc8236c86eefdadb4ef /src/net.c | |
parent | 2c28190e77ce38b6437a2be8337680f77f58d37a (diff) | |
download | wydawca-67a64a6a7809c183516740696e15ab88f82d7ef0.tar.gz wydawca-67a64a6a7809c183516740696e15ab88f82d7ef0.tar.bz2 |
Implement inotify support.
* configure.ac: New option --with-inotify.
Bye default, use inotify if it is present.
* src/watcher.c: New file. Implements inotify watcher.
* src/Makefile.am [COND_INOTIFY] (wydawca_SOURCES): Add watcher.c
* src/diskio.c (dir_get_path): New function.
* src/job.c (job) <spool>: Remove const qualifier. All uses changed.
(inotify_spool): New pseudo-spool.
(fake_spool): Remove static qualifier.
(wydawca_scanner): Support for inotify spools.
* src/net.c (open_listener): Don't exit if the listener
address is not set.
(wydawca_listener): Listen on the listener socket and
on the inotify descriptor. If none is set, bail out.
* src/process.c (for_each_spool)
(file_info_cleanup)
(spool_cwd_add_new_file,spool_add_new_file): New functions.
(scan_spool_unlocked): Use spool_cwd_add_new_file.
Don't initialize dictionaries here: it will be done in
spool_commit_triplets.
(spool_open_dictionaries): New function.
(close_dictionaries): Rename to spool_close_dictionaries.
Clear dict_inited.
* src/triplet.c (hash_triplet_compare): Compare spools as well.
(register_file): Likewise.
(triplet_lookup): New function.
(check_triplet_state): New argument: noauth. All uses updated.
(enumerate_triplets): Rename to spool_commit_triplets.
Call spool_open_dictionaries.
(count_processable_triplets,triplet_remove_file): New functions.
* src/verify.c (verify_directive_file): New argument: noauth.
All uses updated.
* src/vtab.c (reg): Initialize get_path member.
(get_path): New function.
* src/wydawca.c (main): Set print_version_hook.
* src/wydawca.h (virt_tab) <get_path>: New method.
(spool) <dict_inited>: New member.
(fake_spool, inotify_spool): New externs.
(spool_add_new_file, spool_cwd_add_new_file)
(spool_open_dictionaries, spool_close_dictionaries)
(for_each_spool, count_processable_triplets)
(triplet_remove_file, get_path): New protos.
(enumerate_triplets): Rename to spool_commit_triplets.
(verify_directive_file): Take two arguments.
Diffstat (limited to 'src/net.c')
-rw-r--r-- | src/net.c | 87 |
1 files changed, 56 insertions, 31 deletions
@@ -13,28 +13,25 @@ You should have received a copy of the GNU General Public License along with wydawca. If not, see <http://www.gnu.org/licenses/>. */ #include "wydawca.h" static int open_listener () { int fd; if (listen_sockaddr.sa == NULL) - { - logmsg (LOG_CRIT, _("listener address is not configured")); - exit (EX_CONFIG); - } + return -1; fd = socket (listen_sockaddr.sa->sa_family, SOCK_STREAM, 0); if (fd == -1) { logmsg (LOG_CRIT, _("cannot create socket: %s"), strerror(errno)); exit (EX_OSERR); } if (listen_sockaddr.sa->sa_family == AF_UNIX) { struct stat st; struct sockaddr_un *s_un = (struct sockaddr_un *) listen_sockaddr.sa; @@ -90,25 +87,25 @@ trim_crlf (char *s) { s[--len] = 0; if (len > 0 && s[len-1] == '\r') s[--len] = 0; } } void handle_connection (FILE *in, FILE *out) { char *buf = NULL; size_t buflen = 0; - const struct spool *spool; + struct spool *spool; char *p; struct passwd *pw; if (grecs_getline (&buf, &buflen, in) <= 0) return; trim_crlf (buf); if (debug_level) logmsg (LOG_DEBUG, "recv: %s", buf); spool = wydawca_find_spool (buf); if (!spool) { if (all_spool_aliases && grecs_list_locate (all_spool_aliases, buf)) @@ -165,80 +162,108 @@ sig_hup (int sig) } RETSIGTYPE sig_term (int sig) { terminate = 1; } void wydawca_listener () { int ctlfd = open_listener (); + int wfd = watcher_init (); + int maxfd = 0; + + if (ctlfd != -1) + maxfd = ctlfd; + + if (wfd != -1 && wfd > maxfd) + maxfd = wfd; + if (maxfd == 0) + { + logmsg (LOG_CRIT, + _("listener address is not configured and inotify is not available")); + exit (EX_CONFIG); + } + job_init (); signal (SIGHUP, sig_hup); signal (SIGTERM, sig_term); signal (SIGQUIT, sig_term); signal (SIGINT, sig_term); while (!terminate) { - int fd; - FILE *in, *out; int rc; fd_set rset; struct timeval to, *pto; - union { - struct sockaddr sa; - struct sockaddr_in s_in; - struct sockaddr_un s_un; - } addr; - socklen_t len; job_queue_runner (); FD_ZERO (&rset); - FD_SET (ctlfd, &rset); + if (ctlfd != -1) + FD_SET (ctlfd, &rset); + if (wfd != -1) + FD_SET (wfd, &rset); if (wakeup_interval) { to.tv_sec = wakeup_interval; to.tv_usec = 0; *pto = to; } else pto = NULL; - rc = select (ctlfd + 1, &rset, NULL, NULL, pto); + rc = select (maxfd + 1, &rset, NULL, NULL, pto); if (rc == 0) continue; else if (rc < 0) { if (errno == EINTR) continue; logmsg (LOG_ERR, "select: %s", strerror (errno)); break; } - len = sizeof (addr); - fd = accept (ctlfd, (struct sockaddr*) &addr, &len); - if (fd == -1) - continue; - /* FIXME: Use Mailutils ACLs? */ -#ifdef WITH_LIBWRAP - if (!tcpwrap_access(fd)) + if (wfd != -1 && FD_ISSET (wfd, &rset)) { - close(fd); - continue; + watcher_run (wfd); } + + if (ctlfd != -1 && FD_ISSET (ctlfd, &rset)) + { + int fd; + FILE *in, *out; + union + { + struct sockaddr sa; + struct sockaddr_in s_in; + struct sockaddr_un s_un; + } addr; + socklen_t len; + + len = sizeof (addr); + fd = accept (ctlfd, (struct sockaddr*) &addr, &len); + if (fd == -1) + continue; + /* FIXME: Use Mailutils ACLs? */ +#ifdef WITH_LIBWRAP + if (!tcpwrap_access(fd)) + { + close(fd); + continue; + } #endif - in = fdopen (fd, "r"); - setlinebuf (in); - out = fdopen (fd, "w"); - setlinebuf (out); - handle_connection (in, out); - fclose (in); - fclose (out); + in = fdopen (fd, "r"); + setlinebuf (in); + out = fdopen (fd, "w"); + setlinebuf (out); + handle_connection (in, out); + fclose (in); + fclose (out); + } } } |