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