void queue_flow_control(void) { size_t bufsz; int oldlimit = limit; int set, unset; bufsz = p_mda->bytes_queued + p_mta->bytes_queued; if (bufsz <= flow_agent_lowat) limit &= ~LIMIT_AGENT; else if (bufsz > flow_agent_hiwat) limit |= LIMIT_AGENT; if (p_scheduler->bytes_queued <= flow_scheduler_lowat) limit &= ~LIMIT_SCHEDULER; else if (p_scheduler->bytes_queued > flow_scheduler_hiwat) limit |= LIMIT_SCHEDULER; set = limit & (limit ^ oldlimit); unset = oldlimit & (limit ^ oldlimit); if (set & LIMIT_SCHEDULER) { log_warnx("warn: queue: Hiwat reached on scheduler buffer: " "suspending transfer, delivery and lookup input"); mproc_disable(p_mta); mproc_disable(p_mda); mproc_disable(p_lka); } else if (unset & LIMIT_SCHEDULER) { log_warnx("warn: queue: Down to lowat on scheduler buffer: " "resuming transfer, delivery and lookup input"); mproc_enable(p_mta); mproc_enable(p_mda); mproc_enable(p_lka); } if (set & LIMIT_AGENT) { log_warnx("warn: queue: Hiwat reached on transfer and delivery " "buffers: suspending scheduler input"); mproc_disable(p_scheduler); } else if (unset & LIMIT_AGENT) { log_warnx("warn: queue: Down to lowat on transfer and delivery " "buffers: resuming scheduler input"); mproc_enable(p_scheduler); } }
pid_t ca(void) { pid_t pid; struct passwd *pw; struct event ev_sigint; struct event ev_sigterm; switch (pid = fork()) { case -1: fatal("ca: cannot fork"); case 0: post_fork(PROC_CA); break; default: return (pid); } purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES); if ((pw = getpwnam(SMTPD_USER)) == NULL) fatalx("unknown user " SMTPD_USER); if (chroot(PATH_CHROOT) == -1) fatal("ca: chroot"); if (chdir("/") == -1) fatal("ca: chdir(\"/\")"); config_process(PROC_CA); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("ca: cannot drop privileges"); imsg_callback = ca_imsg; event_init(); signal_set(&ev_sigint, SIGINT, ca_sig_handler, NULL); signal_set(&ev_sigterm, SIGTERM, ca_sig_handler, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); config_peer(PROC_CONTROL); config_peer(PROC_PARENT); config_peer(PROC_PONY); config_done(); /* Ignore them until we get our config */ mproc_disable(p_pony); if (event_dispatch() < 0) fatal("event_dispatch"); ca_shutdown(); return (0); }
pid_t lka(void) { pid_t pid; struct passwd *pw; struct event ev_sigint; struct event ev_sigterm; struct event ev_sigchld; switch (pid = fork()) { case -1: fatal("lka: cannot fork"); case 0: break; default: return (pid); } purge_config(PURGE_EVERYTHING); if ((pw = getpwnam(SMTPD_USER)) == NULL) fatalx("unknown user " SMTPD_USER); config_process(PROC_LKA); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("lka: cannot drop privileges"); imsg_callback = lka_imsg; event_init(); signal_set(&ev_sigint, SIGINT, lka_sig_handler, NULL); signal_set(&ev_sigterm, SIGTERM, lka_sig_handler, NULL); signal_set(&ev_sigchld, SIGCHLD, lka_sig_handler, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); signal_add(&ev_sigchld, NULL); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); /* * lka opens all kinds of files and sockets, so bump the limit to max. * XXX: need to analyse the exact hard limit. */ fdlimit(1.0); config_peer(PROC_PARENT); config_peer(PROC_QUEUE); config_peer(PROC_SMTP); config_peer(PROC_MDA); config_peer(PROC_MTA); config_peer(PROC_CONTROL); config_done(); /* Ignore them until we get our config */ mproc_disable(p_mda); mproc_disable(p_mta); mproc_disable(p_smtp); if (event_dispatch() < 0) fatal("event_dispatch"); lka_shutdown(); return (0); }
pid_t mfa(void) { pid_t pid; struct passwd *pw; struct event ev_sigint; struct event ev_sigterm; struct event ev_sigchld; switch (pid = fork()) { case -1: fatal("filter: cannot fork"); case 0: break; default: return (pid); } mfa_filter_prepare(); purge_config(PURGE_EVERYTHING); if ((pw = getpwnam(SMTPD_USER)) == NULL) fatalx("unknown user " SMTPD_USER); config_process(PROC_MFA); if (chroot(PATH_CHROOT) == -1) fatal("scheduler: chroot"); if (chdir("/") == -1) fatal("scheduler: chdir(\"/\")"); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("filter: cannot drop privileges"); imsg_callback = mfa_imsg; event_init(); signal_set(&ev_sigint, SIGINT, mfa_sig_handler, NULL); signal_set(&ev_sigterm, SIGTERM, mfa_sig_handler, NULL); signal_set(&ev_sigchld, SIGCHLD, mfa_sig_handler, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); signal_add(&ev_sigchld, NULL); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); config_peer(PROC_PARENT); config_peer(PROC_SMTP); config_peer(PROC_CONTROL); config_done(); mproc_disable(p_smtp); if (event_dispatch() < 0) fatal("event_dispatch"); mfa_shutdown(); return (0); }