conf-parser: Add support for parsing property lists.
[pulseaudio-raopUDP/pulseaudio-raop-alac.git] / src / daemon / daemon-conf.c
blobd5fba33f625e3297e6f59465c5c47a4399afee80
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/stat.h>
34 #ifdef HAVE_SCHED_H
35 #include <sched.h>
36 #endif
38 #include <pulse/xmalloc.h>
39 #include <pulse/timeval.h>
40 #include <pulse/version.h>
42 #include <pulsecore/core-error.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/i18n.h>
45 #include <pulsecore/strbuf.h>
46 #include <pulsecore/conf-parser.h>
47 #include <pulsecore/resampler.h>
48 #include <pulsecore/macro.h>
50 #include "daemon-conf.h"
52 #define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "default.pa"
53 #define DEFAULT_SCRIPT_FILE_USER PA_PATH_SEP "default.pa"
54 #define DEFAULT_SYSTEM_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "system.pa"
56 #define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "daemon.conf"
57 #define DEFAULT_CONFIG_FILE_USER PA_PATH_SEP "daemon.conf"
59 #define ENV_SCRIPT_FILE "PULSE_SCRIPT"
60 #define ENV_CONFIG_FILE "PULSE_CONFIG"
61 #define ENV_DL_SEARCH_PATH "PULSE_DLPATH"
63 static const pa_daemon_conf default_conf = {
64 .cmd = PA_CMD_DAEMON,
65 .daemonize = FALSE,
66 .fail = TRUE,
67 .high_priority = TRUE,
68 .nice_level = -11,
69 .realtime_scheduling = TRUE,
70 .realtime_priority = 5, /* Half of JACK's default rtprio */
71 .disallow_module_loading = FALSE,
72 .disallow_exit = FALSE,
73 .flat_volumes = TRUE,
74 .exit_idle_time = 20,
75 .scache_idle_time = 20,
76 .auto_log_target = 1,
77 .script_commands = NULL,
78 .dl_search_path = NULL,
79 .load_default_script_file = TRUE,
80 .default_script_file = NULL,
81 .log_target = PA_LOG_SYSLOG,
82 .log_level = PA_LOG_NOTICE,
83 .log_backtrace = 0,
84 .log_meta = FALSE,
85 .log_time = FALSE,
86 .resample_method = PA_RESAMPLER_AUTO,
87 .disable_remixing = FALSE,
88 .disable_lfe_remixing = TRUE,
89 .config_file = NULL,
90 .use_pid_file = TRUE,
91 .system_instance = FALSE,
92 #ifdef HAVE_DBUS
93 .local_server_type = PA_SERVER_TYPE_UNSET, /* The actual default is _USER, but we have to detect when the user doesn't specify this option. */
94 #endif
95 .no_cpu_limit = TRUE,
96 .disable_shm = FALSE,
97 .lock_memory = FALSE,
98 .deferred_volume = TRUE,
99 .default_n_fragments = 4,
100 .default_fragment_size_msec = 25,
101 .deferred_volume_safety_margin_usec = 8000,
102 .deferred_volume_extra_delay_usec = 0,
103 .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
104 .alternate_sample_rate = 48000,
105 .default_channel_map = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } },
106 .shm_size = 0
107 #ifdef HAVE_SYS_RESOURCE_H
108 ,.rlimit_fsize = { .value = 0, .is_set = FALSE },
109 .rlimit_data = { .value = 0, .is_set = FALSE },
110 .rlimit_stack = { .value = 0, .is_set = FALSE },
111 .rlimit_core = { .value = 0, .is_set = FALSE }
112 #ifdef RLIMIT_RSS
113 ,.rlimit_rss = { .value = 0, .is_set = FALSE }
114 #endif
115 #ifdef RLIMIT_NPROC
116 ,.rlimit_nproc = { .value = 0, .is_set = FALSE }
117 #endif
118 #ifdef RLIMIT_NOFILE
119 ,.rlimit_nofile = { .value = 256, .is_set = TRUE }
120 #endif
121 #ifdef RLIMIT_MEMLOCK
122 ,.rlimit_memlock = { .value = 0, .is_set = FALSE }
123 #endif
124 #ifdef RLIMIT_AS
125 ,.rlimit_as = { .value = 0, .is_set = FALSE }
126 #endif
127 #ifdef RLIMIT_LOCKS
128 ,.rlimit_locks = { .value = 0, .is_set = FALSE }
129 #endif
130 #ifdef RLIMIT_SIGPENDING
131 ,.rlimit_sigpending = { .value = 0, .is_set = FALSE }
132 #endif
133 #ifdef RLIMIT_MSGQUEUE
134 ,.rlimit_msgqueue = { .value = 0, .is_set = FALSE }
135 #endif
136 #ifdef RLIMIT_NICE
137 ,.rlimit_nice = { .value = 31, .is_set = TRUE } /* nice level of -11 */
138 #endif
139 #ifdef RLIMIT_RTPRIO
140 ,.rlimit_rtprio = { .value = 9, .is_set = TRUE } /* One below JACK's default for the server */
141 #endif
142 #ifdef RLIMIT_RTTIME
143 ,.rlimit_rttime = { .value = PA_USEC_PER_SEC, .is_set = TRUE }
144 #endif
145 #endif
148 pa_daemon_conf *pa_daemon_conf_new(void) {
149 pa_daemon_conf *c;
151 c = pa_xnewdup(pa_daemon_conf, &default_conf, 1);
153 #ifdef OS_IS_WIN32
154 c->dl_search_path = pa_sprintf_malloc("%s" PA_PATH_SEP "lib" PA_PATH_SEP "pulse-%d.%d" PA_PATH_SEP "modules",
155 pa_win32_get_toplevel(NULL), PA_MAJOR, PA_MINOR);
156 #else
157 if (pa_run_from_build_tree()) {
158 pa_log_notice("Detected that we are run from the build tree, fixing search path.");
159 c->dl_search_path = pa_xstrdup(PA_BUILDDIR "/.libs/");
160 } else
161 c->dl_search_path = pa_xstrdup(PA_DLSEARCHPATH);
162 #endif
164 return c;
167 void pa_daemon_conf_free(pa_daemon_conf *c) {
168 pa_assert(c);
170 pa_log_set_fd(-1);
172 pa_xfree(c->script_commands);
173 pa_xfree(c->dl_search_path);
174 pa_xfree(c->default_script_file);
175 pa_xfree(c->config_file);
176 pa_xfree(c);
179 int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
180 pa_assert(c);
181 pa_assert(string);
183 if (pa_streq(string, "auto"))
184 c->auto_log_target = 1;
185 else if (pa_streq(string, "syslog")) {
186 c->auto_log_target = 0;
187 c->log_target = PA_LOG_SYSLOG;
188 } else if (pa_streq(string, "stderr")) {
189 c->auto_log_target = 0;
190 c->log_target = PA_LOG_STDERR;
191 } else if (pa_startswith(string, "file:")) {
192 char file_path[512];
193 int log_fd;
195 pa_strlcpy(file_path, string + 5, sizeof(file_path));
197 /* Open target file with user rights */
198 if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
199 c->auto_log_target = 0;
200 c->log_target = PA_LOG_FD;
201 pa_log_set_fd(log_fd);
202 } else {
203 printf("Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
204 return -1;
206 } else
207 return -1;
209 return 0;
212 int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
213 uint32_t u;
214 pa_assert(c);
215 pa_assert(string);
217 if (pa_atou(string, &u) >= 0) {
218 if (u >= PA_LOG_LEVEL_MAX)
219 return -1;
221 c->log_level = (pa_log_level_t) u;
222 } else if (pa_startswith(string, "debug"))
223 c->log_level = PA_LOG_DEBUG;
224 else if (pa_startswith(string, "info"))
225 c->log_level = PA_LOG_INFO;
226 else if (pa_startswith(string, "notice"))
227 c->log_level = PA_LOG_NOTICE;
228 else if (pa_startswith(string, "warn"))
229 c->log_level = PA_LOG_WARN;
230 else if (pa_startswith(string, "err"))
231 c->log_level = PA_LOG_ERROR;
232 else
233 return -1;
235 return 0;
238 int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
239 int m;
240 pa_assert(c);
241 pa_assert(string);
243 if ((m = pa_parse_resample_method(string)) < 0)
244 return -1;
246 c->resample_method = m;
247 return 0;
250 int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string) {
251 pa_assert(c);
252 pa_assert(string);
254 if (pa_streq(string, "user"))
255 c->local_server_type = PA_SERVER_TYPE_USER;
256 else if (pa_streq(string, "system")) {
257 c->local_server_type = PA_SERVER_TYPE_SYSTEM;
258 } else if (pa_streq(string, "none")) {
259 c->local_server_type = PA_SERVER_TYPE_NONE;
260 } else
261 return -1;
263 return 0;
266 static int parse_log_target(pa_config_parser_state *state) {
267 pa_daemon_conf *c;
269 pa_assert(state);
271 c = state->data;
273 if (pa_daemon_conf_set_log_target(c, state->rvalue) < 0) {
274 pa_log(_("[%s:%u] Invalid log target '%s'."), state->filename, state->lineno, state->rvalue);
275 return -1;
278 return 0;
281 static int parse_log_level(pa_config_parser_state *state) {
282 pa_daemon_conf *c;
284 pa_assert(state);
286 c = state->data;
288 if (pa_daemon_conf_set_log_level(c, state->rvalue) < 0) {
289 pa_log(_("[%s:%u] Invalid log level '%s'."), state->filename, state->lineno, state->rvalue);
290 return -1;
293 return 0;
296 static int parse_resample_method(pa_config_parser_state *state) {
297 pa_daemon_conf *c;
299 pa_assert(state);
301 c = state->data;
303 if (pa_daemon_conf_set_resample_method(c, state->rvalue) < 0) {
304 pa_log(_("[%s:%u] Invalid resample method '%s'."), state->filename, state->lineno, state->rvalue);
305 return -1;
308 return 0;
311 #ifdef HAVE_SYS_RESOURCE_H
312 static int parse_rlimit(pa_config_parser_state *state) {
313 struct pa_rlimit *r;
315 pa_assert(state);
317 r = state->data;
319 if (state->rvalue[strspn(state->rvalue, "\t ")] == 0) {
320 /* Empty string */
321 r->is_set = 0;
322 r->value = 0;
323 } else {
324 int32_t k;
325 if (pa_atoi(state->rvalue, &k) < 0) {
326 pa_log(_("[%s:%u] Invalid rlimit '%s'."), state->filename, state->lineno, state->rvalue);
327 return -1;
329 r->is_set = k >= 0;
330 r->value = k >= 0 ? (rlim_t) k : 0;
333 return 0;
335 #endif
337 static int parse_sample_format(pa_config_parser_state *state) {
338 pa_daemon_conf *c;
339 pa_sample_format_t f;
341 pa_assert(state);
343 c = state->data;
345 if ((f = pa_parse_sample_format(state->rvalue)) < 0) {
346 pa_log(_("[%s:%u] Invalid sample format '%s'."), state->filename, state->lineno, state->rvalue);
347 return -1;
350 c->default_sample_spec.format = f;
351 return 0;
354 static int parse_sample_rate(pa_config_parser_state *state) {
355 pa_daemon_conf *c;
356 uint32_t r;
358 pa_assert(state);
360 c = state->data;
362 if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
363 !((r % 4000 == 0) || (r % 11025 == 0))) {
364 pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
365 return -1;
368 c->default_sample_spec.rate = r;
369 return 0;
372 static int parse_alternate_sample_rate(pa_config_parser_state *state) {
373 pa_daemon_conf *c;
374 uint32_t r;
376 pa_assert(state);
378 c = state->data;
380 if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
381 !((r % 4000==0) || (r % 11025 == 0))) {
382 pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
383 return -1;
386 c->alternate_sample_rate = r;
387 return 0;
390 struct channel_conf_info {
391 pa_daemon_conf *conf;
392 pa_bool_t default_sample_spec_set;
393 pa_bool_t default_channel_map_set;
396 static int parse_sample_channels(pa_config_parser_state *state) {
397 struct channel_conf_info *i;
398 int32_t n;
400 pa_assert(state);
402 i = state->data;
404 if (pa_atoi(state->rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
405 pa_log(_("[%s:%u] Invalid sample channels '%s'."), state->filename, state->lineno, state->rvalue);
406 return -1;
409 i->conf->default_sample_spec.channels = (uint8_t) n;
410 i->default_sample_spec_set = TRUE;
411 return 0;
414 static int parse_channel_map(pa_config_parser_state *state) {
415 struct channel_conf_info *i;
417 pa_assert(state);
419 i = state->data;
421 if (!pa_channel_map_parse(&i->conf->default_channel_map, state->rvalue)) {
422 pa_log(_("[%s:%u] Invalid channel map '%s'."), state->filename, state->lineno, state->rvalue);
423 return -1;
426 i->default_channel_map_set = TRUE;
427 return 0;
430 static int parse_fragments(pa_config_parser_state *state) {
431 pa_daemon_conf *c;
432 int32_t n;
434 pa_assert(state);
436 c = state->data;
438 if (pa_atoi(state->rvalue, &n) < 0 || n < 2) {
439 pa_log(_("[%s:%u] Invalid number of fragments '%s'."), state->filename, state->lineno, state->rvalue);
440 return -1;
443 c->default_n_fragments = (unsigned) n;
444 return 0;
447 static int parse_fragment_size_msec(pa_config_parser_state *state) {
448 pa_daemon_conf *c;
449 int32_t n;
451 pa_assert(state);
453 c = state->data;
455 if (pa_atoi(state->rvalue, &n) < 0 || n < 1) {
456 pa_log(_("[%s:%u] Invalid fragment size '%s'."), state->filename, state->lineno, state->rvalue);
457 return -1;
460 c->default_fragment_size_msec = (unsigned) n;
461 return 0;
464 static int parse_nice_level(pa_config_parser_state *state) {
465 pa_daemon_conf *c;
466 int32_t level;
468 pa_assert(state);
470 c = state->data;
472 if (pa_atoi(state->rvalue, &level) < 0 || level < -20 || level > 19) {
473 pa_log(_("[%s:%u] Invalid nice level '%s'."), state->filename, state->lineno, state->rvalue);
474 return -1;
477 c->nice_level = (int) level;
478 return 0;
481 static int parse_rtprio(pa_config_parser_state *state) {
482 #if !defined(OS_IS_WIN32) && defined(HAVE_SCHED_H)
483 pa_daemon_conf *c;
484 int32_t rtprio;
485 #endif
487 pa_assert(state);
489 #ifdef OS_IS_WIN32
490 pa_log("[%s:%u] Realtime priority not available on win32.", state->filename, state->lineno);
491 #else
492 # ifdef HAVE_SCHED_H
493 c = state->data;
495 if (pa_atoi(state->rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
496 pa_log("[%s:%u] Invalid realtime priority '%s'.", state->filename, state->lineno, state->rvalue);
497 return -1;
500 c->realtime_priority = (int) rtprio;
501 # endif
502 #endif /* OS_IS_WIN32 */
504 return 0;
507 #ifdef HAVE_DBUS
508 static int parse_server_type(pa_config_parser_state *state) {
509 pa_daemon_conf *c;
511 pa_assert(state);
513 c = state->data;
515 if (pa_daemon_conf_set_local_server_type(c, state->rvalue) < 0) {
516 pa_log(_("[%s:%u] Invalid server type '%s'."), state->filename, state->lineno, state->rvalue);
517 return -1;
520 return 0;
522 #endif
524 int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
525 int r = -1;
526 FILE *f = NULL;
527 struct channel_conf_info ci;
528 pa_config_item table[] = {
529 { "daemonize", pa_config_parse_bool, &c->daemonize, NULL },
530 { "fail", pa_config_parse_bool, &c->fail, NULL },
531 { "high-priority", pa_config_parse_bool, &c->high_priority, NULL },
532 { "realtime-scheduling", pa_config_parse_bool, &c->realtime_scheduling, NULL },
533 { "disallow-module-loading", pa_config_parse_bool, &c->disallow_module_loading, NULL },
534 { "allow-module-loading", pa_config_parse_not_bool, &c->disallow_module_loading, NULL },
535 { "disallow-exit", pa_config_parse_bool, &c->disallow_exit, NULL },
536 { "allow-exit", pa_config_parse_not_bool, &c->disallow_exit, NULL },
537 { "use-pid-file", pa_config_parse_bool, &c->use_pid_file, NULL },
538 { "system-instance", pa_config_parse_bool, &c->system_instance, NULL },
539 #ifdef HAVE_DBUS
540 { "local-server-type", parse_server_type, c, NULL },
541 #endif
542 { "no-cpu-limit", pa_config_parse_bool, &c->no_cpu_limit, NULL },
543 { "cpu-limit", pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
544 { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
545 { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
546 { "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
547 { "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
548 { "enable-deferred-volume", pa_config_parse_bool, &c->deferred_volume, NULL },
549 { "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
550 { "scache-idle-time", pa_config_parse_int, &c->scache_idle_time, NULL },
551 { "realtime-priority", parse_rtprio, c, NULL },
552 { "dl-search-path", pa_config_parse_string, &c->dl_search_path, NULL },
553 { "default-script-file", pa_config_parse_string, &c->default_script_file, NULL },
554 { "log-target", parse_log_target, c, NULL },
555 { "log-level", parse_log_level, c, NULL },
556 { "verbose", parse_log_level, c, NULL },
557 { "resample-method", parse_resample_method, c, NULL },
558 { "default-sample-format", parse_sample_format, c, NULL },
559 { "default-sample-rate", parse_sample_rate, c, NULL },
560 { "alternate-sample-rate", parse_alternate_sample_rate, c, NULL },
561 { "default-sample-channels", parse_sample_channels, &ci, NULL },
562 { "default-channel-map", parse_channel_map, &ci, NULL },
563 { "default-fragments", parse_fragments, c, NULL },
564 { "default-fragment-size-msec", parse_fragment_size_msec, c, NULL },
565 { "deferred-volume-safety-margin-usec",
566 pa_config_parse_unsigned, &c->deferred_volume_safety_margin_usec, NULL },
567 { "deferred-volume-extra-delay-usec",
568 pa_config_parse_int, &c->deferred_volume_extra_delay_usec, NULL },
569 { "nice-level", parse_nice_level, c, NULL },
570 { "disable-remixing", pa_config_parse_bool, &c->disable_remixing, NULL },
571 { "enable-remixing", pa_config_parse_not_bool, &c->disable_remixing, NULL },
572 { "disable-lfe-remixing", pa_config_parse_bool, &c->disable_lfe_remixing, NULL },
573 { "enable-lfe-remixing", pa_config_parse_not_bool, &c->disable_lfe_remixing, NULL },
574 { "load-default-script-file", pa_config_parse_bool, &c->load_default_script_file, NULL },
575 { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL },
576 { "log-meta", pa_config_parse_bool, &c->log_meta, NULL },
577 { "log-time", pa_config_parse_bool, &c->log_time, NULL },
578 { "log-backtrace", pa_config_parse_unsigned, &c->log_backtrace, NULL },
579 #ifdef HAVE_SYS_RESOURCE_H
580 { "rlimit-fsize", parse_rlimit, &c->rlimit_fsize, NULL },
581 { "rlimit-data", parse_rlimit, &c->rlimit_data, NULL },
582 { "rlimit-stack", parse_rlimit, &c->rlimit_stack, NULL },
583 { "rlimit-core", parse_rlimit, &c->rlimit_core, NULL },
584 #ifdef RLIMIT_RSS
585 { "rlimit-rss", parse_rlimit, &c->rlimit_rss, NULL },
586 #endif
587 #ifdef RLIMIT_NOFILE
588 { "rlimit-nofile", parse_rlimit, &c->rlimit_nofile, NULL },
589 #endif
590 #ifdef RLIMIT_AS
591 { "rlimit-as", parse_rlimit, &c->rlimit_as, NULL },
592 #endif
593 #ifdef RLIMIT_NPROC
594 { "rlimit-nproc", parse_rlimit, &c->rlimit_nproc, NULL },
595 #endif
596 #ifdef RLIMIT_MEMLOCK
597 { "rlimit-memlock", parse_rlimit, &c->rlimit_memlock, NULL },
598 #endif
599 #ifdef RLIMIT_LOCKS
600 { "rlimit-locks", parse_rlimit, &c->rlimit_locks, NULL },
601 #endif
602 #ifdef RLIMIT_SIGPENDING
603 { "rlimit-sigpending", parse_rlimit, &c->rlimit_sigpending, NULL },
604 #endif
605 #ifdef RLIMIT_MSGQUEUE
606 { "rlimit-msgqueue", parse_rlimit, &c->rlimit_msgqueue, NULL },
607 #endif
608 #ifdef RLIMIT_NICE
609 { "rlimit-nice", parse_rlimit, &c->rlimit_nice, NULL },
610 #endif
611 #ifdef RLIMIT_RTPRIO
612 { "rlimit-rtprio", parse_rlimit, &c->rlimit_rtprio, NULL },
613 #endif
614 #ifdef RLIMIT_RTTIME
615 { "rlimit-rttime", parse_rlimit, &c->rlimit_rttime, NULL },
616 #endif
617 #endif
618 { NULL, NULL, NULL, NULL },
621 pa_xfree(c->config_file);
622 c->config_file = NULL;
624 f = filename ?
625 pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") :
626 pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);
628 if (!f && errno != ENOENT) {
629 pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno));
630 goto finish;
633 ci.default_channel_map_set = ci.default_sample_spec_set = FALSE;
634 ci.conf = c;
636 r = f ? pa_config_parse(c->config_file, f, table, NULL, NULL) : 0;
638 if (r >= 0) {
640 /* Make sure that channel map and sample spec fit together */
642 if (ci.default_sample_spec_set &&
643 ci.default_channel_map_set &&
644 c->default_channel_map.channels != c->default_sample_spec.channels) {
645 pa_log_error(_("The specified default channel map has a different number of channels than the specified default number of channels."));
646 r = -1;
647 goto finish;
648 } else if (ci.default_sample_spec_set)
649 pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
650 else if (ci.default_channel_map_set)
651 c->default_sample_spec.channels = c->default_channel_map.channels;
654 finish:
655 if (f)
656 fclose(f);
658 return r;
661 int pa_daemon_conf_env(pa_daemon_conf *c) {
662 char *e;
663 pa_assert(c);
665 if ((e = getenv(ENV_DL_SEARCH_PATH))) {
666 pa_xfree(c->dl_search_path);
667 c->dl_search_path = pa_xstrdup(e);
669 if ((e = getenv(ENV_SCRIPT_FILE))) {
670 pa_xfree(c->default_script_file);
671 c->default_script_file = pa_xstrdup(e);
674 return 0;
677 const char *pa_daemon_conf_get_default_script_file(pa_daemon_conf *c) {
678 pa_assert(c);
680 if (!c->default_script_file) {
681 if (c->system_instance)
682 c->default_script_file = pa_find_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE);
683 else
684 c->default_script_file = pa_find_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE);
687 return c->default_script_file;
690 FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) {
691 FILE *f;
692 pa_assert(c);
694 if (!c->default_script_file) {
695 if (c->system_instance)
696 f = pa_open_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE, &c->default_script_file);
697 else
698 f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file);
699 } else
700 f = pa_fopen_cloexec(c->default_script_file, "r");
702 return f;
705 char *pa_daemon_conf_dump(pa_daemon_conf *c) {
706 static const char* const log_level_to_string[] = {
707 [PA_LOG_DEBUG] = "debug",
708 [PA_LOG_INFO] = "info",
709 [PA_LOG_NOTICE] = "notice",
710 [PA_LOG_WARN] = "warning",
711 [PA_LOG_ERROR] = "error"
714 #ifdef HAVE_DBUS
715 static const char* const server_type_to_string[] = {
716 [PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
717 [PA_SERVER_TYPE_USER] = "user",
718 [PA_SERVER_TYPE_SYSTEM] = "system",
719 [PA_SERVER_TYPE_NONE] = "none"
721 #endif
723 pa_strbuf *s;
724 char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
726 pa_assert(c);
728 s = pa_strbuf_new();
730 if (c->config_file)
731 pa_strbuf_printf(s, _("### Read from configuration file: %s ###\n"), c->config_file);
733 pa_assert(c->log_level < PA_LOG_LEVEL_MAX);
735 pa_strbuf_printf(s, "daemonize = %s\n", pa_yes_no(c->daemonize));
736 pa_strbuf_printf(s, "fail = %s\n", pa_yes_no(c->fail));
737 pa_strbuf_printf(s, "high-priority = %s\n", pa_yes_no(c->high_priority));
738 pa_strbuf_printf(s, "nice-level = %i\n", c->nice_level);
739 pa_strbuf_printf(s, "realtime-scheduling = %s\n", pa_yes_no(c->realtime_scheduling));
740 pa_strbuf_printf(s, "realtime-priority = %i\n", c->realtime_priority);
741 pa_strbuf_printf(s, "allow-module-loading = %s\n", pa_yes_no(!c->disallow_module_loading));
742 pa_strbuf_printf(s, "allow-exit = %s\n", pa_yes_no(!c->disallow_exit));
743 pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file));
744 pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance));
745 #ifdef HAVE_DBUS
746 pa_strbuf_printf(s, "local-server-type = %s\n", server_type_to_string[c->local_server_type]);
747 #endif
748 pa_strbuf_printf(s, "cpu-limit = %s\n", pa_yes_no(!c->no_cpu_limit));
749 pa_strbuf_printf(s, "enable-shm = %s\n", pa_yes_no(!c->disable_shm));
750 pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
751 pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
752 pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
753 pa_strbuf_printf(s, "scache-idle-time = %i\n", c->scache_idle_time);
754 pa_strbuf_printf(s, "dl-search-path = %s\n", pa_strempty(c->dl_search_path));
755 pa_strbuf_printf(s, "default-script-file = %s\n", pa_strempty(pa_daemon_conf_get_default_script_file(c)));
756 pa_strbuf_printf(s, "load-default-script-file = %s\n", pa_yes_no(c->load_default_script_file));
757 pa_strbuf_printf(s, "log-target = %s\n", c->auto_log_target ? "auto" : (c->log_target == PA_LOG_SYSLOG ? "syslog" : "stderr"));
758 pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
759 pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
760 pa_strbuf_printf(s, "enable-remixing = %s\n", pa_yes_no(!c->disable_remixing));
761 pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
762 pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
763 pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
764 pa_strbuf_printf(s, "alternate-sample-rate = %u\n", c->alternate_sample_rate);
765 pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
766 pa_strbuf_printf(s, "default-channel-map = %s\n", pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
767 pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
768 pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
769 pa_strbuf_printf(s, "enable-deferred-volume = %s\n", pa_yes_no(c->deferred_volume));
770 pa_strbuf_printf(s, "deferred-volume-safety-margin-usec = %u\n", c->deferred_volume_safety_margin_usec);
771 pa_strbuf_printf(s, "deferred-volume-extra-delay-usec = %d\n", c->deferred_volume_extra_delay_usec);
772 pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
773 pa_strbuf_printf(s, "log-meta = %s\n", pa_yes_no(c->log_meta));
774 pa_strbuf_printf(s, "log-time = %s\n", pa_yes_no(c->log_time));
775 pa_strbuf_printf(s, "log-backtrace = %u\n", c->log_backtrace);
776 #ifdef HAVE_SYS_RESOURCE_H
777 pa_strbuf_printf(s, "rlimit-fsize = %li\n", c->rlimit_fsize.is_set ? (long int) c->rlimit_fsize.value : -1);
778 pa_strbuf_printf(s, "rlimit-data = %li\n", c->rlimit_data.is_set ? (long int) c->rlimit_data.value : -1);
779 pa_strbuf_printf(s, "rlimit-stack = %li\n", c->rlimit_stack.is_set ? (long int) c->rlimit_stack.value : -1);
780 pa_strbuf_printf(s, "rlimit-core = %li\n", c->rlimit_core.is_set ? (long int) c->rlimit_core.value : -1);
781 #ifdef RLIMIT_RSS
782 pa_strbuf_printf(s, "rlimit-rss = %li\n", c->rlimit_rss.is_set ? (long int) c->rlimit_rss.value : -1);
783 #endif
784 #ifdef RLIMIT_AS
785 pa_strbuf_printf(s, "rlimit-as = %li\n", c->rlimit_as.is_set ? (long int) c->rlimit_as.value : -1);
786 #endif
787 #ifdef RLIMIT_NPROC
788 pa_strbuf_printf(s, "rlimit-nproc = %li\n", c->rlimit_nproc.is_set ? (long int) c->rlimit_nproc.value : -1);
789 #endif
790 #ifdef RLIMIT_NOFILE
791 pa_strbuf_printf(s, "rlimit-nofile = %li\n", c->rlimit_nofile.is_set ? (long int) c->rlimit_nofile.value : -1);
792 #endif
793 #ifdef RLIMIT_MEMLOCK
794 pa_strbuf_printf(s, "rlimit-memlock = %li\n", c->rlimit_memlock.is_set ? (long int) c->rlimit_memlock.value : -1);
795 #endif
796 #ifdef RLIMIT_LOCKS
797 pa_strbuf_printf(s, "rlimit-locks = %li\n", c->rlimit_locks.is_set ? (long int) c->rlimit_locks.value : -1);
798 #endif
799 #ifdef RLIMIT_SIGPENDING
800 pa_strbuf_printf(s, "rlimit-sigpending = %li\n", c->rlimit_sigpending.is_set ? (long int) c->rlimit_sigpending.value : -1);
801 #endif
802 #ifdef RLIMIT_MSGQUEUE
803 pa_strbuf_printf(s, "rlimit-msgqueue = %li\n", c->rlimit_msgqueue.is_set ? (long int) c->rlimit_msgqueue.value : -1);
804 #endif
805 #ifdef RLIMIT_NICE
806 pa_strbuf_printf(s, "rlimit-nice = %li\n", c->rlimit_nice.is_set ? (long int) c->rlimit_nice.value : -1);
807 #endif
808 #ifdef RLIMIT_RTPRIO
809 pa_strbuf_printf(s, "rlimit-rtprio = %li\n", c->rlimit_rtprio.is_set ? (long int) c->rlimit_rtprio.value : -1);
810 #endif
811 #ifdef RLIMIT_RTTIME
812 pa_strbuf_printf(s, "rlimit-rttime = %li\n", c->rlimit_rttime.is_set ? (long int) c->rlimit_rttime.value : -1);
813 #endif
814 #endif
816 return pa_strbuf_tostring_free(s);