]> code.delx.au - pulseaudio/blob - src/daemon/daemon-conf.c
cli, log: Improve the set-log-target functionality
[pulseaudio] / src / daemon / daemon-conf.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
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>
33
34 #ifdef HAVE_SCHED_H
35 #include <sched.h>
36 #endif
37
38 #include <pulse/xmalloc.h>
39 #include <pulse/timeval.h>
40 #include <pulse/version.h>
41
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>
49
50 #include "daemon-conf.h"
51
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"
55
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"
58
59 #define ENV_SCRIPT_FILE "PULSE_SCRIPT"
60 #define ENV_CONFIG_FILE "PULSE_CONFIG"
61 #define ENV_DL_SEARCH_PATH "PULSE_DLPATH"
62
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 .script_commands = NULL,
77 .dl_search_path = NULL,
78 .load_default_script_file = TRUE,
79 .default_script_file = NULL,
80 .log_target = NULL,
81 .log_level = PA_LOG_NOTICE,
82 .log_backtrace = 0,
83 .log_meta = FALSE,
84 .log_time = FALSE,
85 .resample_method = PA_RESAMPLER_AUTO,
86 .disable_remixing = FALSE,
87 .disable_lfe_remixing = TRUE,
88 .config_file = NULL,
89 .use_pid_file = TRUE,
90 .system_instance = FALSE,
91 #ifdef HAVE_DBUS
92 .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. */
93 #endif
94 .no_cpu_limit = TRUE,
95 .disable_shm = FALSE,
96 .lock_memory = FALSE,
97 .deferred_volume = TRUE,
98 .default_n_fragments = 4,
99 .default_fragment_size_msec = 25,
100 .deferred_volume_safety_margin_usec = 8000,
101 .deferred_volume_extra_delay_usec = 0,
102 .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
103 .alternate_sample_rate = 48000,
104 .default_channel_map = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } },
105 .shm_size = 0
106 #ifdef HAVE_SYS_RESOURCE_H
107 ,.rlimit_fsize = { .value = 0, .is_set = FALSE },
108 .rlimit_data = { .value = 0, .is_set = FALSE },
109 .rlimit_stack = { .value = 0, .is_set = FALSE },
110 .rlimit_core = { .value = 0, .is_set = FALSE }
111 #ifdef RLIMIT_RSS
112 ,.rlimit_rss = { .value = 0, .is_set = FALSE }
113 #endif
114 #ifdef RLIMIT_NPROC
115 ,.rlimit_nproc = { .value = 0, .is_set = FALSE }
116 #endif
117 #ifdef RLIMIT_NOFILE
118 ,.rlimit_nofile = { .value = 256, .is_set = TRUE }
119 #endif
120 #ifdef RLIMIT_MEMLOCK
121 ,.rlimit_memlock = { .value = 0, .is_set = FALSE }
122 #endif
123 #ifdef RLIMIT_AS
124 ,.rlimit_as = { .value = 0, .is_set = FALSE }
125 #endif
126 #ifdef RLIMIT_LOCKS
127 ,.rlimit_locks = { .value = 0, .is_set = FALSE }
128 #endif
129 #ifdef RLIMIT_SIGPENDING
130 ,.rlimit_sigpending = { .value = 0, .is_set = FALSE }
131 #endif
132 #ifdef RLIMIT_MSGQUEUE
133 ,.rlimit_msgqueue = { .value = 0, .is_set = FALSE }
134 #endif
135 #ifdef RLIMIT_NICE
136 ,.rlimit_nice = { .value = 31, .is_set = TRUE } /* nice level of -11 */
137 #endif
138 #ifdef RLIMIT_RTPRIO
139 ,.rlimit_rtprio = { .value = 9, .is_set = TRUE } /* One below JACK's default for the server */
140 #endif
141 #ifdef RLIMIT_RTTIME
142 ,.rlimit_rttime = { .value = PA_USEC_PER_SEC, .is_set = TRUE }
143 #endif
144 #endif
145 };
146
147 pa_daemon_conf *pa_daemon_conf_new(void) {
148 pa_daemon_conf *c;
149
150 c = pa_xnewdup(pa_daemon_conf, &default_conf, 1);
151
152 #ifdef OS_IS_WIN32
153 c->dl_search_path = pa_sprintf_malloc("%s" PA_PATH_SEP "lib" PA_PATH_SEP "pulse-%d.%d" PA_PATH_SEP "modules",
154 pa_win32_get_toplevel(NULL), PA_MAJOR, PA_MINOR);
155 #else
156 if (pa_run_from_build_tree()) {
157 pa_log_notice("Detected that we are run from the build tree, fixing search path.");
158 c->dl_search_path = pa_xstrdup(PA_BUILDDIR);
159 } else
160 c->dl_search_path = pa_xstrdup(PA_DLSEARCHPATH);
161 #endif
162
163 return c;
164 }
165
166 void pa_daemon_conf_free(pa_daemon_conf *c) {
167 pa_assert(c);
168
169 pa_xfree(c->script_commands);
170 pa_xfree(c->dl_search_path);
171 pa_xfree(c->default_script_file);
172
173 if (c->log_target)
174 pa_log_target_free(c->log_target);
175
176 pa_xfree(c->config_file);
177 pa_xfree(c);
178 }
179
180 int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
181 pa_log_target *log_target = NULL;
182
183 pa_assert(c);
184 pa_assert(string);
185
186 if (!pa_streq(string, "auto")) {
187 log_target = pa_log_parse_target(string);
188
189 if (!log_target)
190 return -1;
191 }
192
193 c->log_target = log_target;
194
195 return 0;
196 }
197
198 int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
199 uint32_t u;
200 pa_assert(c);
201 pa_assert(string);
202
203 if (pa_atou(string, &u) >= 0) {
204 if (u >= PA_LOG_LEVEL_MAX)
205 return -1;
206
207 c->log_level = (pa_log_level_t) u;
208 } else if (pa_startswith(string, "debug"))
209 c->log_level = PA_LOG_DEBUG;
210 else if (pa_startswith(string, "info"))
211 c->log_level = PA_LOG_INFO;
212 else if (pa_startswith(string, "notice"))
213 c->log_level = PA_LOG_NOTICE;
214 else if (pa_startswith(string, "warn"))
215 c->log_level = PA_LOG_WARN;
216 else if (pa_startswith(string, "err"))
217 c->log_level = PA_LOG_ERROR;
218 else
219 return -1;
220
221 return 0;
222 }
223
224 int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
225 int m;
226 pa_assert(c);
227 pa_assert(string);
228
229 if ((m = pa_parse_resample_method(string)) < 0)
230 return -1;
231
232 c->resample_method = m;
233 return 0;
234 }
235
236 int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string) {
237 pa_assert(c);
238 pa_assert(string);
239
240 if (pa_streq(string, "user"))
241 c->local_server_type = PA_SERVER_TYPE_USER;
242 else if (pa_streq(string, "system")) {
243 c->local_server_type = PA_SERVER_TYPE_SYSTEM;
244 } else if (pa_streq(string, "none")) {
245 c->local_server_type = PA_SERVER_TYPE_NONE;
246 } else
247 return -1;
248
249 return 0;
250 }
251
252 static int parse_log_target(pa_config_parser_state *state) {
253 pa_daemon_conf *c;
254
255 pa_assert(state);
256
257 c = state->data;
258
259 if (pa_daemon_conf_set_log_target(c, state->rvalue) < 0) {
260 pa_log(_("[%s:%u] Invalid log target '%s'."), state->filename, state->lineno, state->rvalue);
261 return -1;
262 }
263
264 return 0;
265 }
266
267 static int parse_log_level(pa_config_parser_state *state) {
268 pa_daemon_conf *c;
269
270 pa_assert(state);
271
272 c = state->data;
273
274 if (pa_daemon_conf_set_log_level(c, state->rvalue) < 0) {
275 pa_log(_("[%s:%u] Invalid log level '%s'."), state->filename, state->lineno, state->rvalue);
276 return -1;
277 }
278
279 return 0;
280 }
281
282 static int parse_resample_method(pa_config_parser_state *state) {
283 pa_daemon_conf *c;
284
285 pa_assert(state);
286
287 c = state->data;
288
289 if (pa_daemon_conf_set_resample_method(c, state->rvalue) < 0) {
290 pa_log(_("[%s:%u] Invalid resample method '%s'."), state->filename, state->lineno, state->rvalue);
291 return -1;
292 }
293
294 return 0;
295 }
296
297 #ifdef HAVE_SYS_RESOURCE_H
298 static int parse_rlimit(pa_config_parser_state *state) {
299 struct pa_rlimit *r;
300
301 pa_assert(state);
302
303 r = state->data;
304
305 if (state->rvalue[strspn(state->rvalue, "\t ")] == 0) {
306 /* Empty string */
307 r->is_set = 0;
308 r->value = 0;
309 } else {
310 int32_t k;
311 if (pa_atoi(state->rvalue, &k) < 0) {
312 pa_log(_("[%s:%u] Invalid rlimit '%s'."), state->filename, state->lineno, state->rvalue);
313 return -1;
314 }
315 r->is_set = k >= 0;
316 r->value = k >= 0 ? (rlim_t) k : 0;
317 }
318
319 return 0;
320 }
321 #endif
322
323 static int parse_sample_format(pa_config_parser_state *state) {
324 pa_daemon_conf *c;
325 pa_sample_format_t f;
326
327 pa_assert(state);
328
329 c = state->data;
330
331 if ((f = pa_parse_sample_format(state->rvalue)) < 0) {
332 pa_log(_("[%s:%u] Invalid sample format '%s'."), state->filename, state->lineno, state->rvalue);
333 return -1;
334 }
335
336 c->default_sample_spec.format = f;
337 return 0;
338 }
339
340 static int parse_sample_rate(pa_config_parser_state *state) {
341 pa_daemon_conf *c;
342 uint32_t r;
343
344 pa_assert(state);
345
346 c = state->data;
347
348 if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
349 !((r % 4000 == 0) || (r % 11025 == 0))) {
350 pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
351 return -1;
352 }
353
354 c->default_sample_spec.rate = r;
355 return 0;
356 }
357
358 static int parse_alternate_sample_rate(pa_config_parser_state *state) {
359 pa_daemon_conf *c;
360 uint32_t r;
361
362 pa_assert(state);
363
364 c = state->data;
365
366 if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
367 !((r % 4000==0) || (r % 11025 == 0))) {
368 pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
369 return -1;
370 }
371
372 c->alternate_sample_rate = r;
373 return 0;
374 }
375
376 struct channel_conf_info {
377 pa_daemon_conf *conf;
378 pa_bool_t default_sample_spec_set;
379 pa_bool_t default_channel_map_set;
380 };
381
382 static int parse_sample_channels(pa_config_parser_state *state) {
383 struct channel_conf_info *i;
384 int32_t n;
385
386 pa_assert(state);
387
388 i = state->data;
389
390 if (pa_atoi(state->rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
391 pa_log(_("[%s:%u] Invalid sample channels '%s'."), state->filename, state->lineno, state->rvalue);
392 return -1;
393 }
394
395 i->conf->default_sample_spec.channels = (uint8_t) n;
396 i->default_sample_spec_set = TRUE;
397 return 0;
398 }
399
400 static int parse_channel_map(pa_config_parser_state *state) {
401 struct channel_conf_info *i;
402
403 pa_assert(state);
404
405 i = state->data;
406
407 if (!pa_channel_map_parse(&i->conf->default_channel_map, state->rvalue)) {
408 pa_log(_("[%s:%u] Invalid channel map '%s'."), state->filename, state->lineno, state->rvalue);
409 return -1;
410 }
411
412 i->default_channel_map_set = TRUE;
413 return 0;
414 }
415
416 static int parse_fragments(pa_config_parser_state *state) {
417 pa_daemon_conf *c;
418 int32_t n;
419
420 pa_assert(state);
421
422 c = state->data;
423
424 if (pa_atoi(state->rvalue, &n) < 0 || n < 2) {
425 pa_log(_("[%s:%u] Invalid number of fragments '%s'."), state->filename, state->lineno, state->rvalue);
426 return -1;
427 }
428
429 c->default_n_fragments = (unsigned) n;
430 return 0;
431 }
432
433 static int parse_fragment_size_msec(pa_config_parser_state *state) {
434 pa_daemon_conf *c;
435 int32_t n;
436
437 pa_assert(state);
438
439 c = state->data;
440
441 if (pa_atoi(state->rvalue, &n) < 0 || n < 1) {
442 pa_log(_("[%s:%u] Invalid fragment size '%s'."), state->filename, state->lineno, state->rvalue);
443 return -1;
444 }
445
446 c->default_fragment_size_msec = (unsigned) n;
447 return 0;
448 }
449
450 static int parse_nice_level(pa_config_parser_state *state) {
451 pa_daemon_conf *c;
452 int32_t level;
453
454 pa_assert(state);
455
456 c = state->data;
457
458 if (pa_atoi(state->rvalue, &level) < 0 || level < -20 || level > 19) {
459 pa_log(_("[%s:%u] Invalid nice level '%s'."), state->filename, state->lineno, state->rvalue);
460 return -1;
461 }
462
463 c->nice_level = (int) level;
464 return 0;
465 }
466
467 static int parse_rtprio(pa_config_parser_state *state) {
468 #if !defined(OS_IS_WIN32) && defined(HAVE_SCHED_H)
469 pa_daemon_conf *c;
470 int32_t rtprio;
471 #endif
472
473 pa_assert(state);
474
475 #ifdef OS_IS_WIN32
476 pa_log("[%s:%u] Realtime priority not available on win32.", state->filename, state->lineno);
477 #else
478 # ifdef HAVE_SCHED_H
479 c = state->data;
480
481 if (pa_atoi(state->rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
482 pa_log("[%s:%u] Invalid realtime priority '%s'.", state->filename, state->lineno, state->rvalue);
483 return -1;
484 }
485
486 c->realtime_priority = (int) rtprio;
487 # endif
488 #endif /* OS_IS_WIN32 */
489
490 return 0;
491 }
492
493 #ifdef HAVE_DBUS
494 static int parse_server_type(pa_config_parser_state *state) {
495 pa_daemon_conf *c;
496
497 pa_assert(state);
498
499 c = state->data;
500
501 if (pa_daemon_conf_set_local_server_type(c, state->rvalue) < 0) {
502 pa_log(_("[%s:%u] Invalid server type '%s'."), state->filename, state->lineno, state->rvalue);
503 return -1;
504 }
505
506 return 0;
507 }
508 #endif
509
510 int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
511 int r = -1;
512 FILE *f = NULL;
513 struct channel_conf_info ci;
514 pa_config_item table[] = {
515 { "daemonize", pa_config_parse_bool, &c->daemonize, NULL },
516 { "fail", pa_config_parse_bool, &c->fail, NULL },
517 { "high-priority", pa_config_parse_bool, &c->high_priority, NULL },
518 { "realtime-scheduling", pa_config_parse_bool, &c->realtime_scheduling, NULL },
519 { "disallow-module-loading", pa_config_parse_bool, &c->disallow_module_loading, NULL },
520 { "allow-module-loading", pa_config_parse_not_bool, &c->disallow_module_loading, NULL },
521 { "disallow-exit", pa_config_parse_bool, &c->disallow_exit, NULL },
522 { "allow-exit", pa_config_parse_not_bool, &c->disallow_exit, NULL },
523 { "use-pid-file", pa_config_parse_bool, &c->use_pid_file, NULL },
524 { "system-instance", pa_config_parse_bool, &c->system_instance, NULL },
525 #ifdef HAVE_DBUS
526 { "local-server-type", parse_server_type, c, NULL },
527 #endif
528 { "no-cpu-limit", pa_config_parse_bool, &c->no_cpu_limit, NULL },
529 { "cpu-limit", pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
530 { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
531 { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
532 { "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
533 { "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
534 { "enable-deferred-volume", pa_config_parse_bool, &c->deferred_volume, NULL },
535 { "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
536 { "scache-idle-time", pa_config_parse_int, &c->scache_idle_time, NULL },
537 { "realtime-priority", parse_rtprio, c, NULL },
538 { "dl-search-path", pa_config_parse_string, &c->dl_search_path, NULL },
539 { "default-script-file", pa_config_parse_string, &c->default_script_file, NULL },
540 { "log-target", parse_log_target, c, NULL },
541 { "log-level", parse_log_level, c, NULL },
542 { "verbose", parse_log_level, c, NULL },
543 { "resample-method", parse_resample_method, c, NULL },
544 { "default-sample-format", parse_sample_format, c, NULL },
545 { "default-sample-rate", parse_sample_rate, c, NULL },
546 { "alternate-sample-rate", parse_alternate_sample_rate, c, NULL },
547 { "default-sample-channels", parse_sample_channels, &ci, NULL },
548 { "default-channel-map", parse_channel_map, &ci, NULL },
549 { "default-fragments", parse_fragments, c, NULL },
550 { "default-fragment-size-msec", parse_fragment_size_msec, c, NULL },
551 { "deferred-volume-safety-margin-usec",
552 pa_config_parse_unsigned, &c->deferred_volume_safety_margin_usec, NULL },
553 { "deferred-volume-extra-delay-usec",
554 pa_config_parse_int, &c->deferred_volume_extra_delay_usec, NULL },
555 { "nice-level", parse_nice_level, c, NULL },
556 { "disable-remixing", pa_config_parse_bool, &c->disable_remixing, NULL },
557 { "enable-remixing", pa_config_parse_not_bool, &c->disable_remixing, NULL },
558 { "disable-lfe-remixing", pa_config_parse_bool, &c->disable_lfe_remixing, NULL },
559 { "enable-lfe-remixing", pa_config_parse_not_bool, &c->disable_lfe_remixing, NULL },
560 { "load-default-script-file", pa_config_parse_bool, &c->load_default_script_file, NULL },
561 { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL },
562 { "log-meta", pa_config_parse_bool, &c->log_meta, NULL },
563 { "log-time", pa_config_parse_bool, &c->log_time, NULL },
564 { "log-backtrace", pa_config_parse_unsigned, &c->log_backtrace, NULL },
565 #ifdef HAVE_SYS_RESOURCE_H
566 { "rlimit-fsize", parse_rlimit, &c->rlimit_fsize, NULL },
567 { "rlimit-data", parse_rlimit, &c->rlimit_data, NULL },
568 { "rlimit-stack", parse_rlimit, &c->rlimit_stack, NULL },
569 { "rlimit-core", parse_rlimit, &c->rlimit_core, NULL },
570 #ifdef RLIMIT_RSS
571 { "rlimit-rss", parse_rlimit, &c->rlimit_rss, NULL },
572 #endif
573 #ifdef RLIMIT_NOFILE
574 { "rlimit-nofile", parse_rlimit, &c->rlimit_nofile, NULL },
575 #endif
576 #ifdef RLIMIT_AS
577 { "rlimit-as", parse_rlimit, &c->rlimit_as, NULL },
578 #endif
579 #ifdef RLIMIT_NPROC
580 { "rlimit-nproc", parse_rlimit, &c->rlimit_nproc, NULL },
581 #endif
582 #ifdef RLIMIT_MEMLOCK
583 { "rlimit-memlock", parse_rlimit, &c->rlimit_memlock, NULL },
584 #endif
585 #ifdef RLIMIT_LOCKS
586 { "rlimit-locks", parse_rlimit, &c->rlimit_locks, NULL },
587 #endif
588 #ifdef RLIMIT_SIGPENDING
589 { "rlimit-sigpending", parse_rlimit, &c->rlimit_sigpending, NULL },
590 #endif
591 #ifdef RLIMIT_MSGQUEUE
592 { "rlimit-msgqueue", parse_rlimit, &c->rlimit_msgqueue, NULL },
593 #endif
594 #ifdef RLIMIT_NICE
595 { "rlimit-nice", parse_rlimit, &c->rlimit_nice, NULL },
596 #endif
597 #ifdef RLIMIT_RTPRIO
598 { "rlimit-rtprio", parse_rlimit, &c->rlimit_rtprio, NULL },
599 #endif
600 #ifdef RLIMIT_RTTIME
601 { "rlimit-rttime", parse_rlimit, &c->rlimit_rttime, NULL },
602 #endif
603 #endif
604 { NULL, NULL, NULL, NULL },
605 };
606
607 pa_xfree(c->config_file);
608 c->config_file = NULL;
609
610 f = filename ?
611 pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") :
612 pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);
613
614 if (!f && errno != ENOENT) {
615 pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno));
616 goto finish;
617 }
618
619 ci.default_channel_map_set = ci.default_sample_spec_set = FALSE;
620 ci.conf = c;
621
622 r = f ? pa_config_parse(c->config_file, f, table, NULL, NULL) : 0;
623
624 if (r >= 0) {
625
626 /* Make sure that channel map and sample spec fit together */
627
628 if (ci.default_sample_spec_set &&
629 ci.default_channel_map_set &&
630 c->default_channel_map.channels != c->default_sample_spec.channels) {
631 pa_log_error(_("The specified default channel map has a different number of channels than the specified default number of channels."));
632 r = -1;
633 goto finish;
634 } else if (ci.default_sample_spec_set)
635 pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
636 else if (ci.default_channel_map_set)
637 c->default_sample_spec.channels = c->default_channel_map.channels;
638 }
639
640 finish:
641 if (f)
642 fclose(f);
643
644 return r;
645 }
646
647 int pa_daemon_conf_env(pa_daemon_conf *c) {
648 char *e;
649 pa_assert(c);
650
651 if ((e = getenv(ENV_DL_SEARCH_PATH))) {
652 pa_xfree(c->dl_search_path);
653 c->dl_search_path = pa_xstrdup(e);
654 }
655 if ((e = getenv(ENV_SCRIPT_FILE))) {
656 pa_xfree(c->default_script_file);
657 c->default_script_file = pa_xstrdup(e);
658 }
659
660 return 0;
661 }
662
663 const char *pa_daemon_conf_get_default_script_file(pa_daemon_conf *c) {
664 pa_assert(c);
665
666 if (!c->default_script_file) {
667 if (c->system_instance)
668 c->default_script_file = pa_find_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE);
669 else
670 c->default_script_file = pa_find_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE);
671 }
672
673 return c->default_script_file;
674 }
675
676 FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) {
677 FILE *f;
678 pa_assert(c);
679
680 if (!c->default_script_file) {
681 if (c->system_instance)
682 f = pa_open_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE, &c->default_script_file);
683 else
684 f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file);
685 } else
686 f = pa_fopen_cloexec(c->default_script_file, "r");
687
688 return f;
689 }
690
691 char *pa_daemon_conf_dump(pa_daemon_conf *c) {
692 static const char* const log_level_to_string[] = {
693 [PA_LOG_DEBUG] = "debug",
694 [PA_LOG_INFO] = "info",
695 [PA_LOG_NOTICE] = "notice",
696 [PA_LOG_WARN] = "warning",
697 [PA_LOG_ERROR] = "error"
698 };
699
700 #ifdef HAVE_DBUS
701 static const char* const server_type_to_string[] = {
702 [PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
703 [PA_SERVER_TYPE_USER] = "user",
704 [PA_SERVER_TYPE_SYSTEM] = "system",
705 [PA_SERVER_TYPE_NONE] = "none"
706 };
707 #endif
708
709 pa_strbuf *s;
710 char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
711 char *log_target = NULL;
712
713 pa_assert(c);
714
715 s = pa_strbuf_new();
716
717 if (c->config_file)
718 pa_strbuf_printf(s, _("### Read from configuration file: %s ###\n"), c->config_file);
719
720 pa_assert(c->log_level < PA_LOG_LEVEL_MAX);
721
722 if (c->log_target)
723 log_target = pa_log_target_to_string(c->log_target);
724
725 pa_strbuf_printf(s, "daemonize = %s\n", pa_yes_no(c->daemonize));
726 pa_strbuf_printf(s, "fail = %s\n", pa_yes_no(c->fail));
727 pa_strbuf_printf(s, "high-priority = %s\n", pa_yes_no(c->high_priority));
728 pa_strbuf_printf(s, "nice-level = %i\n", c->nice_level);
729 pa_strbuf_printf(s, "realtime-scheduling = %s\n", pa_yes_no(c->realtime_scheduling));
730 pa_strbuf_printf(s, "realtime-priority = %i\n", c->realtime_priority);
731 pa_strbuf_printf(s, "allow-module-loading = %s\n", pa_yes_no(!c->disallow_module_loading));
732 pa_strbuf_printf(s, "allow-exit = %s\n", pa_yes_no(!c->disallow_exit));
733 pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file));
734 pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance));
735 #ifdef HAVE_DBUS
736 pa_strbuf_printf(s, "local-server-type = %s\n", server_type_to_string[c->local_server_type]);
737 #endif
738 pa_strbuf_printf(s, "cpu-limit = %s\n", pa_yes_no(!c->no_cpu_limit));
739 pa_strbuf_printf(s, "enable-shm = %s\n", pa_yes_no(!c->disable_shm));
740 pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
741 pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
742 pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
743 pa_strbuf_printf(s, "scache-idle-time = %i\n", c->scache_idle_time);
744 pa_strbuf_printf(s, "dl-search-path = %s\n", pa_strempty(c->dl_search_path));
745 pa_strbuf_printf(s, "default-script-file = %s\n", pa_strempty(pa_daemon_conf_get_default_script_file(c)));
746 pa_strbuf_printf(s, "load-default-script-file = %s\n", pa_yes_no(c->load_default_script_file));
747 pa_strbuf_printf(s, "log-target = %s\n", pa_strempty(log_target));
748 pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
749 pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
750 pa_strbuf_printf(s, "enable-remixing = %s\n", pa_yes_no(!c->disable_remixing));
751 pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
752 pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
753 pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
754 pa_strbuf_printf(s, "alternate-sample-rate = %u\n", c->alternate_sample_rate);
755 pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
756 pa_strbuf_printf(s, "default-channel-map = %s\n", pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
757 pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
758 pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
759 pa_strbuf_printf(s, "enable-deferred-volume = %s\n", pa_yes_no(c->deferred_volume));
760 pa_strbuf_printf(s, "deferred-volume-safety-margin-usec = %u\n", c->deferred_volume_safety_margin_usec);
761 pa_strbuf_printf(s, "deferred-volume-extra-delay-usec = %d\n", c->deferred_volume_extra_delay_usec);
762 pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
763 pa_strbuf_printf(s, "log-meta = %s\n", pa_yes_no(c->log_meta));
764 pa_strbuf_printf(s, "log-time = %s\n", pa_yes_no(c->log_time));
765 pa_strbuf_printf(s, "log-backtrace = %u\n", c->log_backtrace);
766 #ifdef HAVE_SYS_RESOURCE_H
767 pa_strbuf_printf(s, "rlimit-fsize = %li\n", c->rlimit_fsize.is_set ? (long int) c->rlimit_fsize.value : -1);
768 pa_strbuf_printf(s, "rlimit-data = %li\n", c->rlimit_data.is_set ? (long int) c->rlimit_data.value : -1);
769 pa_strbuf_printf(s, "rlimit-stack = %li\n", c->rlimit_stack.is_set ? (long int) c->rlimit_stack.value : -1);
770 pa_strbuf_printf(s, "rlimit-core = %li\n", c->rlimit_core.is_set ? (long int) c->rlimit_core.value : -1);
771 #ifdef RLIMIT_RSS
772 pa_strbuf_printf(s, "rlimit-rss = %li\n", c->rlimit_rss.is_set ? (long int) c->rlimit_rss.value : -1);
773 #endif
774 #ifdef RLIMIT_AS
775 pa_strbuf_printf(s, "rlimit-as = %li\n", c->rlimit_as.is_set ? (long int) c->rlimit_as.value : -1);
776 #endif
777 #ifdef RLIMIT_NPROC
778 pa_strbuf_printf(s, "rlimit-nproc = %li\n", c->rlimit_nproc.is_set ? (long int) c->rlimit_nproc.value : -1);
779 #endif
780 #ifdef RLIMIT_NOFILE
781 pa_strbuf_printf(s, "rlimit-nofile = %li\n", c->rlimit_nofile.is_set ? (long int) c->rlimit_nofile.value : -1);
782 #endif
783 #ifdef RLIMIT_MEMLOCK
784 pa_strbuf_printf(s, "rlimit-memlock = %li\n", c->rlimit_memlock.is_set ? (long int) c->rlimit_memlock.value : -1);
785 #endif
786 #ifdef RLIMIT_LOCKS
787 pa_strbuf_printf(s, "rlimit-locks = %li\n", c->rlimit_locks.is_set ? (long int) c->rlimit_locks.value : -1);
788 #endif
789 #ifdef RLIMIT_SIGPENDING
790 pa_strbuf_printf(s, "rlimit-sigpending = %li\n", c->rlimit_sigpending.is_set ? (long int) c->rlimit_sigpending.value : -1);
791 #endif
792 #ifdef RLIMIT_MSGQUEUE
793 pa_strbuf_printf(s, "rlimit-msgqueue = %li\n", c->rlimit_msgqueue.is_set ? (long int) c->rlimit_msgqueue.value : -1);
794 #endif
795 #ifdef RLIMIT_NICE
796 pa_strbuf_printf(s, "rlimit-nice = %li\n", c->rlimit_nice.is_set ? (long int) c->rlimit_nice.value : -1);
797 #endif
798 #ifdef RLIMIT_RTPRIO
799 pa_strbuf_printf(s, "rlimit-rtprio = %li\n", c->rlimit_rtprio.is_set ? (long int) c->rlimit_rtprio.value : -1);
800 #endif
801 #ifdef RLIMIT_RTTIME
802 pa_strbuf_printf(s, "rlimit-rttime = %li\n", c->rlimit_rttime.is_set ? (long int) c->rlimit_rttime.value : -1);
803 #endif
804 #endif
805
806 pa_xfree(log_target);
807
808 return pa_strbuf_tostring_free(s);
809 }