Blame


1 a596b957 2022-07-14 tracey /*
2 a596b957 2022-07-14 tracey * Copyright (c) 2016, 2019, 2020-2021 Tracey Emery <tracey@traceyemery.net>
3 a596b957 2022-07-14 tracey * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
4 a596b957 2022-07-14 tracey *
5 a596b957 2022-07-14 tracey * Permission to use, copy, modify, and distribute this software for any
6 a596b957 2022-07-14 tracey * purpose with or without fee is hereby granted, provided that the above
7 a596b957 2022-07-14 tracey * copyright notice and this permission notice appear in all copies.
8 a596b957 2022-07-14 tracey *
9 a596b957 2022-07-14 tracey * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 a596b957 2022-07-14 tracey * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 a596b957 2022-07-14 tracey * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 a596b957 2022-07-14 tracey * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 a596b957 2022-07-14 tracey * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 a596b957 2022-07-14 tracey * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 a596b957 2022-07-14 tracey * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 a596b957 2022-07-14 tracey */
17 a596b957 2022-07-14 tracey
18 a596b957 2022-07-14 tracey #include <sys/param.h>
19 a596b957 2022-07-14 tracey #include <sys/queue.h>
20 a596b957 2022-07-14 tracey #include <sys/socket.h>
21 a596b957 2022-07-14 tracey #include <sys/wait.h>
22 a596b957 2022-07-14 tracey
23 a596b957 2022-07-14 tracey #include <net/if.h>
24 a596b957 2022-07-14 tracey #include <netinet/in.h>
25 a596b957 2022-07-14 tracey
26 a596b957 2022-07-14 tracey #include <stdio.h>
27 a596b957 2022-07-14 tracey #include <stdlib.h>
28 a596b957 2022-07-14 tracey #include <string.h>
29 a596b957 2022-07-14 tracey #include <termios.h>
30 a596b957 2022-07-14 tracey #include <err.h>
31 a596b957 2022-07-14 tracey #include <errno.h>
32 a596b957 2022-07-14 tracey #include <event.h>
33 a596b957 2022-07-14 tracey #include <fcntl.h>
34 a596b957 2022-07-14 tracey #include <imsg.h>
35 a596b957 2022-07-14 tracey #include <pwd.h>
36 a596b957 2022-07-14 tracey #include <signal.h>
37 a596b957 2022-07-14 tracey #include <syslog.h>
38 a596b957 2022-07-14 tracey #include <unistd.h>
39 a596b957 2022-07-14 tracey #include <ctype.h>
40 a596b957 2022-07-14 tracey #include <util.h>
41 a596b957 2022-07-14 tracey
42 a596b957 2022-07-14 tracey #include "got_opentemp.h"
43 df2d3cd2 2023-03-11 op #include "got_reference.h"
44 a596b957 2022-07-14 tracey
45 a596b957 2022-07-14 tracey #include "gotwebd.h"
46 1220d7ea 2024-05-21 op #include "log.h"
47 a596b957 2022-07-14 tracey
48 a596b957 2022-07-14 tracey __dead void usage(void);
49 a596b957 2022-07-14 tracey
50 a596b957 2022-07-14 tracey int main(int, char **);
51 a596b957 2022-07-14 tracey int gotwebd_configure(struct gotwebd *);
52 a596b957 2022-07-14 tracey void gotwebd_configure_done(struct gotwebd *);
53 a596b957 2022-07-14 tracey void gotwebd_sighdlr(int sig, short event, void *arg);
54 a596b957 2022-07-14 tracey void gotwebd_shutdown(void);
55 26678add 2023-11-16 op void gotwebd_dispatch_sockets(int, short, void *);
56 a596b957 2022-07-14 tracey
57 a596b957 2022-07-14 tracey struct gotwebd *gotwebd_env;
58 a596b957 2022-07-14 tracey
59 26678add 2023-11-16 op void
60 26678add 2023-11-16 op imsg_event_add(struct imsgev *iev)
61 26678add 2023-11-16 op {
62 26678add 2023-11-16 op if (iev->handler == NULL) {
63 26678add 2023-11-16 op imsg_flush(&iev->ibuf);
64 26678add 2023-11-16 op return;
65 26678add 2023-11-16 op }
66 a596b957 2022-07-14 tracey
67 26678add 2023-11-16 op iev->events = EV_READ;
68 26678add 2023-11-16 op if (iev->ibuf.w.queued)
69 26678add 2023-11-16 op iev->events |= EV_WRITE;
70 26678add 2023-11-16 op
71 26678add 2023-11-16 op event_del(&iev->ev);
72 26678add 2023-11-16 op event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
73 26678add 2023-11-16 op event_add(&iev->ev, NULL);
74 26678add 2023-11-16 op }
75 26678add 2023-11-16 op
76 a596b957 2022-07-14 tracey int
77 26678add 2023-11-16 op imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
78 26678add 2023-11-16 op pid_t pid, int fd, const void *data, uint16_t datalen)
79 a596b957 2022-07-14 tracey {
80 26678add 2023-11-16 op int ret;
81 a596b957 2022-07-14 tracey
82 26678add 2023-11-16 op ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen);
83 26678add 2023-11-16 op if (ret == -1)
84 26678add 2023-11-16 op return (ret);
85 26678add 2023-11-16 op imsg_event_add(iev);
86 26678add 2023-11-16 op return (ret);
87 26678add 2023-11-16 op }
88 26678add 2023-11-16 op
89 26678add 2023-11-16 op int
90 26678add 2023-11-16 op main_compose_sockets(struct gotwebd *env, uint32_t type, int fd,
91 26678add 2023-11-16 op const void *data, uint16_t len)
92 26678add 2023-11-16 op {
93 26678add 2023-11-16 op size_t i;
94 26678add 2023-11-16 op int ret, d;
95 26678add 2023-11-16 op
96 26678add 2023-11-16 op for (i = 0; i < env->nserver; ++i) {
97 26678add 2023-11-16 op d = -1;
98 26678add 2023-11-16 op if (fd != -1 && (d = dup(fd)) == -1)
99 b2ce8090 2023-11-16 op goto err;
100 26678add 2023-11-16 op
101 26678add 2023-11-16 op ret = imsg_compose_event(&env->iev_server[i], type, 0, -1,
102 26678add 2023-11-16 op d, data, len);
103 26678add 2023-11-16 op if (ret == -1)
104 b2ce8090 2023-11-16 op goto err;
105 26678add 2023-11-16 op
106 26678add 2023-11-16 op /* prevent fd exhaustion */
107 26678add 2023-11-16 op if (d != -1) {
108 26678add 2023-11-16 op do {
109 26678add 2023-11-16 op ret = imsg_flush(&env->iev_server[i].ibuf);
110 26678add 2023-11-16 op } while (ret == -1 && errno == EAGAIN);
111 26678add 2023-11-16 op if (ret == -1)
112 b2ce8090 2023-11-16 op goto err;
113 26678add 2023-11-16 op imsg_event_add(&env->iev_server[i]);
114 26678add 2023-11-16 op }
115 a596b957 2022-07-14 tracey }
116 a596b957 2022-07-14 tracey
117 26678add 2023-11-16 op if (fd != -1)
118 26678add 2023-11-16 op close(fd);
119 26678add 2023-11-16 op return 0;
120 b2ce8090 2023-11-16 op
121 b2ce8090 2023-11-16 op err:
122 b2ce8090 2023-11-16 op if (fd != -1)
123 b2ce8090 2023-11-16 op close(fd);
124 b2ce8090 2023-11-16 op return -1;
125 a596b957 2022-07-14 tracey }
126 a596b957 2022-07-14 tracey
127 26678add 2023-11-16 op int
128 26678add 2023-11-16 op sockets_compose_main(struct gotwebd *env, uint32_t type, const void *d,
129 26678add 2023-11-16 op uint16_t len)
130 26678add 2023-11-16 op {
131 26678add 2023-11-16 op return (imsg_compose_event(env->iev_parent, type, 0, -1, -1, d, len));
132 26678add 2023-11-16 op }
133 26678add 2023-11-16 op
134 a596b957 2022-07-14 tracey void
135 26678add 2023-11-16 op gotwebd_dispatch_sockets(int fd, short event, void *arg)
136 26678add 2023-11-16 op {
137 26678add 2023-11-16 op struct imsgev *iev = arg;
138 26678add 2023-11-16 op struct imsgbuf *ibuf;
139 26678add 2023-11-16 op struct imsg imsg;
140 26678add 2023-11-16 op struct gotwebd *env = gotwebd_env;
141 26678add 2023-11-16 op ssize_t n;
142 26678add 2023-11-16 op int shut = 0;
143 26678add 2023-11-16 op
144 26678add 2023-11-16 op ibuf = &iev->ibuf;
145 26678add 2023-11-16 op
146 26678add 2023-11-16 op if (event & EV_READ) {
147 26678add 2023-11-16 op if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
148 26678add 2023-11-16 op fatal("imsg_read error");
149 26678add 2023-11-16 op if (n == 0) /* Connection closed */
150 26678add 2023-11-16 op shut = 1;
151 26678add 2023-11-16 op }
152 26678add 2023-11-16 op if (event & EV_WRITE) {
153 26678add 2023-11-16 op if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
154 26678add 2023-11-16 op fatal("msgbuf_write");
155 26678add 2023-11-16 op if (n == 0) /* Connection closed */
156 26678add 2023-11-16 op shut = 1;
157 26678add 2023-11-16 op }
158 26678add 2023-11-16 op
159 26678add 2023-11-16 op for (;;) {
160 26678add 2023-11-16 op if ((n = imsg_get(ibuf, &imsg)) == -1)
161 26678add 2023-11-16 op fatal("imsg_get");
162 26678add 2023-11-16 op if (n == 0) /* No more messages. */
163 26678add 2023-11-16 op break;
164 26678add 2023-11-16 op
165 26678add 2023-11-16 op switch (imsg.hdr.type) {
166 26678add 2023-11-16 op case IMSG_CFG_DONE:
167 26678add 2023-11-16 op gotwebd_configure_done(env);
168 26678add 2023-11-16 op break;
169 26678add 2023-11-16 op default:
170 26678add 2023-11-16 op fatalx("%s: unknown imsg type %d", __func__,
171 26678add 2023-11-16 op imsg.hdr.type);
172 26678add 2023-11-16 op }
173 26678add 2023-11-16 op
174 26678add 2023-11-16 op imsg_free(&imsg);
175 26678add 2023-11-16 op }
176 26678add 2023-11-16 op
177 26678add 2023-11-16 op if (!shut)
178 26678add 2023-11-16 op imsg_event_add(iev);
179 26678add 2023-11-16 op else {
180 26678add 2023-11-16 op /* This pipe is dead. Remove its event handler */
181 26678add 2023-11-16 op event_del(&iev->ev);
182 26678add 2023-11-16 op event_loopexit(NULL);
183 26678add 2023-11-16 op }
184 26678add 2023-11-16 op }
185 26678add 2023-11-16 op
186 26678add 2023-11-16 op void
187 a596b957 2022-07-14 tracey gotwebd_sighdlr(int sig, short event, void *arg)
188 a596b957 2022-07-14 tracey {
189 a596b957 2022-07-14 tracey /* struct privsep *ps = arg; */
190 a596b957 2022-07-14 tracey
191 a596b957 2022-07-14 tracey switch (sig) {
192 a596b957 2022-07-14 tracey case SIGHUP:
193 a596b957 2022-07-14 tracey log_info("%s: ignoring SIGHUP", __func__);
194 a596b957 2022-07-14 tracey break;
195 a596b957 2022-07-14 tracey case SIGPIPE:
196 a596b957 2022-07-14 tracey log_info("%s: ignoring SIGPIPE", __func__);
197 a596b957 2022-07-14 tracey break;
198 a596b957 2022-07-14 tracey case SIGUSR1:
199 a596b957 2022-07-14 tracey log_info("%s: ignoring SIGUSR1", __func__);
200 a596b957 2022-07-14 tracey break;
201 a596b957 2022-07-14 tracey case SIGTERM:
202 a596b957 2022-07-14 tracey case SIGINT:
203 a596b957 2022-07-14 tracey gotwebd_shutdown();
204 a596b957 2022-07-14 tracey break;
205 a596b957 2022-07-14 tracey default:
206 a596b957 2022-07-14 tracey fatalx("unexpected signal");
207 a596b957 2022-07-14 tracey }
208 a596b957 2022-07-14 tracey }
209 a596b957 2022-07-14 tracey
210 26678add 2023-11-16 op static int
211 26678add 2023-11-16 op spawn_socket_process(struct gotwebd *env, const char *argv0, int n)
212 26678add 2023-11-16 op {
213 c89c70b6 2024-05-27 op const char *argv[6];
214 26678add 2023-11-16 op int argc = 0;
215 26678add 2023-11-16 op int p[2];
216 26678add 2023-11-16 op pid_t pid;
217 26678add 2023-11-16 op
218 26678add 2023-11-16 op if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) == -1)
219 26678add 2023-11-16 op fatal("socketpair");
220 26678add 2023-11-16 op
221 26678add 2023-11-16 op switch (pid = fork()) {
222 26678add 2023-11-16 op case -1:
223 26678add 2023-11-16 op fatal("fork");
224 26678add 2023-11-16 op case 0: /* child */
225 26678add 2023-11-16 op break;
226 26678add 2023-11-16 op default: /* parent */
227 26678add 2023-11-16 op close(p[0]);
228 26678add 2023-11-16 op imsg_init(&env->iev_server[n].ibuf, p[1]);
229 26678add 2023-11-16 op env->iev_server[n].handler = gotwebd_dispatch_sockets;
230 26678add 2023-11-16 op env->iev_server[n].data = &env->iev_server[n];
231 26678add 2023-11-16 op event_set(&env->iev_server[n].ev, p[1], EV_READ,
232 26678add 2023-11-16 op gotwebd_dispatch_sockets, &env->iev_server[n]);
233 26678add 2023-11-16 op event_add(&env->iev_server[n].ev, NULL);
234 26678add 2023-11-16 op return 0;
235 26678add 2023-11-16 op }
236 26678add 2023-11-16 op
237 26678add 2023-11-16 op close(p[1]);
238 26678add 2023-11-16 op
239 26678add 2023-11-16 op argv[argc++] = argv0;
240 26678add 2023-11-16 op argv[argc++] = "-S";
241 26678add 2023-11-16 op if (env->gotwebd_debug)
242 26678add 2023-11-16 op argv[argc++] = "-d";
243 c89c70b6 2024-05-27 op if (env->gotwebd_verbose > 0)
244 26678add 2023-11-16 op argv[argc++] = "-v";
245 c89c70b6 2024-05-27 op if (env->gotwebd_verbose > 1)
246 c89c70b6 2024-05-27 op argv[argc++] = "-v";
247 26678add 2023-11-16 op argv[argc] = NULL;
248 26678add 2023-11-16 op
249 9ec8edf7 2023-11-16 op if (p[0] != GOTWEBD_SOCK_FILENO) {
250 9ec8edf7 2023-11-16 op if (dup2(p[0], GOTWEBD_SOCK_FILENO) == -1)
251 26678add 2023-11-16 op fatal("dup2");
252 26678add 2023-11-16 op } else if (fcntl(p[0], F_SETFD, 0) == -1)
253 26678add 2023-11-16 op fatal("fcntl");
254 26678add 2023-11-16 op
255 26678add 2023-11-16 op /* obnoxious cast */
256 26678add 2023-11-16 op execvp(argv0, (char * const *)argv);
257 26678add 2023-11-16 op fatal("execvp %s", argv0);
258 26678add 2023-11-16 op }
259 26678add 2023-11-16 op
260 a596b957 2022-07-14 tracey __dead void
261 a596b957 2022-07-14 tracey usage(void)
262 a596b957 2022-07-14 tracey {
263 a596b957 2022-07-14 tracey fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
264 a596b957 2022-07-14 tracey getprogname());
265 a596b957 2022-07-14 tracey exit(1);
266 a596b957 2022-07-14 tracey }
267 a596b957 2022-07-14 tracey
268 a596b957 2022-07-14 tracey int
269 a596b957 2022-07-14 tracey main(int argc, char **argv)
270 a596b957 2022-07-14 tracey {
271 26678add 2023-11-16 op struct event sigint, sigterm, sighup, sigpipe, sigusr1;
272 26678add 2023-11-16 op struct gotwebd *env;
273 26678add 2023-11-16 op struct passwd *pw;
274 26678add 2023-11-16 op int ch, i;
275 26678add 2023-11-16 op int no_action = 0;
276 26678add 2023-11-16 op int server_proc = 0;
277 26678add 2023-11-16 op const char *conffile = GOTWEBD_CONF;
278 9bc2ee80 2024-05-21 op const char *username = GOTWEBD_DEFAULT_USER;
279 26678add 2023-11-16 op const char *argv0;
280 a596b957 2022-07-14 tracey
281 26678add 2023-11-16 op if ((argv0 = argv[0]) == NULL)
282 26678add 2023-11-16 op argv0 = "gotwebd";
283 ba5f8ecf 2023-11-16 op
284 ba5f8ecf 2023-11-16 op /* log to stderr until daemonized */
285 ba5f8ecf 2023-11-16 op log_init(1, LOG_DAEMON);
286 26678add 2023-11-16 op
287 a596b957 2022-07-14 tracey env = calloc(1, sizeof(*env));
288 a596b957 2022-07-14 tracey if (env == NULL)
289 a596b957 2022-07-14 tracey fatal("%s: calloc", __func__);
290 26678add 2023-11-16 op config_init(env);
291 5abbba2d 2023-11-15 op
292 26678add 2023-11-16 op while ((ch = getopt(argc, argv, "D:df:nSv")) != -1) {
293 a596b957 2022-07-14 tracey switch (ch) {
294 a596b957 2022-07-14 tracey case 'D':
295 a596b957 2022-07-14 tracey if (cmdline_symset(optarg) < 0)
296 a596b957 2022-07-14 tracey log_warnx("could not parse macro definition %s",
297 a596b957 2022-07-14 tracey optarg);
298 a596b957 2022-07-14 tracey break;
299 a596b957 2022-07-14 tracey case 'd':
300 26678add 2023-11-16 op env->gotwebd_debug = 1;
301 a596b957 2022-07-14 tracey break;
302 a596b957 2022-07-14 tracey case 'f':
303 a596b957 2022-07-14 tracey conffile = optarg;
304 a596b957 2022-07-14 tracey break;
305 a596b957 2022-07-14 tracey case 'n':
306 26678add 2023-11-16 op no_action = 1;
307 a596b957 2022-07-14 tracey break;
308 26678add 2023-11-16 op case 'S':
309 26678add 2023-11-16 op server_proc = 1;
310 a596b957 2022-07-14 tracey break;
311 6f319063 2022-10-27 stsp case 'v':
312 c89c70b6 2024-05-27 op if (env->gotwebd_verbose < 3)
313 c89c70b6 2024-05-27 op env->gotwebd_verbose++;
314 a596b957 2022-07-14 tracey break;
315 a596b957 2022-07-14 tracey default:
316 a596b957 2022-07-14 tracey usage();
317 a596b957 2022-07-14 tracey }
318 a596b957 2022-07-14 tracey }
319 a596b957 2022-07-14 tracey
320 a596b957 2022-07-14 tracey argc -= optind;
321 a596b957 2022-07-14 tracey if (argc > 0)
322 a596b957 2022-07-14 tracey usage();
323 a596b957 2022-07-14 tracey
324 a596b957 2022-07-14 tracey gotwebd_env = env;
325 a596b957 2022-07-14 tracey env->gotwebd_conffile = conffile;
326 a596b957 2022-07-14 tracey
327 a596b957 2022-07-14 tracey if (parse_config(env->gotwebd_conffile, env) == -1)
328 a596b957 2022-07-14 tracey exit(1);
329 a596b957 2022-07-14 tracey
330 26678add 2023-11-16 op if (no_action) {
331 26678add 2023-11-16 op fprintf(stderr, "configuration OK\n");
332 26678add 2023-11-16 op exit(0);
333 26678add 2023-11-16 op }
334 a596b957 2022-07-14 tracey
335 a596b957 2022-07-14 tracey /* check for root privileges */
336 26678add 2023-11-16 op if (geteuid())
337 26678add 2023-11-16 op fatalx("need root privileges");
338 a596b957 2022-07-14 tracey
339 9bc2ee80 2024-05-21 op if (env->user)
340 9bc2ee80 2024-05-21 op username = env->user;
341 9bc2ee80 2024-05-21 op pw = getpwnam(username);
342 26678add 2023-11-16 op if (pw == NULL)
343 9bc2ee80 2024-05-21 op fatalx("unknown user %s", username);
344 26678add 2023-11-16 op env->pw = pw;
345 a596b957 2022-07-14 tracey
346 a596b957 2022-07-14 tracey log_init(env->gotwebd_debug, LOG_DAEMON);
347 a596b957 2022-07-14 tracey log_setverbose(env->gotwebd_verbose);
348 a596b957 2022-07-14 tracey
349 26678add 2023-11-16 op if (server_proc) {
350 26678add 2023-11-16 op setproctitle("sockets");
351 26678add 2023-11-16 op log_procinit("sockets");
352 a596b957 2022-07-14 tracey
353 60594467 2023-12-08 stsp if (chroot(env->httpd_chroot) == -1)
354 60594467 2023-12-08 stsp fatal("chroot %s", env->httpd_chroot);
355 26678add 2023-11-16 op if (chdir("/") == -1)
356 26678add 2023-11-16 op fatal("chdir /");
357 26678add 2023-11-16 op if (setgroups(1, &pw->pw_gid) == -1 ||
358 26678add 2023-11-16 op setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
359 26678add 2023-11-16 op setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
360 26678add 2023-11-16 op fatal("failed to drop privileges");
361 a596b957 2022-07-14 tracey
362 9ec8edf7 2023-11-16 op sockets(env, GOTWEBD_SOCK_FILENO);
363 26678add 2023-11-16 op return 1;
364 26678add 2023-11-16 op }
365 a596b957 2022-07-14 tracey
366 4056db63 2023-11-16 op if (!env->gotwebd_debug && daemon(1, 0) == -1)
367 26678add 2023-11-16 op fatal("daemon");
368 a596b957 2022-07-14 tracey
369 a596b957 2022-07-14 tracey event_init();
370 a596b957 2022-07-14 tracey
371 26678add 2023-11-16 op env->nserver = env->prefork_gotwebd;
372 26678add 2023-11-16 op env->iev_server = calloc(env->nserver, sizeof(*env->iev_server));
373 26678add 2023-11-16 op if (env->iev_server == NULL)
374 26678add 2023-11-16 op fatal("calloc");
375 a596b957 2022-07-14 tracey
376 26678add 2023-11-16 op for (i = 0; i < env->nserver; ++i) {
377 26678add 2023-11-16 op if (spawn_socket_process(env, argv0, i) == -1)
378 26678add 2023-11-16 op fatal("spawn_socket_process");
379 26678add 2023-11-16 op }
380 a596b957 2022-07-14 tracey
381 4056db63 2023-11-16 op if (chdir("/") == -1)
382 4056db63 2023-11-16 op fatal("chdir /");
383 4056db63 2023-11-16 op
384 26678add 2023-11-16 op log_procinit("gotwebd");
385 a596b957 2022-07-14 tracey
386 26678add 2023-11-16 op log_info("%s startup", getprogname());
387 26678add 2023-11-16 op
388 26678add 2023-11-16 op signal_set(&sigint, SIGINT, gotwebd_sighdlr, env);
389 26678add 2023-11-16 op signal_set(&sigterm, SIGTERM, gotwebd_sighdlr, env);
390 26678add 2023-11-16 op signal_set(&sighup, SIGHUP, gotwebd_sighdlr, env);
391 26678add 2023-11-16 op signal_set(&sigpipe, SIGPIPE, gotwebd_sighdlr, env);
392 26678add 2023-11-16 op signal_set(&sigusr1, SIGUSR1, gotwebd_sighdlr, env);
393 26678add 2023-11-16 op
394 26678add 2023-11-16 op signal_add(&sigint, NULL);
395 26678add 2023-11-16 op signal_add(&sigterm, NULL);
396 26678add 2023-11-16 op signal_add(&sighup, NULL);
397 26678add 2023-11-16 op signal_add(&sigpipe, NULL);
398 26678add 2023-11-16 op signal_add(&sigusr1, NULL);
399 26678add 2023-11-16 op
400 a596b957 2022-07-14 tracey if (gotwebd_configure(env) == -1)
401 a596b957 2022-07-14 tracey fatalx("configuration failed");
402 a596b957 2022-07-14 tracey
403 a596b957 2022-07-14 tracey #ifdef PROFILE
404 a596b957 2022-07-14 tracey if (unveil("gmon.out", "rwc") != 0)
405 a596b957 2022-07-14 tracey err(1, "gmon.out");
406 a596b957 2022-07-14 tracey #endif
407 a596b957 2022-07-14 tracey
408 6fe3b58a 2023-11-14 stsp if (unveil(env->httpd_chroot, "r") == -1)
409 a596b957 2022-07-14 tracey err(1, "unveil");
410 a596b957 2022-07-14 tracey
411 a596b957 2022-07-14 tracey if (unveil(GOTWEBD_CONF, "r") == -1)
412 a596b957 2022-07-14 tracey err(1, "unveil");
413 a596b957 2022-07-14 tracey
414 a596b957 2022-07-14 tracey if (unveil(NULL, NULL) != 0)
415 a596b957 2022-07-14 tracey err(1, "unveil");
416 a596b957 2022-07-14 tracey
417 a596b957 2022-07-14 tracey #ifndef PROFILE
418 63c6b10f 2023-11-14 stsp if (pledge("stdio", NULL) == -1)
419 a596b957 2022-07-14 tracey err(1, "pledge");
420 a596b957 2022-07-14 tracey #endif
421 a596b957 2022-07-14 tracey
422 a596b957 2022-07-14 tracey event_dispatch();
423 a596b957 2022-07-14 tracey
424 a596b957 2022-07-14 tracey log_debug("%s gotwebd exiting", getprogname());
425 a596b957 2022-07-14 tracey
426 a596b957 2022-07-14 tracey return (0);
427 a596b957 2022-07-14 tracey }
428 a596b957 2022-07-14 tracey
429 a596b957 2022-07-14 tracey int
430 a596b957 2022-07-14 tracey gotwebd_configure(struct gotwebd *env)
431 a596b957 2022-07-14 tracey {
432 a596b957 2022-07-14 tracey struct server *srv;
433 a596b957 2022-07-14 tracey struct socket *sock;
434 a596b957 2022-07-14 tracey
435 a596b957 2022-07-14 tracey /* gotweb need to reload its config. */
436 a596b957 2022-07-14 tracey env->gotwebd_reload = env->prefork_gotwebd;
437 a596b957 2022-07-14 tracey
438 a596b957 2022-07-14 tracey /* send our gotweb servers */
439 2ad48e9a 2022-08-16 stsp TAILQ_FOREACH(srv, &env->servers, entry) {
440 a596b957 2022-07-14 tracey if (config_setserver(env, srv) == -1)
441 a596b957 2022-07-14 tracey fatalx("%s: send server error", __func__);
442 a596b957 2022-07-14 tracey }
443 a596b957 2022-07-14 tracey
444 a596b957 2022-07-14 tracey /* send our sockets */
445 2ad48e9a 2022-08-16 stsp TAILQ_FOREACH(sock, &env->sockets, entry) {
446 a596b957 2022-07-14 tracey if (config_setsock(env, sock) == -1)
447 a596b957 2022-07-14 tracey fatalx("%s: send socket error", __func__);
448 a596b957 2022-07-14 tracey }
449 2a83fef7 2024-05-27 op
450 2a83fef7 2024-05-27 op /* send the temp files */
451 2a83fef7 2024-05-27 op if (config_setfd(env) == -1)
452 2a83fef7 2024-05-27 op fatalx("%s: send priv_fd error", __func__);
453 a596b957 2022-07-14 tracey
454 26678add 2023-11-16 op if (main_compose_sockets(env, IMSG_CFG_DONE, -1, NULL, 0) == -1)
455 26678add 2023-11-16 op fatal("main_compose_sockets IMSG_CFG_DONE");
456 a596b957 2022-07-14 tracey
457 a596b957 2022-07-14 tracey return (0);
458 a596b957 2022-07-14 tracey }
459 a596b957 2022-07-14 tracey
460 a596b957 2022-07-14 tracey void
461 a596b957 2022-07-14 tracey gotwebd_configure_done(struct gotwebd *env)
462 a596b957 2022-07-14 tracey {
463 a596b957 2022-07-14 tracey if (env->gotwebd_reload == 0) {
464 a596b957 2022-07-14 tracey log_warnx("%s: configuration already finished", __func__);
465 a596b957 2022-07-14 tracey return;
466 a596b957 2022-07-14 tracey }
467 a596b957 2022-07-14 tracey
468 a596b957 2022-07-14 tracey env->gotwebd_reload--;
469 26678add 2023-11-16 op if (env->gotwebd_reload == 0 &&
470 26678add 2023-11-16 op main_compose_sockets(env, IMSG_CTL_START, -1, NULL, 0) == -1)
471 26678add 2023-11-16 op fatal("main_compose_sockets IMSG_CTL_START");
472 a596b957 2022-07-14 tracey }
473 a596b957 2022-07-14 tracey
474 a596b957 2022-07-14 tracey void
475 a596b957 2022-07-14 tracey gotwebd_shutdown(void)
476 a596b957 2022-07-14 tracey {
477 26678add 2023-11-16 op struct gotwebd *env = gotwebd_env;
478 26678add 2023-11-16 op pid_t pid;
479 26678add 2023-11-16 op int i, status;
480 a596b957 2022-07-14 tracey
481 26678add 2023-11-16 op for (i = 0; i < env->nserver; ++i) {
482 26678add 2023-11-16 op event_del(&env->iev_server[i].ev);
483 26678add 2023-11-16 op imsg_clear(&env->iev_server[i].ibuf);
484 26678add 2023-11-16 op close(env->iev_server[i].ibuf.fd);
485 26678add 2023-11-16 op env->iev_server[i].ibuf.fd = -1;
486 26678add 2023-11-16 op }
487 26678add 2023-11-16 op
488 26678add 2023-11-16 op do {
489 26678add 2023-11-16 op pid = waitpid(WAIT_ANY, &status, 0);
490 26678add 2023-11-16 op if (pid <= 0)
491 26678add 2023-11-16 op continue;
492 26678add 2023-11-16 op
493 26678add 2023-11-16 op if (WIFSIGNALED(status))
494 26678add 2023-11-16 op log_warnx("lost child: pid %u terminated; signal %d",
495 26678add 2023-11-16 op pid, WTERMSIG(status));
496 26678add 2023-11-16 op else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
497 26678add 2023-11-16 op log_warnx("lost child: pid %u exited abnormally",
498 26678add 2023-11-16 op pid);
499 26678add 2023-11-16 op } while (pid != -1 || (pid == -1 && errno == EINTR));
500 26678add 2023-11-16 op
501 a596b957 2022-07-14 tracey free(gotwebd_env);
502 a596b957 2022-07-14 tracey
503 a596b957 2022-07-14 tracey log_warnx("gotwebd terminating");
504 a596b957 2022-07-14 tracey exit(0);
505 a596b957 2022-07-14 tracey }