/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
#include "common.h"
+#include "ioloop.h"
#include "fd-close-on-exec.h"
#include "fd-set-nonblock.h"
#include "service.h"
#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
+static void
+anvil_input_fd_discard(struct service_list *service_list, int fd)
+{
+ char buf[1024];
+ ssize_t ret;
+
+ ret = read(fd, buf, sizeof(buf));
+ if (ret <= 0) {
+ i_error("read(anvil fd) failed: %m");
+ io_remove(&service_list->anvil_io_blocking);
+ io_remove(&service_list->anvil_io_nonblocking);
+ }
+}
+
+static void anvil_input_blocking_discard(struct service_list *service_list)
+{
+ anvil_input_fd_discard(service_list,
+ service_list->blocking_anvil_fd[0]);
+}
+
+static void anvil_input_nonblocking_discard(struct service_list *service_list)
+{
+ anvil_input_fd_discard(service_list,
+ service_list->nonblocking_anvil_fd[0]);
+}
+
+static void service_list_anvil_discard_input(struct service_list *service_list)
+{
+ service_list->anvil_io_blocking =
+ io_add(service_list->blocking_anvil_fd[0], IO_READ,
+ anvil_input_blocking_discard, service_list);
+ service_list->anvil_io_nonblocking =
+ io_add(service_list->nonblocking_anvil_fd[0], IO_READ,
+ anvil_input_nonblocking_discard, service_list);
+}
+
static int anvil_send_handshake(int fd, const char **error_r)
{
ssize_t ret;
service_list->anvil_kills =
service_process_notify_init(service_list->nonblocking_anvil_fd[1],
service_process_write_anvil_kill);
+ service_list_anvil_discard_input(service_list);
return 0;
}
if (close(service_list->nonblocking_anvil_fd[1]) < 0)
i_error("close(anvil) failed: %m");
}
+
+void service_anvil_process_created(struct service *service)
+{
+ if (service->list->anvil_io_blocking != NULL) {
+ io_remove(&service->list->anvil_io_blocking);
+ io_remove(&service->list->anvil_io_nonblocking);
+ }
+}
+
+void service_anvil_process_destroyed(struct service *service)
+{
+ if (service->process_count == 0 &&
+ service->list->anvil_io_blocking == NULL)
+ service_list_anvil_discard_input(service->list);
+}
#include "master-service-settings.h"
#include "dup2-array.h"
#include "service.h"
+#include "service-anvil.h"
#include "service-log.h"
#include "service-auth-server.h"
#include "service-auth-source.h"
service_process_auth_source_init(process, fd[0]);
(void)close(fd[1]);
break;
+ case SERVICE_TYPE_ANVIL:
+ service_anvil_process_created(service);
+ /* fall through */
default:
process = i_new(struct service_process, 1);
process->service = service;
case SERVICE_TYPE_AUTH_SOURCE:
service_process_auth_source_deinit(process);
break;
+ case SERVICE_TYPE_ANVIL:
+ service_anvil_process_destroyed(service);
+ break;
default:
break;
}