168 #include <sys/socket.h>
178 #ifdef STRCASECMP_IN_STRINGS_H
226 static int use_count;
229 static char *trigger_server_name;
230 static char **trigger_server_argv;
231 static void (*trigger_server_accept) (
int,
void *);
232 static void (*trigger_server_onexit) (
char *,
char **);
233 static void (*trigger_server_pre_accept) (
char *,
char **);
234 static VSTREAM *trigger_server_lock;
235 static int trigger_server_in_flow_delay;
236 static unsigned trigger_server_generation;
237 static int trigger_server_watchdog = 1000;
241 static NORETURN trigger_server_exit(
void)
243 if (trigger_server_onexit)
244 trigger_server_onexit(trigger_server_name, trigger_server_argv);
250 static void trigger_server_abort(
int unused_event,
void *unused_context)
253 msg_info(
"master disconnect -- exiting");
254 trigger_server_exit();
259 static void trigger_server_timeout(
int unused_event,
void *unused_context)
262 msg_info(
"idle timeout -- exiting");
263 trigger_server_exit();
268 static void trigger_server_wakeup(
int fd)
282 if ((len = read(fd, buf,
sizeof(buf))) >= 0)
283 trigger_server_service(buf, len, trigger_server_name,
284 trigger_server_argv);
290 if (use_count < INT_MAX)
296 static void trigger_server_accept_fifo(
int unused_event,
void *context)
298 const char *myname =
"trigger_server_accept_fifo";
301 if (trigger_server_lock != 0
307 msg_info(
"%s: trigger arrived", myname);
313 if (trigger_server_pre_accept)
314 trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
315 trigger_server_wakeup(listen_fd);
320 static void trigger_server_accept_local(
int unused_event,
void *context)
322 const char *myname =
"trigger_server_accept_local";
328 msg_info(
"%s: trigger arrived", myname);
340 if (trigger_server_pre_accept)
341 trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
343 if (trigger_server_lock != 0
356 trigger_server_wakeup(fd);
357 else if (time_left >= 0)
362 #ifdef MASTER_XPORT_NAME_PASS
366 static void trigger_server_accept_pass(
int unused_event,
void *context)
368 const char *myname =
"trigger_server_accept_pass";
374 msg_info(
"%s: trigger arrived", myname);
386 if (trigger_server_pre_accept)
387 trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
389 if (trigger_server_lock != 0
402 trigger_server_wakeup(fd);
403 else if (time_left >= 0)
414 const char *myname =
"trigger_server_main";
419 char *service_name =
basename(argv[0]);
423 int socket_count = 1;
443 int msg_vstream_needed = 0;
444 int redo_syslog_init = 0;
445 const char *dsn_filter_title;
446 const char **dsn_filter_maps;
459 signal(SIGPIPE, SIG_IGN);
465 signal(SIGXFSZ, SIG_IGN);
504 while ((c =
GETOPT(argc, argv,
"cdDi:lm:n:o:s:St:uvVz")) > 0) {
525 service_name = optarg;
530 msg_fatal(
"invalid \"-o %s\" option value: %s", optarg, err);
533 redo_syslog_init = 1;
537 if ((socket_count = atoi(optarg)) <= 0)
538 msg_fatal(
"invalid socket_count: %s", optarg);
553 if (++msg_vstream_needed == 1)
570 if (redo_syslog_init)
582 if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
584 msg_fatal(
"do not run this command by hand");
590 va_start(ap, service);
591 while ((key = va_arg(ap,
int)) != 0) {
633 trigger_server_in_flow_delay = 1;
636 if (stream == 0 && !alone)
637 msg_fatal(
"service %s requires a process limit of 1",
641 if (stream == 0 && !zerolimit)
642 msg_fatal(
"service %s requires a process limit of 0",
647 msg_fatal(
"service %s requires privileged operation",
651 trigger_server_watchdog = *va_arg(ap,
int *);
654 dsn_filter_title = va_arg(ap,
const char *);
655 dsn_filter_maps = va_arg(ap,
const char **);
659 msg_panic(
"%s: unknown argument type: %d", myname, key);
688 msg_fatal(
"no transport type specified");
690 trigger_server_accept = trigger_server_accept_local;
692 trigger_server_accept = trigger_server_accept_fifo;
693 #ifdef MASTER_XPORT_NAME_PASS
695 trigger_server_accept = trigger_server_accept_pass;
698 msg_fatal(
"unsupported transport type: %s", transport);
706 msg_fatal(
"bad generation: %s", generation);
709 msg_info(
"process generation: %s (%o)",
710 generation, trigger_server_generation);
725 if (stream == 0 && !alone) {
727 ".", service_name, (
char *) 0);
729 if ((trigger_server_lock =
safe_open(lock_path, O_CREAT | O_RDWR, 0600,
730 (
struct stat *) 0, -1, -1, why)) == 0)
740 trigger_server_service = service;
741 trigger_server_name = service_name;
742 trigger_server_argv = argv + optind;
750 pre_init(trigger_server_name, trigger_server_argv);
763 post_init(trigger_server_name, trigger_server_argv);
772 service(buf, len, trigger_server_name, trigger_server_argv);
774 trigger_server_exit();
800 if (trigger_server_lock != 0) {
807 delay = loop ? loop(trigger_server_name, trigger_server_argv) : -1;
810 trigger_server_exit();
void event_enable_read(int fd, EVENT_NOTIFY_RDWR_FN callback, void *context)
void msg_error(const char *fmt,...)
#define MAIL_SERVER_UNLIMITED
const char * mail_task(const char *argv0)
#define MAIL_SERVER_STR_TABLE
char * mystrdup(const char *str)
int master_notify(int pid, unsigned generation, int status)
void set_mail_conf_str(const char *, const char *)
#define CAST_ANY_PTR_TO_INT(cptr)
NORETURN msg_panic(const char *fmt,...)
void chroot_uid(const char *root_dir, const char *user_name)
#define MAIL_SERVER_INT_TABLE
#define MASTER_FLOW_WRITE
#define MYFLOCK_OP_EXCLUSIVE
#define OCTAL_TO_UNSIGNED(res, str)
#define MAIL_SERVER_TIME_TABLE
void get_mail_conf_nint_table(const CONFIG_NINT_TABLE *)
void(* MAIL_SERVER_EXIT_FN)(char *, char **)
void get_mail_conf_nbool_table(const CONFIG_NBOOL_TABLE *)
#define MASTER_XPORT_NAME_PASS
#define EVENT_NULL_CONTEXT
void(* TRIGGER_SERVER_FN)(char *, ssize_t, char *, char **)
int alldig(const char *string)
#define MASTER_STAT_AVAIL
const char * split_nameval(char *buf, char **name, char **value)
void watchdog_start(WATCHDOG *wp)
#define MAIL_SERVER_WATCHDOG
void(* WATCHDOG_FN)(WATCHDOG *, char *)
void mail_conf_suck(void)
#define MAIL_SERVER_BOOL_TABLE
#define MAIL_SERVER_PRIVILEGED
#define MAIL_SERVER_POST_INIT
#define MAIL_SERVER_BOUNCE_INIT
NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,...)
void get_mail_conf_time_table(const CONFIG_TIME_TABLE *)
#define MAIL_SERVER_PRE_ACCEPT
#define MASTER_STAT_TAKEN
void(* MAIL_SERVER_INIT_FN)(char *, char **)
void get_mail_conf_raw_table(const CONFIG_RAW_TABLE *)
#define CAST_INT_TO_VOID_PTR(ival)
ssize_t mail_flow_get(ssize_t len)
void event_loop(int delay)
WATCHDOG * watchdog_create(unsigned timeout, WATCHDOG_FN action, char *context)
#define read_wait(fd, timeout)
#define MAIL_SERVER_IN_FLOW_DELAY
void resolve_local_init(void)
VSTRING * vstring_alloc(ssize_t len)
int myflock(int fd, int lock_style, int operation)
void mail_dict_init(void)
void doze(unsigned delay)
#define MASTER_XPORT_NAME_FIFO
void get_mail_conf_str_table(const CONFIG_STR_TABLE *)
NORETURN msg_fatal(const char *fmt,...)
void get_mail_conf_bool_table(const CONFIG_BOOL_TABLE *)
#define MASTER_XPORT_NAME_UNIX
#define MAIL_VERSION_CHECK
#define MAIL_SERVER_LONG_TABLE
int vstream_fflush(VSTREAM *stream)
void watchdog_stop(WATCHDOG *wp)
char * concatenate(const char *arg0,...)
#define GETOPT(argc, argv, str)
void bounce_client_init(const char *title, const char *maps)
void msg_syslog_init(const char *name, int logopt, int facility)
void(* MAIL_SERVER_ACCEPT_FN)(char *, char **)
#define MAIL_SERVER_NINT_TABLE
int strcasecmp(const char *s1, const char *s2)
VSTREAM * safe_open(const char *path, int flags, mode_t mode, struct stat *st, uid_t user, gid_t group, VSTRING *why)
VSTRING * vstring_free(VSTRING *vp)
time_t event_request_timer(EVENT_NOTIFY_TIME_FN callback, void *context, int delay)
#define MAIL_SERVER_PRE_INIT
void get_mail_conf_int_table(const CONFIG_INT_TABLE *)
#define vstream_fileno(vp)
void msg_vstream_init(const char *name, VSTREAM *vp)
int(* MAIL_SERVER_LOOP_FN)(char *, char **)
void get_mail_conf_long_table(const CONFIG_LONG_TABLE *)
void mail_conf_update(const char *key, const char *value)
#define MAIL_SERVER_NBOOL_TABLE
int event_cancel_timer(EVENT_NOTIFY_TIME_FN callback, void *context)
int close_on_exec(int fd, int on)
#define MAIL_SERVER_RAW_TABLE
#define MAIL_SERVER_SOLITARY
void msg_info(const char *fmt,...)