1 /* $OpenBSD: sndiod.c,v 1.50 2024/12/20 07:35:56 ratchov Exp $ */
2 /*
3 * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <sys/resource.h>
20 #include <sys/socket.h>
21
22 #include <err.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <grp.h>
26 #include <limits.h>
27 #include <pwd.h>
28 #include <signal.h>
29 #include <sndio.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 #include "amsg.h"
36 #include "defs.h"
37 #include "dev.h"
38 #include "fdpass.h"
39 #include "file.h"
40 #include "listen.h"
41 #include "midi.h"
42 #include "opt.h"
43 #include "sock.h"
44 #include "utils.h"
45
46 /*
47 * unprivileged user name
48 */
49 #ifndef SNDIO_USER
50 #define SNDIO_USER "_sndio"
51 #endif
52
53 /*
54 * privileged user name
55 */
56 #ifndef SNDIO_PRIV_USER
57 #define SNDIO_PRIV_USER "_sndiop"
58 #endif
59
60 /*
61 * priority when run as root
62 */
63 #ifndef SNDIO_PRIO
64 #define SNDIO_PRIO (-20)
65 #endif
66
67 /*
68 * sample rate if no ``-r'' is used
69 */
70 #ifndef DEFAULT_RATE
71 #define DEFAULT_RATE 48000
72 #endif
73
74 /*
75 * block size if neither ``-z'' nor ``-b'' is used
76 */
77 #ifndef DEFAULT_ROUND
78 #define DEFAULT_ROUND 480
79 #endif
80
81 /*
82 * buffer size if neither ``-z'' nor ``-b'' is used
83 */
84 #ifndef DEFAULT_BUFSZ
85 #define DEFAULT_BUFSZ 7680
86 #endif
87
88 /*
89 * default device precision
90 */
91 #ifndef DEFAULT_BITS
92 #define DEFAULT_BITS 16
93 #endif
94
95 void sigint(int);
96 void sighup(int);
97 void opt_ch(int *, int *);
98 void opt_enc(struct aparams *);
99 int opt_mmc(void);
100 int opt_onoff(void);
101 int getword(char *, char **);
102 unsigned int opt_mode(void);
103 void getbasepath(char *);
104 void setsig(void);
105 void unsetsig(void);
106 struct dev *mkdev(char *, struct aparams *,
107 int, int, int, int, int, int);
108 struct port *mkport(char *, int);
109 struct opt *mkopt(char *, struct dev *,
110 int, int, int, int, int, int, int, int);
111
112 unsigned int log_level = 0;
113 volatile sig_atomic_t quit_flag = 0, reopen_flag = 0;
114
115 char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] "
116 "[-C min:max] [-c min:max]\n\t"
117 "[-e enc] [-F device] [-f device] [-j flag] [-L addr] [-m mode]\n\t"
118 "[-Q port] [-q port] [-r rate] [-s name] [-t mode] [-U unit]\n\t"
119 "[-v volume] [-w flag] [-z nframes]\n";
120
121 /*
122 * default audio devices
123 */
124 static char *default_devs[] = {
125 "rsnd/0", "rsnd/1", "rsnd/2", "rsnd/3",
126 NULL
127 };
128
129 /*
130 * default MIDI ports
131 */
132 static char *default_ports[] = {
133 "rmidi/0", "rmidi/1", "rmidi/2", "rmidi/3",
134 "rmidi/4", "rmidi/5", "rmidi/6", "rmidi/7",
135 NULL
136 };
137
138 /*
139 * SIGINT handler, it raises the quit flag. If the flag is already set,
140 * that means that the last SIGINT was not handled, because the process
141 * is blocked somewhere, so exit.
142 */
143 void
sigint(int s)144 sigint(int s)
145 {
146 if (quit_flag)
147 _exit(1);
148 quit_flag = 1;
149 }
150
151 /*
152 * SIGHUP handler, it raises the reopen flag, which requests devices
153 * to be reopened.
154 */
155 void
sighup(int s)156 sighup(int s)
157 {
158 reopen_flag = 1;
159 }
160
161 void
opt_ch(int * rcmin,int * rcmax)162 opt_ch(int *rcmin, int *rcmax)
163 {
164 char *next, *end;
165 long cmin, cmax;
166
167 errno = 0;
168 cmin = strtol(optarg, &next, 10);
169 if (next == optarg || *next != ':')
170 goto failed;
171 cmax = strtol(++next, &end, 10);
172 if (end == next || *end != '\0')
173 goto failed;
174 if (cmin < 0 || cmax < cmin || cmax >= NCHAN_MAX)
175 goto failed;
176 *rcmin = cmin;
177 *rcmax = cmax;
178 return;
179 failed:
180 errx(1, "%s: bad channel range", optarg);
181 }
182
183 void
opt_enc(struct aparams * par)184 opt_enc(struct aparams *par)
185 {
186 int len;
187
188 len = aparams_strtoenc(par, optarg);
189 if (len == 0 || optarg[len] != '\0')
190 errx(1, "%s: bad encoding", optarg);
191 }
192
193 int
opt_mmc(void)194 opt_mmc(void)
195 {
196 if (strcmp("off", optarg) == 0)
197 return 0;
198 if (strcmp("slave", optarg) == 0)
199 return 1;
200 errx(1, "%s: off/slave expected", optarg);
201 }
202
203 int
opt_onoff(void)204 opt_onoff(void)
205 {
206 if (strcmp("off", optarg) == 0)
207 return 0;
208 if (strcmp("on", optarg) == 0)
209 return 1;
210 errx(1, "%s: on/off expected", optarg);
211 }
212
213 int
getword(char * word,char ** str)214 getword(char *word, char **str)
215 {
216 char *p = *str;
217
218 for (;;) {
219 if (*word == '\0')
220 break;
221 if (*word++ != *p++)
222 return 0;
223 }
224 if (*p == ',' || *p == '\0') {
225 *str = p;
226 return 1;
227 }
228 return 0;
229 }
230
231 unsigned int
opt_mode(void)232 opt_mode(void)
233 {
234 unsigned int mode = 0;
235 char *p = optarg;
236
237 for (;;) {
238 if (getword("play", &p)) {
239 mode |= MODE_PLAY;
240 } else if (getword("rec", &p)) {
241 mode |= MODE_REC;
242 } else if (getword("mon", &p)) {
243 mode |= MODE_MON;
244 } else if (getword("midi", &p)) {
245 mode |= MODE_MIDIMASK;
246 } else
247 errx(1, "%s: bad mode", optarg);
248 if (*p == '\0')
249 break;
250 p++;
251 }
252 if (mode == 0)
253 errx(1, "empty mode");
254 return mode;
255 }
256
257 /*
258 * Open all devices. Possibly switch to the new devices if they have higher
259 * priorities than the current ones.
260 */
261 static void
reopen_devs(void)262 reopen_devs(void)
263 {
264 struct opt *o;
265 struct dev *d, *a;
266
267 for (o = opt_list; o != NULL; o = o->next) {
268
269 /* skip unused logical devices and ones with fixed hardware */
270 if (o->refcnt == 0 || strcmp(o->name, o->dev->name) == 0)
271 continue;
272
273 /* circulate to the device with the highest prio */
274 a = o->alt_first;
275 for (d = a; d->alt_next != a; d = d->alt_next) {
276 if (d->num > o->alt_first->num)
277 o->alt_first = d;
278 }
279
280 /* switch to the first working one, in pririty order */
281 d = o->alt_first;
282 while (d != o->dev) {
283 if (opt_setdev(o, d))
284 break;
285 d = d->alt_next;
286 }
287 }
288
289 /*
290 * retry to open the remaining devices that are not used but need
291 * to stay open (ex. '-a on')
292 */
293 for (d = dev_list; d != NULL; d = d->next) {
294 if (d->refcnt > 0 && d->pstate == DEV_CFG)
295 dev_open(d);
296 }
297 }
298
299 /*
300 * For each port, open the alt with the highest priority and switch to it
301 */
302 static void
reopen_ports(void)303 reopen_ports(void)
304 {
305 struct port *p, *a, *apri;
306 int inuse;
307
308 for (p = port_list; p != NULL; p = a->next) {
309
310 /* skip unused ports */
311 inuse = 0;
312 a = p;
313 while (1) {
314 if (midi_rxmask(a->midi) || a->midi->txmask)
315 inuse = 1;
316 if (a->alt_next == p)
317 break;
318 a = a->alt_next;
319 }
320 if (!inuse)
321 continue;
322
323 /* open the alt with the highest prio */
324 apri = port_alt_ref(p->num);
325
326 /* switch to it */
327 a = p;
328 while (1) {
329 if (a != apri) {
330 midi_migrate(a->midi, apri->midi);
331 port_unref(a);
332 }
333 if (a->alt_next == p)
334 break;
335 a = a->alt_next;
336 }
337 }
338 }
339
340 void
setsig(void)341 setsig(void)
342 {
343 struct sigaction sa;
344
345 quit_flag = 0;
346 reopen_flag = 0;
347 sigfillset(&sa.sa_mask);
348 sa.sa_flags = SA_RESTART;
349 sa.sa_handler = sigint;
350 if (sigaction(SIGINT, &sa, NULL) == -1)
351 err(1, "sigaction(int) failed");
352 if (sigaction(SIGTERM, &sa, NULL) == -1)
353 err(1, "sigaction(term) failed");
354 sa.sa_handler = sighup;
355 if (sigaction(SIGHUP, &sa, NULL) == -1)
356 err(1, "sigaction(hup) failed");
357 }
358
359 void
unsetsig(void)360 unsetsig(void)
361 {
362 struct sigaction sa;
363
364 sigfillset(&sa.sa_mask);
365 sa.sa_flags = SA_RESTART;
366 sa.sa_handler = SIG_DFL;
367 if (sigaction(SIGHUP, &sa, NULL) == -1)
368 err(1, "unsetsig(hup): sigaction failed");
369 if (sigaction(SIGTERM, &sa, NULL) == -1)
370 err(1, "unsetsig(term): sigaction failed");
371 if (sigaction(SIGINT, &sa, NULL) == -1)
372 err(1, "unsetsig(int): sigaction failed");
373 }
374
375 void
getbasepath(char * base)376 getbasepath(char *base)
377 {
378 uid_t uid;
379 struct stat sb;
380 mode_t mask, omask;
381
382 uid = geteuid();
383 if (uid == 0) {
384 mask = 022;
385 snprintf(base, SOCKPATH_MAX, SOCKPATH_DIR);
386 } else {
387 mask = 077;
388 snprintf(base, SOCKPATH_MAX, SOCKPATH_DIR "-%u", uid);
389 }
390 omask = umask(mask);
391 if (mkdir(base, 0777) == -1) {
392 if (errno != EEXIST)
393 err(1, "mkdir(\"%s\")", base);
394 }
395 umask(omask);
396 if (stat(base, &sb) == -1)
397 err(1, "stat(\"%s\")", base);
398 if (!S_ISDIR(sb.st_mode))
399 errx(1, "%s is not a directory", base);
400 if (sb.st_uid != uid || (sb.st_mode & mask) != 0)
401 errx(1, "%s has wrong permissions", base);
402 }
403
404 struct dev *
mkdev(char * path,struct aparams * par,int mode,int bufsz,int round,int rate,int hold,int autovol)405 mkdev(char *path, struct aparams *par,
406 int mode, int bufsz, int round, int rate, int hold, int autovol)
407 {
408 struct dev *d;
409
410 for (d = dev_list; d != NULL; d = d->next) {
411 if (strcmp(d->path, path) == 0)
412 return d;
413 }
414 if (!bufsz && !round) {
415 round = DEFAULT_ROUND;
416 bufsz = DEFAULT_BUFSZ;
417 } else if (!bufsz) {
418 bufsz = round * 2;
419 } else if (!round)
420 round = bufsz / 2;
421 d = dev_new(path, par, mode, bufsz, round, rate, hold, autovol);
422 if (d == NULL)
423 exit(1);
424 return d;
425 }
426
427 struct port *
mkport(char * path,int hold)428 mkport(char *path, int hold)
429 {
430 struct port *c;
431
432 for (c = port_list; c != NULL; c = c->next) {
433 if (strcmp(c->path, path) == 0)
434 return c;
435 }
436 c = port_new(path, MODE_MIDIMASK, hold);
437 if (c == NULL)
438 exit(1);
439 return c;
440 }
441
442 struct opt *
mkopt(char * path,struct dev * d,int pmin,int pmax,int rmin,int rmax,int mode,int vol,int mmc,int dup)443 mkopt(char *path, struct dev *d,
444 int pmin, int pmax, int rmin, int rmax,
445 int mode, int vol, int mmc, int dup)
446 {
447 struct opt *o;
448
449 o = opt_new(d, path, pmin, pmax, rmin, rmax,
450 MIDI_TO_ADATA(vol), mmc, dup, mode);
451 if (o == NULL)
452 return NULL;
453 dev_adjpar(d, o->mode, o->pmax, o->rmax);
454 return o;
455 }
456
457 static void
dounveil(char * name,char * prefix,char * path_prefix)458 dounveil(char *name, char *prefix, char *path_prefix)
459 {
460 size_t prefix_len;
461 char path[PATH_MAX];
462
463 prefix_len = strlen(prefix);
464
465 if (strncmp(name, prefix, prefix_len) != 0)
466 errx(1, "%s: unsupported device or port format", name);
467 snprintf(path, sizeof(path), "%s%s", path_prefix, name + prefix_len);
468 if (unveil(path, "rw") == -1)
469 err(1, "unveil %s", path);
470 }
471
472 static int
start_helper(int background)473 start_helper(int background)
474 {
475 struct dev *d;
476 struct port *p;
477 struct passwd *pw;
478 int s[2];
479 pid_t pid;
480
481 if (geteuid() == 0) {
482 if ((pw = getpwnam(SNDIO_PRIV_USER)) == NULL)
483 errx(1, "unknown user %s", SNDIO_PRIV_USER);
484 } else
485 pw = NULL;
486 if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1) {
487 perror("socketpair");
488 return 0;
489 }
490 pid = fork();
491 if (pid == -1) {
492 perror("fork");
493 return 0;
494 }
495 if (pid == 0) {
496 setproctitle("helper");
497 close(s[0]);
498 if (fdpass_new(s[1], &helper_fileops) == NULL)
499 return 0;
500 if (background) {
501 log_flush();
502 log_level = 0;
503 if (daemon(0, 0) == -1)
504 err(1, "daemon");
505 }
506 if (pw != NULL) {
507 if (setgroups(1, &pw->pw_gid) ||
508 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
509 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
510 err(1, "cannot drop privileges");
511 }
512 for (d = dev_list; d != NULL; d = d->next) {
513 dounveil(d->path, "rsnd/", "/dev/audio");
514 dounveil(d->path, "rsnd/", "/dev/audioctl");
515 }
516 for (p = port_list; p != NULL; p = p->next) {
517 dounveil(p->path, "rmidi/", "/dev/rmidi");
518 }
519 if (pledge("stdio sendfd rpath wpath", NULL) == -1)
520 err(1, "pledge");
521 while (file_poll())
522 ; /* nothing */
523 exit(0);
524 } else {
525 close(s[1]);
526 if (fdpass_new(s[0], &worker_fileops) == NULL)
527 return 0;
528 }
529 return 1;
530 }
531
532 static void
stop_helper(void)533 stop_helper(void)
534 {
535 if (fdpass_peer)
536 fdpass_close(fdpass_peer);
537 }
538
539 int
main(int argc,char ** argv)540 main(int argc, char **argv)
541 {
542 int c, i, background, unit;
543 int pmin, pmax, rmin, rmax;
544 char base[SOCKPATH_MAX], path[SOCKPATH_MAX];
545 unsigned int mode, dup, mmc, vol;
546 unsigned int hold, autovol, bufsz, round, rate;
547 const char *str;
548 struct aparams par;
549 struct opt *o;
550 struct dev *d, *dev_first, *dev_next;
551 struct port *p, *port_first, *port_next;
552 struct listen *l;
553 struct passwd *pw;
554 struct tcpaddr {
555 char *host;
556 struct tcpaddr *next;
557 } *tcpaddr_list, *ta;
558
559 atexit(log_flush);
560
561 /*
562 * global options defaults
563 */
564 vol = 127;
565 dup = 1;
566 mmc = 0;
567 hold = 0;
568 autovol = 0;
569 bufsz = 0;
570 round = 0;
571 rate = DEFAULT_RATE;
572 unit = 0;
573 background = 1;
574 pmin = 0;
575 pmax = 1;
576 rmin = 0;
577 rmax = 1;
578 par.bits = DEFAULT_BITS;
579 par.bps = APARAMS_BPS(par.bits);
580 par.le = ADATA_LE;
581 par.sig = 1;
582 par.msb = 0;
583 mode = MODE_PLAY | MODE_REC;
584 dev_first = dev_next = NULL;
585 port_first = port_next = NULL;
586 tcpaddr_list = NULL;
587 d = NULL;
588 p = NULL;
589
590 slot_array_init();
591
592 while ((c = getopt(argc, argv,
593 "a:b:c:C:de:F:f:j:L:m:Q:q:r:s:t:U:v:w:x:z:")) != -1) {
594 switch (c) {
595 case 'd':
596 log_level++;
597 background = 0;
598 break;
599 case 'U':
600 unit = strtonum(optarg, 0, 15, &str);
601 if (str)
602 errx(1, "%s: unit number is %s", optarg, str);
603 break;
604 case 'L':
605 ta = xmalloc(sizeof(struct tcpaddr));
606 ta->host = optarg;
607 ta->next = tcpaddr_list;
608 tcpaddr_list = ta;
609 break;
610 case 'm':
611 mode = opt_mode();
612 break;
613 case 'j':
614 dup = opt_onoff();
615 break;
616 case 't':
617 mmc = opt_mmc();
618 break;
619 case 'c':
620 opt_ch(&pmin, &pmax);
621 break;
622 case 'C':
623 opt_ch(&rmin, &rmax);
624 break;
625 case 'e':
626 opt_enc(&par);
627 break;
628 case 'r':
629 rate = strtonum(optarg, RATE_MIN, RATE_MAX, &str);
630 if (str)
631 errx(1, "%s: rate is %s", optarg, str);
632 break;
633 case 'v':
634 vol = strtonum(optarg, 0, MIDI_MAXCTL, &str);
635 if (str)
636 errx(1, "%s: volume is %s", optarg, str);
637 break;
638 case 's':
639 if (d == NULL) {
640 for (i = 0; default_devs[i] != NULL; i++) {
641 mkdev(default_devs[i], &par, 0,
642 bufsz, round, rate, 0, autovol);
643 }
644 d = dev_list;
645 }
646 if (mkopt(optarg, d, pmin, pmax, rmin, rmax,
647 mode, vol, mmc, dup) == NULL)
648 return 1;
649 break;
650 case 'q':
651 p = mkport(optarg, hold);
652 /* create new circulate list */
653 port_first = port_next = p;
654 break;
655 case 'Q':
656 if (p == NULL)
657 errx(1, "-Q %s: no ports defined", optarg);
658 p = mkport(optarg, hold);
659 /* add to circulate list */
660 p->alt_next = port_next;
661 port_first->alt_next = p;
662 port_next = p;
663 break;
664 case 'a':
665 hold = opt_onoff();
666 break;
667 case 'w':
668 autovol = opt_onoff();
669 break;
670 case 'b':
671 bufsz = strtonum(optarg, 1, RATE_MAX, &str);
672 if (str)
673 errx(1, "%s: buffer size is %s", optarg, str);
674 break;
675 case 'z':
676 round = strtonum(optarg, 1, SHRT_MAX, &str);
677 if (str)
678 errx(1, "%s: block size is %s", optarg, str);
679 break;
680 case 'f':
681 d = mkdev(optarg, &par, 0, bufsz, round,
682 rate, hold, autovol);
683 /* create new circulate list */
684 dev_first = dev_next = d;
685 break;
686 case 'F':
687 if (d == NULL)
688 errx(1, "-F %s: no devices defined", optarg);
689 d = mkdev(optarg, &par, 0, bufsz, round,
690 rate, hold, autovol);
691 /* add to circulate list */
692 d->alt_next = dev_next;
693 dev_first->alt_next = d;
694 dev_next = d;
695 break;
696 default:
697 fputs(usagestr, stderr);
698 return 1;
699 }
700 }
701 argc -= optind;
702 argv += optind;
703 if (argc > 0) {
704 fputs(usagestr, stderr);
705 return 1;
706 }
707 if (port_list == NULL) {
708 for (i = 0; default_ports[i] != NULL; i++)
709 mkport(default_ports[i], 0);
710 }
711 if (dev_list == NULL) {
712 for (i = 0; default_devs[i] != NULL; i++) {
713 mkdev(default_devs[i], &par, 0,
714 bufsz, round, rate, 0, autovol);
715 }
716 }
717
718 /*
719 * Add default sub-device (if none) backed by the last device
720 */
721 o = opt_byname("default");
722 if (o == NULL) {
723 o = mkopt("default", dev_list, pmin, pmax, rmin, rmax,
724 mode, vol, 0, dup);
725 if (o == NULL)
726 return 1;
727 }
728
729 /*
730 * For each device create an anonymous sub-device using
731 * the "default" sub-device as template
732 */
733 for (d = dev_list; d != NULL; d = d->next) {
734 if (opt_new(d, NULL, o->pmin, o->pmax, o->rmin, o->rmax,
735 o->maxweight, o->mtc != NULL, o->dup, o->mode) == NULL)
736 return 1;
737 dev_adjpar(d, o->mode, o->pmax, o->rmax);
738 }
739
740 setsig();
741 filelist_init();
742
743 if (!start_helper(background))
744 return 1;
745
746 if (geteuid() == 0) {
747 if ((pw = getpwnam(SNDIO_USER)) == NULL)
748 errx(1, "unknown user %s", SNDIO_USER);
749 } else
750 pw = NULL;
751 getbasepath(base);
752 snprintf(path, SOCKPATH_MAX, "%s/" SOCKPATH_FILE "%u", base, unit);
753 if (!listen_new_un(path))
754 return 1;
755 for (ta = tcpaddr_list; ta != NULL; ta = ta->next) {
756 if (!listen_new_tcp(ta->host, AUCAT_PORT + unit))
757 return 1;
758 }
759 for (l = listen_list; l != NULL; l = l->next) {
760 if (!listen_init(l))
761 return 1;
762 }
763 midi_init();
764 for (p = port_list; p != NULL; p = p->next) {
765 if (!port_init(p))
766 return 1;
767 }
768 for (d = dev_list; d != NULL; d = d->next) {
769 if (!dev_init(d))
770 return 1;
771 }
772 for (o = opt_list; o != NULL; o = o->next)
773 opt_init(o);
774 if (background) {
775 log_flush();
776 log_level = 0;
777 if (daemon(0, 0) == -1)
778 err(1, "daemon");
779 }
780 if (pw != NULL) {
781 if (setpriority(PRIO_PROCESS, 0, SNDIO_PRIO) == -1)
782 err(1, "setpriority");
783 if (chroot(pw->pw_dir) == -1 || chdir("/") == -1)
784 err(1, "cannot chroot to %s", pw->pw_dir);
785 if (setgroups(1, &pw->pw_gid) == -1 ||
786 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
787 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1 )
788 err(1, "cannot drop privileges");
789 }
790 if (tcpaddr_list) {
791 if (pledge("stdio audio recvfd unix inet", NULL) == -1)
792 err(1, "pledge");
793 } else {
794 if (pledge("stdio audio recvfd unix", NULL) == -1)
795 err(1, "pledge");
796 }
797
798 for (;;) {
799 if (quit_flag)
800 break;
801 if (reopen_flag) {
802 reopen_flag = 0;
803 reopen_devs();
804 reopen_ports();
805 }
806 if (!fdpass_peer)
807 break;
808 if (!file_poll())
809 break;
810 }
811 stop_helper();
812 while (listen_list != NULL)
813 listen_close(listen_list);
814 while (sock_list != NULL)
815 sock_close(sock_list);
816 for (o = opt_list; o != NULL; o = o->next)
817 opt_done(o);
818 for (d = dev_list; d != NULL; d = d->next)
819 dev_done(d);
820 for (p = port_list; p != NULL; p = p->next)
821 port_done(p);
822 while (file_poll())
823 ; /* nothing */
824 midi_done();
825
826 while (opt_list)
827 opt_del(opt_list);
828 while (dev_list)
829 dev_del(dev_list);
830 while (port_list)
831 port_del(port_list);
832 while (tcpaddr_list) {
833 ta = tcpaddr_list;
834 tcpaddr_list = ta->next;
835 xfree(ta);
836 }
837 filelist_done();
838 unsetsig();
839 return 0;
840 }
841