Bug Summary

File:src/usr.bin/sndiod/sndiod.c
Warning:line 609, column 2
Value stored to 'argv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sndiod.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/sndiod/obj -resource-dir /usr/local/lib/clang/13.0.0 -D DEBUG -I /usr/src/usr.bin/sndiod/../../lib/libsndio -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/sndiod/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/sndiod/sndiod.c
1/* $OpenBSD: sndiod.c,v 1.47 2021/11/01 14:43:25 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(*__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"_sndio"
50#define SNDIO_USER"_sndio" "_sndio"
51#endif
52
53/*
54 * privileged user name
55 */
56#ifndef SNDIO_PRIV_USER"_sndiop"
57#define SNDIO_PRIV_USER"_sndiop" "_sndiop"
58#endif
59
60/*
61 * priority when run as root
62 */
63#ifndef SNDIO_PRIO(-20)
64#define SNDIO_PRIO(-20) (-20)
65#endif
66
67/*
68 * sample rate if no ``-r'' is used
69 */
70#ifndef DEFAULT_RATE48000
71#define DEFAULT_RATE48000 48000
72#endif
73
74/*
75 * block size if neither ``-z'' nor ``-b'' is used
76 */
77#ifndef DEFAULT_ROUND480
78#define DEFAULT_ROUND480 480
79#endif
80
81/*
82 * buffer size if neither ``-z'' nor ``-b'' is used
83 */
84#ifndef DEFAULT_BUFSZ7680
85#define DEFAULT_BUFSZ7680 7680
86#endif
87
88void sigint(int);
89void sighup(int);
90void opt_ch(int *, int *);
91void opt_enc(struct aparams *);
92int opt_mmc(void);
93int opt_onoff(void);
94int getword(char *, char **);
95unsigned int opt_mode(void);
96void getbasepath(char *);
97void setsig(void);
98void unsetsig(void);
99struct dev *mkdev(char *, struct aparams *,
100 int, int, int, int, int, int);
101struct port *mkport(char *, int);
102struct opt *mkopt(char *, struct dev *,
103 int, int, int, int, int, int, int, int);
104
105unsigned int log_level = 0;
106volatile sig_atomic_t quit_flag = 0, reopen_flag = 0;
107
108char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] "
109 "[-C min:max] [-c min:max]\n\t"
110 "[-e enc] [-F device] [-f device] [-j flag] [-L addr] [-m mode]\n\t"
111 "[-Q port] [-q port] [-r rate] [-s name] [-t mode] [-U unit]\n\t"
112 "[-v volume] [-w flag] [-z nframes]\n";
113
114/*
115 * default audio devices
116 */
117static char *default_devs[] = {
118 "rsnd/0", "rsnd/1", "rsnd/2", "rsnd/3",
119 NULL((void*)0)
120};
121
122/*
123 * default MIDI ports
124 */
125static char *default_ports[] = {
126 "rmidi/0", "rmidi/1", "rmidi/2", "rmidi/3",
127 "rmidi/4", "rmidi/5", "rmidi/6", "rmidi/7",
128 NULL((void*)0)
129};
130
131/*
132 * SIGINT handler, it raises the quit flag. If the flag is already set,
133 * that means that the last SIGINT was not handled, because the process
134 * is blocked somewhere, so exit.
135 */
136void
137sigint(int s)
138{
139 if (quit_flag)
140 _exit(1);
141 quit_flag = 1;
142}
143
144/*
145 * SIGHUP handler, it raises the reopen flag, which requests devices
146 * to be reopened.
147 */
148void
149sighup(int s)
150{
151 reopen_flag = 1;
152}
153
154void
155opt_ch(int *rcmin, int *rcmax)
156{
157 char *next, *end;
158 long cmin, cmax;
159
160 errno(*__errno()) = 0;
161 cmin = strtol(optarg, &next, 10);
162 if (next == optarg || *next != ':')
163 goto failed;
164 cmax = strtol(++next, &end, 10);
165 if (end == next || *end != '\0')
166 goto failed;
167 if (cmin < 0 || cmax < cmin || cmax >= NCHAN_MAX64)
168 goto failed;
169 *rcmin = cmin;
170 *rcmax = cmax;
171 return;
172failed:
173 errx(1, "%s: bad channel range", optarg);
174}
175
176void
177opt_enc(struct aparams *par)
178{
179 int len;
180
181 len = aparams_strtoenc(par, optarg);
182 if (len == 0 || optarg[len] != '\0')
183 errx(1, "%s: bad encoding", optarg);
184}
185
186int
187opt_mmc(void)
188{
189 if (strcmp("off", optarg) == 0)
190 return 0;
191 if (strcmp("slave", optarg) == 0)
192 return 1;
193 errx(1, "%s: off/slave expected", optarg);
194}
195
196int
197opt_onoff(void)
198{
199 if (strcmp("off", optarg) == 0)
200 return 0;
201 if (strcmp("on", optarg) == 0)
202 return 1;
203 errx(1, "%s: on/off expected", optarg);
204}
205
206int
207getword(char *word, char **str)
208{
209 char *p = *str;
210
211 for (;;) {
212 if (*word == '\0')
213 break;
214 if (*word++ != *p++)
215 return 0;
216 }
217 if (*p == ',' || *p == '\0') {
218 *str = p;
219 return 1;
220 }
221 return 0;
222}
223
224unsigned int
225opt_mode(void)
226{
227 unsigned int mode = 0;
228 char *p = optarg;
229
230 for (;;) {
231 if (getword("play", &p)) {
232 mode |= MODE_PLAY0x01;
233 } else if (getword("rec", &p)) {
234 mode |= MODE_REC0x02;
235 } else if (getword("mon", &p)) {
236 mode |= MODE_MON0x10;
237 } else if (getword("midi", &p)) {
238 mode |= MODE_MIDIMASK(0x08 | 0x04);
239 } else
240 errx(1, "%s: bad mode", optarg);
241 if (*p == '\0')
242 break;
243 p++;
244 }
245 if (mode == 0)
246 errx(1, "empty mode");
247 return mode;
248}
249
250void
251setsig(void)
252{
253 struct sigaction sa;
254
255 quit_flag = 0;
256 reopen_flag = 0;
257 sigfillset(&sa.sa_mask);
258 sa.sa_flags = SA_RESTART0x0002;
259 sa.sa_handler__sigaction_u.__sa_handler = sigint;
260 if (sigaction(SIGINT2, &sa, NULL((void*)0)) == -1)
261 err(1, "sigaction(int) failed");
262 if (sigaction(SIGTERM15, &sa, NULL((void*)0)) == -1)
263 err(1, "sigaction(term) failed");
264 sa.sa_handler__sigaction_u.__sa_handler = sighup;
265 if (sigaction(SIGHUP1, &sa, NULL((void*)0)) == -1)
266 err(1, "sigaction(hup) failed");
267}
268
269void
270unsetsig(void)
271{
272 struct sigaction sa;
273
274 sigfillset(&sa.sa_mask);
275 sa.sa_flags = SA_RESTART0x0002;
276 sa.sa_handler__sigaction_u.__sa_handler = SIG_DFL(void (*)(int))0;
277 if (sigaction(SIGHUP1, &sa, NULL((void*)0)) == -1)
278 err(1, "unsetsig(hup): sigaction failed");
279 if (sigaction(SIGTERM15, &sa, NULL((void*)0)) == -1)
280 err(1, "unsetsig(term): sigaction failed");
281 if (sigaction(SIGINT2, &sa, NULL((void*)0)) == -1)
282 err(1, "unsetsig(int): sigaction failed");
283}
284
285void
286getbasepath(char *base)
287{
288 uid_t uid;
289 struct stat sb;
290 mode_t mask, omask;
291
292 uid = geteuid();
293 if (uid == 0) {
294 mask = 022;
295 snprintf(base, SOCKPATH_MAX(1 + sizeof("/tmp/sndio") - 1 + sizeof(char) + sizeof(int) * 3
+ sizeof(char) + sizeof("sock") - 1 + sizeof(int) * 3)
, SOCKPATH_DIR"/tmp/sndio");
296 } else {
297 mask = 077;
298 snprintf(base, SOCKPATH_MAX(1 + sizeof("/tmp/sndio") - 1 + sizeof(char) + sizeof(int) * 3
+ sizeof(char) + sizeof("sock") - 1 + sizeof(int) * 3)
, SOCKPATH_DIR"/tmp/sndio" "-%u", uid);
299 }
300 omask = umask(mask);
301 if (mkdir(base, 0777) == -1) {
302 if (errno(*__errno()) != EEXIST17)
303 err(1, "mkdir(\"%s\")", base);
304 }
305 umask(omask);
306 if (stat(base, &sb) == -1)
307 err(1, "stat(\"%s\")", base);
308 if (!S_ISDIR(sb.st_mode)((sb.st_mode & 0170000) == 0040000))
309 errx(1, "%s is not a directory", base);
310 if (sb.st_uid != uid || (sb.st_mode & mask) != 0)
311 errx(1, "%s has wrong permissions", base);
312}
313
314struct dev *
315mkdev(char *path, struct aparams *par,
316 int mode, int bufsz, int round, int rate, int hold, int autovol)
317{
318 struct dev *d;
319
320 for (d = dev_list; d != NULL((void*)0); d = d->next) {
321 if (strcmp(d->path, path) == 0)
322 return d;
323 }
324 if (!bufsz && !round) {
325 round = DEFAULT_ROUND480;
326 bufsz = DEFAULT_BUFSZ7680;
327 } else if (!bufsz) {
328 bufsz = round * 2;
329 } else if (!round)
330 round = bufsz / 2;
331 d = dev_new(path, par, mode, bufsz, round, rate, hold, autovol);
332 if (d == NULL((void*)0))
333 exit(1);
334 return d;
335}
336
337struct port *
338mkport(char *path, int hold)
339{
340 struct port *c;
341
342 for (c = port_list; c != NULL((void*)0); c = c->next) {
343 if (strcmp(c->path, path) == 0)
344 return c;
345 }
346 c = port_new(path, MODE_MIDIMASK(0x08 | 0x04), hold);
347 if (c == NULL((void*)0))
348 exit(1);
349 return c;
350}
351
352struct opt *
353mkopt(char *path, struct dev *d,
354 int pmin, int pmax, int rmin, int rmax,
355 int mode, int vol, int mmc, int dup)
356{
357 struct opt *o;
358
359 o = opt_new(d, path, pmin, pmax, rmin, rmax,
360 MIDI_TO_ADATA(vol)(aparams_ctltovol[vol] << (16 - 16)), mmc, dup, mode);
361 if (o == NULL((void*)0))
362 return NULL((void*)0);
363 dev_adjpar(d, o->mode, o->pmax, o->rmax);
364 return o;
365}
366
367static void
368dounveil(char *name, char *prefix, char *path_prefix)
369{
370 size_t prefix_len;
371 char path[PATH_MAX1024];
372
373 prefix_len = strlen(prefix);
374
375 if (strncmp(name, prefix, prefix_len) != 0)
376 errx(1, "%s: unsupported device or port format", name);
377 snprintf(path, sizeof(path), "%s%s", path_prefix, name + prefix_len);
378 if (unveil(path, "rw") == -1)
379 err(1, "unveil %s", path);
380}
381
382static int
383start_helper(int background)
384{
385 struct dev *d;
386 struct port *p;
387 struct passwd *pw;
388 int s[2];
389 pid_t pid;
390
391 if (geteuid() == 0) {
392 if ((pw = getpwnam(SNDIO_PRIV_USER"_sndiop")) == NULL((void*)0))
393 errx(1, "unknown user %s", SNDIO_PRIV_USER"_sndiop");
394 } else
395 pw = NULL((void*)0);
396 if (socketpair(AF_UNIX1, SOCK_STREAM1, 0, s) == -1) {
397 perror("socketpair");
398 return 0;
399 }
400 pid = fork();
401 if (pid == -1) {
402 log_puts("can't fork\n");
403 return 0;
404 }
405 if (pid == 0) {
406 setproctitle("helper");
407 close(s[0]);
408 if (fdpass_new(s[1], &helper_fileops) == NULL((void*)0))
409 return 0;
410 if (background) {
411 log_flush();
412 log_level = 0;
413 if (daemon(0, 0) == -1)
414 err(1, "daemon");
415 }
416 if (pw != NULL((void*)0)) {
417 if (setgroups(1, &pw->pw_gid) ||
418 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
419 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
420 err(1, "cannot drop privileges");
421 }
422 for (d = dev_list; d != NULL((void*)0); d = d->next) {
423 dounveil(d->path, "rsnd/", "/dev/audio");
424 dounveil(d->path, "rsnd/", "/dev/audioctl");
425 }
426 for (p = port_list; p != NULL((void*)0); p = p->next) {
427 dounveil(p->path, "rmidi/", "/dev/rmidi");
428 }
429 if (pledge("stdio sendfd rpath wpath", NULL((void*)0)) == -1)
430 err(1, "pledge");
431 while (file_poll())
432 ; /* nothing */
433 exit(0);
434 } else {
435 close(s[1]);
436 if (fdpass_new(s[0], &worker_fileops) == NULL((void*)0))
437 return 0;
438 }
439 return 1;
440}
441
442static void
443stop_helper(void)
444{
445 if (fdpass_peer)
446 fdpass_close(fdpass_peer);
447}
448
449int
450main(int argc, char **argv)
451{
452 int c, i, background, unit;
453 int pmin, pmax, rmin, rmax;
454 char base[SOCKPATH_MAX(1 + sizeof("/tmp/sndio") - 1 + sizeof(char) + sizeof(int) * 3
+ sizeof(char) + sizeof("sock") - 1 + sizeof(int) * 3)
], path[SOCKPATH_MAX(1 + sizeof("/tmp/sndio") - 1 + sizeof(char) + sizeof(int) * 3
+ sizeof(char) + sizeof("sock") - 1 + sizeof(int) * 3)
];
455 unsigned int mode, dup, mmc, vol;
456 unsigned int hold, autovol, bufsz, round, rate;
457 unsigned int reopen_list;
458 const char *str;
459 struct aparams par;
460 struct opt *o;
461 struct dev *d, *dev_first, *dev_next;
462 struct port *p, *port_first, *port_next;
463 struct listen *l;
464 struct passwd *pw;
465 struct tcpaddr {
466 char *host;
467 struct tcpaddr *next;
468 } *tcpaddr_list, *ta;
469
470 atexit(log_flush);
471
472 /*
473 * global options defaults
474 */
475 vol = 127;
476 dup = 1;
477 mmc = 0;
478 hold = 0;
479 autovol = 0;
480 bufsz = 0;
481 round = 0;
482 rate = DEFAULT_RATE48000;
483 unit = 0;
484 background = 1;
485 pmin = 0;
486 pmax = 1;
487 rmin = 0;
488 rmax = 1;
489 aparams_init(&par);
490 mode = MODE_PLAY0x01 | MODE_REC0x02;
491 dev_first = dev_next = NULL((void*)0);
492 port_first = port_next = NULL((void*)0);
493 tcpaddr_list = NULL((void*)0);
494 d = NULL((void*)0);
495 p = NULL((void*)0);
496
497 slot_array_init();
498
499 while ((c = getopt(argc, argv,
500 "a:b:c:C:de:F:f:j:L:m:Q:q:r:s:t:U:v:w:x:z:")) != -1) {
501 switch (c) {
502 case 'd':
503 log_level++;
504 background = 0;
505 break;
506 case 'U':
507 unit = strtonum(optarg, 0, 15, &str);
508 if (str)
509 errx(1, "%s: unit number is %s", optarg, str);
510 break;
511 case 'L':
512 ta = xmalloc(sizeof(struct tcpaddr));
513 ta->host = optarg;
514 ta->next = tcpaddr_list;
515 tcpaddr_list = ta;
516 break;
517 case 'm':
518 mode = opt_mode();
519 break;
520 case 'j':
521 dup = opt_onoff();
522 break;
523 case 't':
524 mmc = opt_mmc();
525 break;
526 case 'c':
527 opt_ch(&pmin, &pmax);
528 break;
529 case 'C':
530 opt_ch(&rmin, &rmax);
531 break;
532 case 'e':
533 opt_enc(&par);
534 break;
535 case 'r':
536 rate = strtonum(optarg, RATE_MIN4000, RATE_MAX192000, &str);
537 if (str)
538 errx(1, "%s: rate is %s", optarg, str);
539 break;
540 case 'v':
541 vol = strtonum(optarg, 0, MIDI_MAXCTL127, &str);
542 if (str)
543 errx(1, "%s: volume is %s", optarg, str);
544 break;
545 case 's':
546 if (d == NULL((void*)0)) {
547 for (i = 0; default_devs[i] != NULL((void*)0); i++) {
548 mkdev(default_devs[i], &par, 0,
549 bufsz, round, rate, 0, autovol);
550 }
551 d = dev_list;
552 }
553 if (mkopt(optarg, d, pmin, pmax, rmin, rmax,
554 mode, vol, mmc, dup) == NULL((void*)0))
555 return 1;
556 break;
557 case 'q':
558 p = mkport(optarg, hold);
559 /* create new circulate list */
560 port_first = port_next = p;
561 break;
562 case 'Q':
563 if (p == NULL((void*)0))
564 errx(1, "-Q %s: no ports defined", optarg);
565 p = mkport(optarg, hold);
566 /* add to circulate list */
567 p->alt_next = port_next;
568 port_first->alt_next = p;
569 port_next = p;
570 break;
571 case 'a':
572 hold = opt_onoff();
573 break;
574 case 'w':
575 autovol = opt_onoff();
576 break;
577 case 'b':
578 bufsz = strtonum(optarg, 1, RATE_MAX192000, &str);
579 if (str)
580 errx(1, "%s: buffer size is %s", optarg, str);
581 break;
582 case 'z':
583 round = strtonum(optarg, 1, SHRT_MAX32767, &str);
584 if (str)
585 errx(1, "%s: block size is %s", optarg, str);
586 break;
587 case 'f':
588 d = mkdev(optarg, &par, 0, bufsz, round,
589 rate, hold, autovol);
590 /* create new circulate list */
591 dev_first = dev_next = d;
592 break;
593 case 'F':
594 if (d == NULL((void*)0))
595 errx(1, "-F %s: no devices defined", optarg);
596 d = mkdev(optarg, &par, 0, bufsz, round,
597 rate, hold, autovol);
598 /* add to circulate list */
599 d->alt_next = dev_next;
600 dev_first->alt_next = d;
601 dev_next = d;
602 break;
603 default:
604 fputs(usagestr, stderr(&__sF[2]));
605 return 1;
606 }
607 }
608 argc -= optind;
609 argv += optind;
Value stored to 'argv' is never read
610 if (argc > 0) {
611 fputs(usagestr, stderr(&__sF[2]));
612 return 1;
613 }
614 if (port_list == NULL((void*)0)) {
615 for (i = 0; default_ports[i] != NULL((void*)0); i++)
616 mkport(default_ports[i], 0);
617 }
618 if (dev_list == NULL((void*)0)) {
619 for (i = 0; default_devs[i] != NULL((void*)0); i++) {
620 mkdev(default_devs[i], &par, 0,
621 bufsz, round, rate, 0, autovol);
622 }
623 }
624
625 /*
626 * Add default sub-device (if none) backed by the last device
627 */
628 o = opt_byname("default");
629 if (o == NULL((void*)0)) {
630 o = mkopt("default", dev_list, pmin, pmax, rmin, rmax,
631 mode, vol, 0, dup);
632 if (o == NULL((void*)0))
633 return 1;
634 }
635
636 /*
637 * For each device create an anonymous sub-device using
638 * the "default" sub-device as template
639 */
640 for (d = dev_list; d != NULL((void*)0); d = d->next) {
641 if (opt_new(d, NULL((void*)0), o->pmin, o->pmax, o->rmin, o->rmax,
642 o->maxweight, o->mtc != NULL((void*)0), o->dup, o->mode) == NULL((void*)0))
643 return 1;
644 dev_adjpar(d, o->mode, o->pmax, o->rmax);
645 }
646
647 setsig();
648 filelist_init();
649
650 if (!start_helper(background))
651 return 1;
652
653 if (geteuid() == 0) {
654 if ((pw = getpwnam(SNDIO_USER"_sndio")) == NULL((void*)0))
655 errx(1, "unknown user %s", SNDIO_USER"_sndio");
656 } else
657 pw = NULL((void*)0);
658 getbasepath(base);
659 snprintf(path, SOCKPATH_MAX(1 + sizeof("/tmp/sndio") - 1 + sizeof(char) + sizeof(int) * 3
+ sizeof(char) + sizeof("sock") - 1 + sizeof(int) * 3)
, "%s/" SOCKPATH_FILE"sock" "%u", base, unit);
660 if (!listen_new_un(path))
661 return 1;
662 for (ta = tcpaddr_list; ta != NULL((void*)0); ta = ta->next) {
663 if (!listen_new_tcp(ta->host, AUCAT_PORT11025 + unit))
664 return 1;
665 }
666 for (l = listen_list; l != NULL((void*)0); l = l->next) {
667 if (!listen_init(l))
668 return 1;
669 }
670 midi_init();
671 for (p = port_list; p != NULL((void*)0); p = p->next) {
672 if (!port_init(p))
673 return 1;
674 }
675 for (d = dev_list; d != NULL((void*)0); d = d->next) {
676 if (!dev_init(d))
677 return 1;
678 }
679 for (o = opt_list; o != NULL((void*)0); o = o->next)
680 opt_init(o);
681 if (background) {
682 log_flush();
683 log_level = 0;
684 if (daemon(0, 0) == -1)
685 err(1, "daemon");
686 }
687 if (pw != NULL((void*)0)) {
688 if (setpriority(PRIO_PROCESS0, 0, SNDIO_PRIO(-20)) == -1)
689 err(1, "setpriority");
690 if (chroot(pw->pw_dir) == -1 || chdir("/") == -1)
691 err(1, "cannot chroot to %s", pw->pw_dir);
692 if (setgroups(1, &pw->pw_gid) == -1 ||
693 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
694 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1 )
695 err(1, "cannot drop privileges");
696 }
697 if (tcpaddr_list) {
698 if (pledge("stdio audio recvfd unix inet", NULL((void*)0)) == -1)
699 err(1, "pledge");
700 } else {
701 if (pledge("stdio audio recvfd unix", NULL((void*)0)) == -1)
702 err(1, "pledge");
703 }
704 for (;;) {
705 if (quit_flag)
706 break;
707 if (reopen_flag) {
708 reopen_flag = 0;
709
710 reopen_list = 0;
711 for (d = dev_list; d != NULL((void*)0); d = d->next) {
712 if (d->pstate != DEV_CFG0)
713 reopen_list |= (1 << d->num);
714 }
715 for (d = dev_list; d != NULL((void*)0); d = d->next) {
716 if (reopen_list & (1 << d->num))
717 dev_migrate(d);
718 }
719
720 reopen_list = 0;
721 for (p = port_list; p != NULL((void*)0); p = p->next) {
722 if (p->state != PORT_CFG0)
723 reopen_list |= (1 << p->num);
724 }
725 for (p = port_list; p != NULL((void*)0); p = p->next) {
726 if (reopen_list & (1 << p->num)) {
727 if (port_migrate(p) != p)
728 port_close(p);
729 }
730 }
731 }
732 if (!fdpass_peer)
733 break;
734 if (!file_poll())
735 break;
736 }
737 stop_helper();
738 while (listen_list != NULL((void*)0))
739 listen_close(listen_list);
740 while (sock_list != NULL((void*)0))
741 sock_close(sock_list);
742 for (o = opt_list; o != NULL((void*)0); o = o->next)
743 opt_done(o);
744 for (d = dev_list; d != NULL((void*)0); d = d->next)
745 dev_done(d);
746 for (p = port_list; p != NULL((void*)0); p = p->next)
747 port_done(p);
748 while (file_poll())
749 ; /* nothing */
750 midi_done();
751
752 while (opt_list)
753 opt_del(opt_list);
754 while (dev_list)
755 dev_del(dev_list);
756 while (port_list)
757 port_del(port_list);
758 while (tcpaddr_list) {
759 ta = tcpaddr_list;
760 tcpaddr_list = ta->next;
761 xfree(ta);
762 }
763 filelist_done();
764 unsetsig();
765 return 0;
766}