Blame


1 50794f47 2023-04-04 op /*
2 50794f47 2023-04-04 op * This file is in the public domain.
3 50794f47 2023-04-04 op */
4 50794f47 2023-04-04 op
5 50794f47 2023-04-04 op #include <sys/socket.h>
6 50794f47 2023-04-04 op #include <sys/stat.h>
7 50794f47 2023-04-04 op #include <sys/tree.h>
8 50794f47 2023-04-04 op #include <sys/types.h>
9 50794f47 2023-04-04 op #include <sys/un.h>
10 50794f47 2023-04-04 op #include <sys/wait.h>
11 50794f47 2023-04-04 op
12 50794f47 2023-04-04 op #include <err.h>
13 50794f47 2023-04-04 op #include <errno.h>
14 50794f47 2023-04-04 op #include <event.h>
15 50794f47 2023-04-04 op #include <fcntl.h>
16 50794f47 2023-04-04 op #include <limits.h>
17 50794f47 2023-04-04 op #include <pwd.h>
18 50794f47 2023-04-04 op #include <signal.h>
19 50794f47 2023-04-04 op #include <stdarg.h>
20 50794f47 2023-04-04 op #include <stdio.h>
21 50794f47 2023-04-04 op #include <stdlib.h>
22 50794f47 2023-04-04 op #include <string.h>
23 50794f47 2023-04-04 op #include <syslog.h>
24 50794f47 2023-04-04 op #include <unistd.h>
25 50794f47 2023-04-04 op
26 50794f47 2023-04-04 op #include "msearchd.h"
27 50794f47 2023-04-04 op
28 50794f47 2023-04-04 op #ifndef MSEARCHD_DB
29 50794f47 2023-04-04 op #define MSEARCHD_DB "/msearchd/mails.sqlite3"
30 50794f47 2023-04-04 op #endif
31 50794f47 2023-04-04 op
32 50794f47 2023-04-04 op #ifndef MSEARCHD_SOCK
33 50794f47 2023-04-04 op #define MSEARCHD_SOCK "/run/msearchd.sock"
34 50794f47 2023-04-04 op #endif
35 50794f47 2023-04-04 op
36 50794f47 2023-04-04 op #ifndef MSEARCHD_USER
37 50794f47 2023-04-04 op #define MSEARCHD_USER "www"
38 50794f47 2023-04-04 op #endif
39 50794f47 2023-04-04 op
40 8e5ae9ac 2023-05-05 op #ifndef MSEARCH_TMPL_DIR
41 38232a0a 2023-05-07 op #define MSEARCH_TMPL_DIR SYSCONFDIR "/smarc"
42 8e5ae9ac 2023-05-05 op #endif
43 8e5ae9ac 2023-05-05 op
44 50794f47 2023-04-04 op #define MAX_CHILDREN 32
45 50794f47 2023-04-04 op
46 50794f47 2023-04-04 op int debug;
47 50794f47 2023-04-04 op int verbose;
48 50794f47 2023-04-04 op int children = 3;
49 50794f47 2023-04-04 op pid_t pids[MAX_CHILDREN];
50 50794f47 2023-04-04 op
51 8e5ae9ac 2023-05-05 op const char *tmpl_head;
52 8e5ae9ac 2023-05-05 op const char *tmpl_search;
53 8e5ae9ac 2023-05-05 op const char *tmpl_search_header;
54 8e5ae9ac 2023-05-05 op const char *tmpl_foot;
55 8e5ae9ac 2023-05-05 op
56 50794f47 2023-04-04 op __dead void srch_syslog_fatal(int, const char *, ...);
57 50794f47 2023-04-04 op __dead void srch_syslog_fatalx(int, const char *, ...);
58 50794f47 2023-04-04 op void srch_syslog_warn(const char *, ...);
59 50794f47 2023-04-04 op void srch_syslog_warnx(const char *, ...);
60 50794f47 2023-04-04 op void srch_syslog_info(const char *, ...);
61 50794f47 2023-04-04 op void srch_syslog_debug(const char *, ...);
62 50794f47 2023-04-04 op
63 50794f47 2023-04-04 op const struct logger syslogger = {
64 50794f47 2023-04-04 op .fatal = &srch_syslog_fatal,
65 50794f47 2023-04-04 op .fatalx = &srch_syslog_fatalx,
66 50794f47 2023-04-04 op .warn = &srch_syslog_warn,
67 50794f47 2023-04-04 op .warnx = &srch_syslog_warnx,
68 50794f47 2023-04-04 op .info = &srch_syslog_info,
69 50794f47 2023-04-04 op .debug = &srch_syslog_debug,
70 50794f47 2023-04-04 op };
71 50794f47 2023-04-04 op
72 50794f47 2023-04-04 op const struct logger dbglogger = {
73 50794f47 2023-04-04 op .fatal = &err,
74 50794f47 2023-04-04 op .fatalx = &errx,
75 50794f47 2023-04-04 op .warn = &warn,
76 50794f47 2023-04-04 op .warnx = &warnx,
77 50794f47 2023-04-04 op .info = &warnx,
78 50794f47 2023-04-04 op .debug = &warnx,
79 50794f47 2023-04-04 op };
80 50794f47 2023-04-04 op
81 50794f47 2023-04-04 op const struct logger *logger = &dbglogger;
82 50794f47 2023-04-04 op
83 50794f47 2023-04-04 op static void
84 28c73ba9 2023-04-04 op sighdlr(int sig)
85 50794f47 2023-04-04 op {
86 28c73ba9 2023-04-04 op static volatile sig_atomic_t got_sig;
87 50794f47 2023-04-04 op int i, save_errno;
88 50794f47 2023-04-04 op
89 28c73ba9 2023-04-04 op if (got_sig)
90 50794f47 2023-04-04 op return;
91 28c73ba9 2023-04-04 op got_sig = -1;
92 50794f47 2023-04-04 op
93 50794f47 2023-04-04 op save_errno = errno;
94 50794f47 2023-04-04 op for (i = 0; i < children; ++i)
95 50794f47 2023-04-04 op (void)kill(pids[i], SIGTERM);
96 50794f47 2023-04-04 op errno = save_errno;
97 50794f47 2023-04-04 op }
98 50794f47 2023-04-04 op
99 8e5ae9ac 2023-05-05 op static void
100 8e5ae9ac 2023-05-05 op load_tmpl(const char **ret, const char *dir, const char *name)
101 8e5ae9ac 2023-05-05 op {
102 8e5ae9ac 2023-05-05 op FILE *fp;
103 8e5ae9ac 2023-05-05 op struct stat sb;
104 8e5ae9ac 2023-05-05 op char *t;
105 8e5ae9ac 2023-05-05 op char path[PATH_MAX];
106 8e5ae9ac 2023-05-05 op int r;
107 8e5ae9ac 2023-05-05 op
108 8e5ae9ac 2023-05-05 op r = snprintf(path, sizeof(path), "%s/%s", dir, name);
109 8e5ae9ac 2023-05-05 op if (r < 0 || (size_t)r >= sizeof(path))
110 8e5ae9ac 2023-05-05 op fatalx("path too long: %s/%s", dir, name);
111 8e5ae9ac 2023-05-05 op
112 8e5ae9ac 2023-05-05 op if ((fp = fopen(path, "r")) == NULL)
113 8e5ae9ac 2023-05-05 op fatal("can't open %s", path);
114 8e5ae9ac 2023-05-05 op
115 8e5ae9ac 2023-05-05 op if (fstat(fileno(fp), &sb) == -1)
116 8e5ae9ac 2023-05-05 op fatal("fstat");
117 8e5ae9ac 2023-05-05 op
118 8e5ae9ac 2023-05-05 op if (sb.st_size > SIZE_MAX)
119 8e5ae9ac 2023-05-05 op fatal("file too big %s", path);
120 8e5ae9ac 2023-05-05 op
121 8e5ae9ac 2023-05-05 op if ((t = malloc(sb.st_size + 1)) == NULL)
122 8e5ae9ac 2023-05-05 op fatal("malloc");
123 8e5ae9ac 2023-05-05 op
124 8e5ae9ac 2023-05-05 op if (fread(t, 1, sb.st_size, fp) != sb.st_size)
125 8e5ae9ac 2023-05-05 op fatal("fread %s", path);
126 8e5ae9ac 2023-05-05 op
127 8e5ae9ac 2023-05-05 op fclose(fp);
128 8e5ae9ac 2023-05-05 op
129 8e5ae9ac 2023-05-05 op t[sb.st_size] = '\0';
130 8e5ae9ac 2023-05-05 op *ret = t;
131 8e5ae9ac 2023-05-05 op }
132 8e5ae9ac 2023-05-05 op
133 50794f47 2023-04-04 op static int
134 50794f47 2023-04-04 op bind_socket(const char *path, struct passwd *pw)
135 50794f47 2023-04-04 op {
136 50794f47 2023-04-04 op struct sockaddr_un sun;
137 50794f47 2023-04-04 op int fd, old_umask;
138 50794f47 2023-04-04 op
139 50794f47 2023-04-04 op if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0)) == -1) {
140 50794f47 2023-04-04 op log_warn("%s: socket", __func__);
141 50794f47 2023-04-04 op return (-1);
142 50794f47 2023-04-04 op }
143 50794f47 2023-04-04 op
144 50794f47 2023-04-04 op memset(&sun, 0, sizeof(sun));
145 50794f47 2023-04-04 op sun.sun_family = AF_UNIX;
146 50794f47 2023-04-04 op
147 50794f47 2023-04-04 op if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
148 50794f47 2023-04-04 op sizeof(sun.sun_path)) {
149 50794f47 2023-04-04 op log_warnx("%s: path too long: %s", __func__, path);
150 50794f47 2023-04-04 op close(fd);
151 50794f47 2023-04-04 op return (-1);
152 50794f47 2023-04-04 op }
153 50794f47 2023-04-04 op
154 50794f47 2023-04-04 op if (unlink(path) == -1 && errno != ENOENT) {
155 50794f47 2023-04-04 op log_warn("%s: unlink %s", __func__, path);
156 50794f47 2023-04-04 op close(fd);
157 50794f47 2023-04-04 op return (-1);
158 50794f47 2023-04-04 op }
159 50794f47 2023-04-04 op
160 50794f47 2023-04-04 op old_umask = umask(0117);
161 50794f47 2023-04-04 op if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
162 50794f47 2023-04-04 op log_warn("%s: bind: %s (%d)", __func__, path, geteuid());
163 50794f47 2023-04-04 op close(fd);
164 50794f47 2023-04-04 op umask(old_umask);
165 50794f47 2023-04-04 op return (-1);
166 50794f47 2023-04-04 op }
167 50794f47 2023-04-04 op umask(old_umask);
168 50794f47 2023-04-04 op
169 50794f47 2023-04-04 op if (chmod(path, 0660) == -1) {
170 50794f47 2023-04-04 op log_warn("%s: chmod 0660 %s", __func__, path);
171 50794f47 2023-04-04 op close(fd);
172 50794f47 2023-04-04 op (void)unlink(path);
173 50794f47 2023-04-04 op return (-1);
174 50794f47 2023-04-04 op }
175 50794f47 2023-04-04 op
176 50794f47 2023-04-04 op if (chown(path, pw->pw_uid, pw->pw_gid) == -1) {
177 50794f47 2023-04-04 op log_warn("%s: chown %s %s", __func__, pw->pw_name, path);
178 50794f47 2023-04-04 op close(fd);
179 50794f47 2023-04-04 op (void)unlink(path);
180 50794f47 2023-04-04 op return (-1);
181 50794f47 2023-04-04 op }
182 50794f47 2023-04-04 op
183 50794f47 2023-04-04 op if (listen(fd, 5) == -1) {
184 50794f47 2023-04-04 op log_warn("%s: listen", __func__);
185 50794f47 2023-04-04 op close(fd);
186 50794f47 2023-04-04 op (void)unlink(path);
187 50794f47 2023-04-04 op return (-1);
188 50794f47 2023-04-04 op }
189 50794f47 2023-04-04 op
190 50794f47 2023-04-04 op return (fd);
191 50794f47 2023-04-04 op }
192 50794f47 2023-04-04 op
193 50794f47 2023-04-04 op static pid_t
194 50794f47 2023-04-04 op start_child(const char *argv0, const char *root, const char *user,
195 8e5ae9ac 2023-05-05 op const char *db, const char *tmpl, int debug, int verbose, int fd)
196 50794f47 2023-04-04 op {
197 8e5ae9ac 2023-05-05 op const char *argv[13];
198 50794f47 2023-04-04 op int argc = 0;
199 50794f47 2023-04-04 op pid_t pid;
200 50794f47 2023-04-04 op
201 50794f47 2023-04-04 op switch (pid = fork()) {
202 50794f47 2023-04-04 op case -1:
203 50794f47 2023-04-04 op fatal("cannot fork");
204 50794f47 2023-04-04 op case 0:
205 50794f47 2023-04-04 op break;
206 50794f47 2023-04-04 op default:
207 50794f47 2023-04-04 op close(fd);
208 50794f47 2023-04-04 op return (pid);
209 50794f47 2023-04-04 op }
210 50794f47 2023-04-04 op
211 50794f47 2023-04-04 op if (fd != 3) {
212 50794f47 2023-04-04 op if (dup2(fd, 3) == -1)
213 50794f47 2023-04-04 op fatal("cannot setup socket fd");
214 50794f47 2023-04-04 op } else if (fcntl(fd, F_SETFD, 0) == -1)
215 50794f47 2023-04-04 op fatal("cannot setup socket fd");
216 50794f47 2023-04-04 op
217 50794f47 2023-04-04 op argv[argc++] = argv0;
218 50794f47 2023-04-04 op argv[argc++] = "-S";
219 50794f47 2023-04-04 op argv[argc++] = "-p"; argv[argc++] = root;
220 8e5ae9ac 2023-05-05 op argv[argc++] = "-t"; argv[argc++] = tmpl;
221 50794f47 2023-04-04 op argv[argc++] = "-u"; argv[argc++] = user;
222 50794f47 2023-04-04 op if (debug)
223 50794f47 2023-04-04 op argv[argc++] = "-d";
224 50794f47 2023-04-04 op if (verbose--)
225 50794f47 2023-04-04 op argv[argc++] = "-v";
226 50794f47 2023-04-04 op if (verbose--)
227 50794f47 2023-04-04 op argv[argc++] = "-v";
228 50794f47 2023-04-04 op argv[argc++] = db;
229 50794f47 2023-04-04 op argv[argc++] = NULL;
230 50794f47 2023-04-04 op
231 50794f47 2023-04-04 op /* obnoxious cast */
232 50794f47 2023-04-04 op execvp(argv0, (char * const *) argv);
233 50794f47 2023-04-04 op fatal("execvp %s", argv0);
234 50794f47 2023-04-04 op }
235 50794f47 2023-04-04 op
236 50794f47 2023-04-04 op static void __dead
237 50794f47 2023-04-04 op usage(void)
238 50794f47 2023-04-04 op {
239 8e5ae9ac 2023-05-05 op fprintf(stderr, "usage: %s [-dv] [-j n] [-p path] [-s socket]"
240 8e5ae9ac 2023-05-05 op " [-t tmpldir] [-u user] [db]\n",
241 50794f47 2023-04-04 op getprogname());
242 50794f47 2023-04-04 op exit(1);
243 50794f47 2023-04-04 op }
244 50794f47 2023-04-04 op
245 50794f47 2023-04-04 op int
246 50794f47 2023-04-04 op main(int argc, char **argv)
247 50794f47 2023-04-04 op {
248 50794f47 2023-04-04 op struct stat sb;
249 50794f47 2023-04-04 op struct passwd *pw;
250 50794f47 2023-04-04 op char sockp[PATH_MAX];
251 50794f47 2023-04-04 op const char *sock = MSEARCHD_SOCK;
252 50794f47 2023-04-04 op const char *user = MSEARCHD_USER;
253 50794f47 2023-04-04 op const char *root = NULL;
254 50794f47 2023-04-04 op const char *db = MSEARCHD_DB;
255 8e5ae9ac 2023-05-05 op const char *tmpldir = MSEARCH_TMPL_DIR;
256 50794f47 2023-04-04 op const char *errstr, *cause, *argv0;
257 50794f47 2023-04-04 op pid_t pid;
258 50794f47 2023-04-04 op int ch, i, fd, ret, status, server = 0;
259 50794f47 2023-04-04 op
260 50794f47 2023-04-04 op /*
261 50794f47 2023-04-04 op * Ensure we have fds 0-2 open so that we have no issue with
262 50794f47 2023-04-04 op * calling bind_socket before daemon(3).
263 50794f47 2023-04-04 op */
264 50794f47 2023-04-04 op for (i = 0; i < 3; ++i) {
265 50794f47 2023-04-04 op if (fstat(i, &sb) == -1) {
266 50794f47 2023-04-04 op if ((fd = open("/dev/null", O_RDWR)) != -1) {
267 50794f47 2023-04-04 op if (dup2(fd, i) == -1)
268 50794f47 2023-04-04 op exit(1);
269 50794f47 2023-04-04 op if (fd > i)
270 50794f47 2023-04-04 op close(fd);
271 50794f47 2023-04-04 op } else
272 50794f47 2023-04-04 op exit(1);
273 50794f47 2023-04-04 op }
274 50794f47 2023-04-04 op }
275 50794f47 2023-04-04 op
276 50794f47 2023-04-04 op if ((argv0 = argv[0]) == NULL)
277 50794f47 2023-04-04 op argv0 = "msearchd";
278 50794f47 2023-04-04 op
279 8e5ae9ac 2023-05-05 op while ((ch = getopt(argc, argv, "dj:p:Ss:t:u:v")) != -1) {
280 50794f47 2023-04-04 op switch (ch) {
281 50794f47 2023-04-04 op case 'd':
282 50794f47 2023-04-04 op debug = 1;
283 50794f47 2023-04-04 op break;
284 50794f47 2023-04-04 op case 'j':
285 50794f47 2023-04-04 op children = strtonum(optarg, 1, MAX_CHILDREN, &errstr);
286 50794f47 2023-04-04 op if (errstr)
287 50794f47 2023-04-04 op fatalx("number of children is %s: %s",
288 50794f47 2023-04-04 op errstr, optarg);
289 50794f47 2023-04-04 op break;
290 50794f47 2023-04-04 op case 'p':
291 50794f47 2023-04-04 op root = optarg;
292 50794f47 2023-04-04 op break;
293 50794f47 2023-04-04 op case 'S':
294 50794f47 2023-04-04 op server = 1;
295 50794f47 2023-04-04 op break;
296 50794f47 2023-04-04 op case 's':
297 50794f47 2023-04-04 op sock = optarg;
298 50794f47 2023-04-04 op break;
299 8e5ae9ac 2023-05-05 op case 't':
300 8e5ae9ac 2023-05-05 op tmpldir = optarg;
301 8e5ae9ac 2023-05-05 op break;
302 50794f47 2023-04-04 op case 'u':
303 50794f47 2023-04-04 op user = optarg;
304 50794f47 2023-04-04 op break;
305 50794f47 2023-04-04 op case 'v':
306 50794f47 2023-04-04 op verbose++;
307 50794f47 2023-04-04 op break;
308 50794f47 2023-04-04 op default:
309 50794f47 2023-04-04 op usage();
310 50794f47 2023-04-04 op }
311 50794f47 2023-04-04 op }
312 50794f47 2023-04-04 op argc -= optind;
313 50794f47 2023-04-04 op argv += optind;
314 50794f47 2023-04-04 op
315 50794f47 2023-04-04 op if (argc > 0) {
316 50794f47 2023-04-04 op db = argv[0];
317 50794f47 2023-04-04 op argv++;
318 50794f47 2023-04-04 op argc--;
319 50794f47 2023-04-04 op }
320 50794f47 2023-04-04 op if (argc != 0)
321 50794f47 2023-04-04 op usage();
322 50794f47 2023-04-04 op
323 50794f47 2023-04-04 op if (geteuid())
324 50794f47 2023-04-04 op fatalx("need root privileges");
325 50794f47 2023-04-04 op
326 50794f47 2023-04-04 op pw = getpwnam(user);
327 50794f47 2023-04-04 op if (pw == NULL)
328 50794f47 2023-04-04 op fatalx("user %s not found", user);
329 50794f47 2023-04-04 op if (pw->pw_uid == 0)
330 50794f47 2023-04-04 op fatalx("cannot run as %s: must not be the superuser", user);
331 50794f47 2023-04-04 op
332 50794f47 2023-04-04 op if (root == NULL)
333 50794f47 2023-04-04 op root = pw->pw_dir;
334 2901dc0e 2023-04-04 op
335 2901dc0e 2023-04-04 op if (!debug)
336 2901dc0e 2023-04-04 op logger = &syslogger;
337 2901dc0e 2023-04-04 op
338 2901dc0e 2023-04-04 op if (!debug && !server && daemon(1, 0) == -1)
339 2901dc0e 2023-04-04 op fatal("daemon");
340 50794f47 2023-04-04 op
341 50794f47 2023-04-04 op if (!server) {
342 50794f47 2023-04-04 op sigset_t set;
343 50794f47 2023-04-04 op
344 50794f47 2023-04-04 op sigemptyset(&set);
345 50794f47 2023-04-04 op sigaddset(&set, SIGCHLD);
346 28c73ba9 2023-04-04 op sigaddset(&set, SIGINT);
347 28c73ba9 2023-04-04 op sigaddset(&set, SIGTERM);
348 50794f47 2023-04-04 op sigprocmask(SIG_BLOCK, &set, NULL);
349 50794f47 2023-04-04 op
350 50794f47 2023-04-04 op ret = snprintf(sockp, sizeof(sockp), "%s/%s", root, sock);
351 50794f47 2023-04-04 op if (ret < 0 || (size_t)ret >= sizeof(sockp))
352 50794f47 2023-04-04 op fatalx("socket path too long");
353 50794f47 2023-04-04 op if ((fd = bind_socket(sockp, pw)) == -1)
354 50794f47 2023-04-04 op fatalx("failed to open socket %s", sock);
355 50794f47 2023-04-04 op for (i = 0; i < children; ++i) {
356 50794f47 2023-04-04 op int d;
357 50794f47 2023-04-04 op
358 50794f47 2023-04-04 op if ((d = dup(fd)) == -1)
359 50794f47 2023-04-04 op fatalx("dup");
360 8e5ae9ac 2023-05-05 op pids[i] = start_child(argv0, root, user, db, tmpldir,
361 8e5ae9ac 2023-05-05 op debug, verbose, d);
362 50794f47 2023-04-04 op log_debug("forking child %d (pid %lld)", i,
363 50794f47 2023-04-04 op (long long)pids[i]);
364 50794f47 2023-04-04 op }
365 50794f47 2023-04-04 op
366 28c73ba9 2023-04-04 op signal(SIGINT, sighdlr);
367 28c73ba9 2023-04-04 op signal(SIGTERM, sighdlr);
368 28c73ba9 2023-04-04 op signal(SIGCHLD, sighdlr);
369 50794f47 2023-04-04 op signal(SIGHUP, SIG_IGN);
370 50794f47 2023-04-04 op
371 50794f47 2023-04-04 op sigprocmask(SIG_UNBLOCK, &set, NULL);
372 8e5ae9ac 2023-05-05 op } else {
373 8e5ae9ac 2023-05-05 op load_tmpl(&tmpl_head, tmpldir, "head.html");
374 8e5ae9ac 2023-05-05 op load_tmpl(&tmpl_search, tmpldir, "search.html");
375 8e5ae9ac 2023-05-05 op load_tmpl(&tmpl_search_header, tmpldir, "search-header.html");
376 8e5ae9ac 2023-05-05 op load_tmpl(&tmpl_foot, tmpldir, "foot.html");
377 ab1569ee 2023-05-06 op
378 ab1569ee 2023-05-06 op setproctitle("server");
379 50794f47 2023-04-04 op }
380 50794f47 2023-04-04 op
381 50794f47 2023-04-04 op if (chroot(root) == -1)
382 50794f47 2023-04-04 op fatal("chroot %s", root);
383 50794f47 2023-04-04 op if (chdir("/") == -1)
384 50794f47 2023-04-04 op fatal("chdir /");
385 50794f47 2023-04-04 op
386 50794f47 2023-04-04 op if (setgroups(1, &pw->pw_gid) == -1 ||
387 50794f47 2023-04-04 op setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
388 50794f47 2023-04-04 op setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
389 50794f47 2023-04-04 op fatal("failed to drop privileges");
390 50794f47 2023-04-04 op
391 50794f47 2023-04-04 op if (server)
392 50794f47 2023-04-04 op return (server_main(db));
393 50794f47 2023-04-04 op
394 50794f47 2023-04-04 op if (pledge("stdio proc", NULL) == -1)
395 50794f47 2023-04-04 op fatal("pledge");
396 50794f47 2023-04-04 op
397 50794f47 2023-04-04 op for (;;) {
398 50794f47 2023-04-04 op do {
399 50794f47 2023-04-04 op pid = waitpid(WAIT_ANY, &status, 0);
400 50794f47 2023-04-04 op } while (pid != -1 || errno == EINTR);
401 50794f47 2023-04-04 op
402 50794f47 2023-04-04 op if (pid == -1) {
403 50794f47 2023-04-04 op if (errno == ECHILD)
404 50794f47 2023-04-04 op break;
405 50794f47 2023-04-04 op fatal("waitpid");
406 50794f47 2023-04-04 op }
407 50794f47 2023-04-04 op
408 50794f47 2023-04-04 op if (WIFSIGNALED(status))
409 50794f47 2023-04-04 op cause = "was terminated";
410 50794f47 2023-04-04 op else if (WIFEXITED(status)) {
411 50794f47 2023-04-04 op if (WEXITSTATUS(status) != 0)
412 50794f47 2023-04-04 op cause = "exited abnormally";
413 50794f47 2023-04-04 op else
414 50794f47 2023-04-04 op cause = "exited successfully";
415 50794f47 2023-04-04 op } else
416 50794f47 2023-04-04 op cause = "died";
417 50794f47 2023-04-04 op
418 50794f47 2023-04-04 op log_warnx("child process %lld %s", (long long)pid, cause);
419 50794f47 2023-04-04 op }
420 50794f47 2023-04-04 op
421 50794f47 2023-04-04 op return (1);
422 50794f47 2023-04-04 op }
423 50794f47 2023-04-04 op
424 50794f47 2023-04-04 op __dead void
425 50794f47 2023-04-04 op srch_syslog_fatal(int eval, const char *fmt, ...)
426 50794f47 2023-04-04 op {
427 50794f47 2023-04-04 op static char s[BUFSIZ];
428 50794f47 2023-04-04 op va_list ap;
429 50794f47 2023-04-04 op int r, save_errno;
430 50794f47 2023-04-04 op
431 50794f47 2023-04-04 op save_errno = errno;
432 50794f47 2023-04-04 op
433 50794f47 2023-04-04 op va_start(ap, fmt);
434 50794f47 2023-04-04 op r = vsnprintf(s, sizeof(s), fmt, ap);
435 50794f47 2023-04-04 op va_end(ap);
436 50794f47 2023-04-04 op
437 50794f47 2023-04-04 op errno = save_errno;
438 50794f47 2023-04-04 op
439 50794f47 2023-04-04 op if (r > 0 && (size_t)r <= sizeof(s))
440 50794f47 2023-04-04 op syslog(LOG_DAEMON|LOG_CRIT, "%s: %s", s, strerror(errno));
441 50794f47 2023-04-04 op
442 50794f47 2023-04-04 op exit(eval);
443 50794f47 2023-04-04 op }
444 50794f47 2023-04-04 op
445 50794f47 2023-04-04 op __dead void
446 50794f47 2023-04-04 op srch_syslog_fatalx(int eval, const char *fmt, ...)
447 50794f47 2023-04-04 op {
448 50794f47 2023-04-04 op va_list ap;
449 50794f47 2023-04-04 op
450 50794f47 2023-04-04 op va_start(ap, fmt);
451 50794f47 2023-04-04 op vsyslog(LOG_DAEMON|LOG_CRIT, fmt, ap);
452 50794f47 2023-04-04 op va_end(ap);
453 50794f47 2023-04-04 op
454 50794f47 2023-04-04 op exit(eval);
455 50794f47 2023-04-04 op }
456 50794f47 2023-04-04 op
457 50794f47 2023-04-04 op void
458 50794f47 2023-04-04 op srch_syslog_warn(const char *fmt, ...)
459 50794f47 2023-04-04 op {
460 50794f47 2023-04-04 op static char s[BUFSIZ];
461 50794f47 2023-04-04 op va_list ap;
462 50794f47 2023-04-04 op int r, save_errno;
463 50794f47 2023-04-04 op
464 50794f47 2023-04-04 op save_errno = errno;
465 50794f47 2023-04-04 op
466 50794f47 2023-04-04 op va_start(ap, fmt);
467 50794f47 2023-04-04 op r = vsnprintf(s, sizeof(s), fmt, ap);
468 50794f47 2023-04-04 op va_end(ap);
469 50794f47 2023-04-04 op
470 50794f47 2023-04-04 op errno = save_errno;
471 50794f47 2023-04-04 op
472 cae98100 2023-04-04 op if (r > 0 && (size_t)r < sizeof(s))
473 50794f47 2023-04-04 op syslog(LOG_DAEMON|LOG_ERR, "%s: %s", s, strerror(errno));
474 50794f47 2023-04-04 op
475 50794f47 2023-04-04 op errno = save_errno;
476 50794f47 2023-04-04 op }
477 50794f47 2023-04-04 op
478 50794f47 2023-04-04 op void
479 50794f47 2023-04-04 op srch_syslog_warnx(const char *fmt, ...)
480 50794f47 2023-04-04 op {
481 50794f47 2023-04-04 op va_list ap;
482 50794f47 2023-04-04 op int save_errno;
483 50794f47 2023-04-04 op
484 50794f47 2023-04-04 op save_errno = errno;
485 50794f47 2023-04-04 op va_start(ap, fmt);
486 50794f47 2023-04-04 op vsyslog(LOG_DAEMON|LOG_ERR, fmt, ap);
487 50794f47 2023-04-04 op va_end(ap);
488 50794f47 2023-04-04 op errno = save_errno;
489 50794f47 2023-04-04 op }
490 50794f47 2023-04-04 op
491 50794f47 2023-04-04 op void
492 50794f47 2023-04-04 op srch_syslog_info(const char *fmt, ...)
493 50794f47 2023-04-04 op {
494 50794f47 2023-04-04 op va_list ap;
495 50794f47 2023-04-04 op int save_errno;
496 50794f47 2023-04-04 op
497 50794f47 2023-04-04 op if (verbose < 1)
498 50794f47 2023-04-04 op return;
499 50794f47 2023-04-04 op
500 50794f47 2023-04-04 op save_errno = errno;
501 50794f47 2023-04-04 op va_start(ap, fmt);
502 50794f47 2023-04-04 op vsyslog(LOG_DAEMON|LOG_INFO, fmt, ap);
503 50794f47 2023-04-04 op va_end(ap);
504 50794f47 2023-04-04 op errno = save_errno;
505 50794f47 2023-04-04 op }
506 50794f47 2023-04-04 op
507 50794f47 2023-04-04 op void
508 50794f47 2023-04-04 op srch_syslog_debug(const char *fmt, ...)
509 50794f47 2023-04-04 op {
510 50794f47 2023-04-04 op va_list ap;
511 50794f47 2023-04-04 op int save_errno;
512 50794f47 2023-04-04 op
513 50794f47 2023-04-04 op if (verbose < 2)
514 50794f47 2023-04-04 op return;
515 50794f47 2023-04-04 op
516 50794f47 2023-04-04 op save_errno = errno;
517 50794f47 2023-04-04 op va_start(ap, fmt);
518 50794f47 2023-04-04 op vsyslog(LOG_DAEMON|LOG_DEBUG, fmt, ap);
519 50794f47 2023-04-04 op va_end(ap);
520 50794f47 2023-04-04 op errno = save_errno;
521 50794f47 2023-04-04 op }