2 * Copyright (c) 2021 Proofpoint, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
14 #include <sm/sendmail.h>
15 #include <sm/notify.h>
17 static ENVELOPE QmEnvelope;
23 ** Note: these are not "universal", e.g.,
24 ** proc_list_add() might be used in parent or child.
25 ** maybe check pname != NULL to invoke proc_list_add()?
28 #define FORK_P1(emsg, pname, ptype) \
30 (void) sm_blocksignal(SIGCHLD); \
31 (void) sm_signal(SIGCHLD, reapchild); \
36 const char *msg = emsg; \
37 const char *err = sm_errstring(errno); \
40 sm_syslog(LOG_INFO, NOQID, "%s: %s", \
42 (void) sm_releasesignal(SIGCHLD); \
47 proc_list_add(pid, pname, ptype, 0, -1, NULL); \
48 /* parent -- pick up intermediate zombie */ \
49 (void) sm_releasesignal(SIGCHLD); \
56 /* child -- clean up signals */ \
58 /* Reset global flags */ \
59 RestartRequest = NULL; \
60 RestartWorkGroup = false; \
61 ShutdownRequest = NULL; \
63 CurrentPid = getpid(); \
64 close_sendmail_pid(); \
67 ** Initialize exception stack and default exception \
68 ** handler for child process. \
71 sm_exc_newthread(fatal_error); \
75 (void) sm_releasesignal(SIGCHLD); \
76 (void) sm_signal(SIGCHLD, SIG_DFL); \
77 (void) sm_signal(SIGHUP, SIG_DFL); \
78 (void) sm_signal(SIGTERM, intsig); \
80 /* drop privileges */ \
81 if (geteuid() == (uid_t) 0) \
82 (void) drop_privileges(false); \
83 disconnect(1, NULL); \
89 ** QM -- queue "manager"
98 ** fork()s and runs as process to deliver queue entries
108 sm_syslog(LOG_DEBUG, NOQID, "queue manager: start");
110 FORK_P1("Queue manager -- fork() failed", "QM", PROC_QM);
113 r = sm_notify_start(true, 0);
115 syserr("sm_notify_start() failed=%d", r);
118 ** Initially wait indefinitely, then only wait
119 ** until something needs to get done (not yet implemented).
130 ** TODO: This should try to receive multiple ids:
131 ** after it got one, check for more with a very short timeout
132 ** and collect them in a list.
133 ** but them some other code should be used to run all of them.
136 sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=start");
137 r = sm_notify_rcv(buf, sizeof(buf), tmo);
140 sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=timed_out");
145 sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=%d", r);
148 if (r > 0 && r < sizeof(buf))
150 buf[sizeof(buf) - 1] = '\0';
151 sm_syslog(LOG_DEBUG, NOQID, "queue manager: got=%s", buf);
152 CurEnv = &QmEnvelope;
153 rpool = sm_rpool_new_x(NULL);
154 e = newenvelope(&QmEnvelope, CurEnv, rpool);
155 e->e_flags = BlankEnvelope.e_flags;
157 r = sm_io_sscanf(buf, "N:%d:%d:%s", &e->e_qgrp, &e->e_qdir, e->e_id);
160 sm_syslog(LOG_DEBUG, NOQID, "queue manager: buf=%s, scan=%d", buf, r);
163 dowork(e->e_qgrp, e->e_qdir, e->e_id, true, false, e);
167 sm_syslog(LOG_DEBUG, NOQID, "queue manager: stop");
168 finis(false, false, EX_OK);
172 #endif /* _FFR_DMTRIGGER */