]> code.delx.au - pulseaudio/blob - src/daemon/daemon-conf.c
volume: Rename 'sync volume' to 'deferred volume'.
[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 .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 .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 "/.libs/");
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_log_set_fd(-1);
170
171 pa_xfree(c->script_commands);
172 pa_xfree(c->dl_search_path);
173 pa_xfree(c->default_script_file);
174 pa_xfree(c->config_file);
175 pa_xfree(c);
176 }
177
178 int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
179 pa_assert(c);
180 pa_assert(string);
181
182 if (!strcmp(string, "auto"))
183 c->auto_log_target = 1;
184 else if (!strcmp(string, "syslog")) {
185 c->auto_log_target = 0;
186 c->log_target = PA_LOG_SYSLOG;
187 } else if (!strcmp(string, "stderr")) {
188 c->auto_log_target = 0;
189 c->log_target = PA_LOG_STDERR;
190 } else if (pa_startswith(string, "file:")) {
191 char file_path[512];
192 int log_fd;
193
194 pa_strlcpy(file_path, string + 5, sizeof(file_path));
195
196 /* Open target file with user rights */
197 if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
198 c->auto_log_target = 0;
199 c->log_target = PA_LOG_FD;
200 pa_log_set_fd(log_fd);
201 } else {
202 printf("Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
203 return -1;
204 }
205 } else
206 return -1;
207
208 return 0;
209 }
210
211 int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
212 uint32_t u;
213 pa_assert(c);
214 pa_assert(string);
215
216 if (pa_atou(string, &u) >= 0) {
217 if (u >= PA_LOG_LEVEL_MAX)
218 return -1;
219
220 c->log_level = (pa_log_level_t) u;
221 } else if (pa_startswith(string, "debug"))
222 c->log_level = PA_LOG_DEBUG;
223 else if (pa_startswith(string, "info"))
224 c->log_level = PA_LOG_INFO;
225 else if (pa_startswith(string, "notice"))
226 c->log_level = PA_LOG_NOTICE;
227 else if (pa_startswith(string, "warn"))
228 c->log_level = PA_LOG_WARN;
229 else if (pa_startswith(string, "err"))
230 c->log_level = PA_LOG_ERROR;
231 else
232 return -1;
233
234 return 0;
235 }
236
237 int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
238 int m;
239 pa_assert(c);
240 pa_assert(string);
241
242 if ((m = pa_parse_resample_method(string)) < 0)
243 return -1;
244
245 c->resample_method = m;
246 return 0;
247 }
248
249 int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string) {
250 pa_assert(c);
251 pa_assert(string);
252
253 if (!strcmp(string, "user"))
254 c->local_server_type = PA_SERVER_TYPE_USER;
255 else if (!strcmp(string, "system")) {
256 c->local_server_type = PA_SERVER_TYPE_SYSTEM;
257 } else if (!strcmp(string, "none")) {
258 c->local_server_type = PA_SERVER_TYPE_NONE;
259 } else
260 return -1;
261
262 return 0;
263 }
264
265 static int parse_log_target(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
266 pa_daemon_conf *c = data;
267
268 pa_assert(filename);
269 pa_assert(lvalue);
270 pa_assert(rvalue);
271 pa_assert(data);
272
273 if (pa_daemon_conf_set_log_target(c, rvalue) < 0) {
274 pa_log(_("[%s:%u] Invalid log target '%s'."), filename, line, rvalue);
275 return -1;
276 }
277
278 return 0;
279 }
280
281 static int parse_log_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
282 pa_daemon_conf *c = data;
283
284 pa_assert(filename);
285 pa_assert(lvalue);
286 pa_assert(rvalue);
287 pa_assert(data);
288
289 if (pa_daemon_conf_set_log_level(c, rvalue) < 0) {
290 pa_log(_("[%s:%u] Invalid log level '%s'."), filename, line, rvalue);
291 return -1;
292 }
293
294 return 0;
295 }
296
297 static int parse_resample_method(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
298 pa_daemon_conf *c = data;
299
300 pa_assert(filename);
301 pa_assert(lvalue);
302 pa_assert(rvalue);
303 pa_assert(data);
304
305 if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) {
306 pa_log(_("[%s:%u] Invalid resample method '%s'."), filename, line, rvalue);
307 return -1;
308 }
309
310 return 0;
311 }
312
313 #ifdef HAVE_SYS_RESOURCE_H
314 static int parse_rlimit(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
315 struct pa_rlimit *r = data;
316
317 pa_assert(filename);
318 pa_assert(lvalue);
319 pa_assert(rvalue);
320 pa_assert(r);
321
322 if (rvalue[strspn(rvalue, "\t ")] == 0) {
323 /* Empty string */
324 r->is_set = 0;
325 r->value = 0;
326 } else {
327 int32_t k;
328 if (pa_atoi(rvalue, &k) < 0) {
329 pa_log(_("[%s:%u] Invalid rlimit '%s'."), filename, line, rvalue);
330 return -1;
331 }
332 r->is_set = k >= 0;
333 r->value = k >= 0 ? (rlim_t) k : 0;
334 }
335
336 return 0;
337 }
338 #endif
339
340 static int parse_sample_format(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
341 pa_daemon_conf *c = data;
342 pa_sample_format_t f;
343
344 pa_assert(filename);
345 pa_assert(lvalue);
346 pa_assert(rvalue);
347 pa_assert(data);
348
349 if ((f = pa_parse_sample_format(rvalue)) < 0) {
350 pa_log(_("[%s:%u] Invalid sample format '%s'."), filename, line, rvalue);
351 return -1;
352 }
353
354 c->default_sample_spec.format = f;
355 return 0;
356 }
357
358 static int parse_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
359 pa_daemon_conf *c = data;
360 uint32_t r;
361
362 pa_assert(filename);
363 pa_assert(lvalue);
364 pa_assert(rvalue);
365 pa_assert(data);
366
367 if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) {
368 pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
369 return -1;
370 }
371
372 c->default_sample_spec.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(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
383 struct channel_conf_info *i = data;
384 int32_t n;
385
386 pa_assert(filename);
387 pa_assert(lvalue);
388 pa_assert(rvalue);
389 pa_assert(data);
390
391 if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
392 pa_log(_("[%s:%u] Invalid sample channels '%s'."), filename, line, rvalue);
393 return -1;
394 }
395
396 i->conf->default_sample_spec.channels = (uint8_t) n;
397 i->default_sample_spec_set = TRUE;
398 return 0;
399 }
400
401 static int parse_channel_map(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
402 struct channel_conf_info *i = data;
403
404 pa_assert(filename);
405 pa_assert(lvalue);
406 pa_assert(rvalue);
407 pa_assert(data);
408
409 if (!pa_channel_map_parse(&i->conf->default_channel_map, rvalue)) {
410 pa_log(_("[%s:%u] Invalid channel map '%s'."), filename, line, rvalue);
411 return -1;
412 }
413
414 i->default_channel_map_set = TRUE;
415 return 0;
416 }
417
418 static int parse_fragments(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
419 pa_daemon_conf *c = data;
420 int32_t n;
421
422 pa_assert(filename);
423 pa_assert(lvalue);
424 pa_assert(rvalue);
425 pa_assert(data);
426
427 if (pa_atoi(rvalue, &n) < 0 || n < 2) {
428 pa_log(_("[%s:%u] Invalid number of fragments '%s'."), filename, line, rvalue);
429 return -1;
430 }
431
432 c->default_n_fragments = (unsigned) n;
433 return 0;
434 }
435
436 static int parse_fragment_size_msec(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
437 pa_daemon_conf *c = data;
438 int32_t n;
439
440 pa_assert(filename);
441 pa_assert(lvalue);
442 pa_assert(rvalue);
443 pa_assert(data);
444
445 if (pa_atoi(rvalue, &n) < 0 || n < 1) {
446 pa_log(_("[%s:%u] Invalid fragment size '%s'."), filename, line, rvalue);
447 return -1;
448 }
449
450 c->default_fragment_size_msec = (unsigned) n;
451 return 0;
452 }
453
454 static int parse_nice_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
455 pa_daemon_conf *c = data;
456 int32_t level;
457
458 pa_assert(filename);
459 pa_assert(lvalue);
460 pa_assert(rvalue);
461 pa_assert(data);
462
463 if (pa_atoi(rvalue, &level) < 0 || level < -20 || level > 19) {
464 pa_log(_("[%s:%u] Invalid nice level '%s'."), filename, line, rvalue);
465 return -1;
466 }
467
468 c->nice_level = (int) level;
469 return 0;
470 }
471
472 static int parse_rtprio(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
473 #ifdef OS_IS_WIN32
474 pa_log("[%s:%u] Realtime priority not available on win32.", filename, line);
475 #else
476 # ifdef HAVE_SCHED_H
477 pa_daemon_conf *c = data;
478 int32_t rtprio;
479
480 pa_assert(filename);
481 pa_assert(lvalue);
482 pa_assert(rvalue);
483 pa_assert(data);
484
485 if (pa_atoi(rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
486 pa_log("[%s:%u] Invalid realtime priority '%s'.", filename, line, rvalue);
487 return -1;
488 }
489
490 c->realtime_priority = (int) rtprio;
491 # endif
492 #endif /* OS_IS_WIN32 */
493
494 return 0;
495 }
496
497 #ifdef HAVE_DBUS
498 static int parse_server_type(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
499 pa_daemon_conf *c = data;
500
501 pa_assert(filename);
502 pa_assert(lvalue);
503 pa_assert(rvalue);
504 pa_assert(data);
505
506 if (pa_daemon_conf_set_local_server_type(c, rvalue) < 0) {
507 pa_log(_("[%s:%u] Invalid server type '%s'."), filename, line, rvalue);
508 return -1;
509 }
510
511 return 0;
512 }
513 #endif
514
515 int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
516 int r = -1;
517 FILE *f = NULL;
518 struct channel_conf_info ci;
519 pa_config_item table[] = {
520 { "daemonize", pa_config_parse_bool, &c->daemonize, NULL },
521 { "fail", pa_config_parse_bool, &c->fail, NULL },
522 { "high-priority", pa_config_parse_bool, &c->high_priority, NULL },
523 { "realtime-scheduling", pa_config_parse_bool, &c->realtime_scheduling, NULL },
524 { "disallow-module-loading", pa_config_parse_bool, &c->disallow_module_loading, NULL },
525 { "allow-module-loading", pa_config_parse_not_bool, &c->disallow_module_loading, NULL },
526 { "disallow-exit", pa_config_parse_bool, &c->disallow_exit, NULL },
527 { "allow-exit", pa_config_parse_not_bool, &c->disallow_exit, NULL },
528 { "use-pid-file", pa_config_parse_bool, &c->use_pid_file, NULL },
529 { "system-instance", pa_config_parse_bool, &c->system_instance, NULL },
530 #ifdef HAVE_DBUS
531 { "local-server-type", parse_server_type, c, NULL },
532 #endif
533 { "no-cpu-limit", pa_config_parse_bool, &c->no_cpu_limit, NULL },
534 { "cpu-limit", pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
535 { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
536 { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
537 { "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
538 { "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
539 { "enable-deferred-volume", pa_config_parse_bool, &c->deferred_volume, NULL },
540 { "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
541 { "scache-idle-time", pa_config_parse_int, &c->scache_idle_time, NULL },
542 { "realtime-priority", parse_rtprio, c, NULL },
543 { "dl-search-path", pa_config_parse_string, &c->dl_search_path, NULL },
544 { "default-script-file", pa_config_parse_string, &c->default_script_file, NULL },
545 { "log-target", parse_log_target, c, NULL },
546 { "log-level", parse_log_level, c, NULL },
547 { "verbose", parse_log_level, c, NULL },
548 { "resample-method", parse_resample_method, c, NULL },
549 { "default-sample-format", parse_sample_format, c, NULL },
550 { "default-sample-rate", parse_sample_rate, c, NULL },
551 { "default-sample-channels", parse_sample_channels, &ci, NULL },
552 { "default-channel-map", parse_channel_map, &ci, NULL },
553 { "default-fragments", parse_fragments, c, NULL },
554 { "default-fragment-size-msec", parse_fragment_size_msec, c, NULL },
555 { "deferred-volume-safety-margin-usec",
556 pa_config_parse_unsigned, &c->deferred_volume_safety_margin_usec, NULL },
557 { "deferred-volume-extra-delay-usec",
558 pa_config_parse_int, &c->deferred_volume_extra_delay_usec, NULL },
559 { "nice-level", parse_nice_level, c, NULL },
560 { "disable-remixing", pa_config_parse_bool, &c->disable_remixing, NULL },
561 { "enable-remixing", pa_config_parse_not_bool, &c->disable_remixing, NULL },
562 { "disable-lfe-remixing", pa_config_parse_bool, &c->disable_lfe_remixing, NULL },
563 { "enable-lfe-remixing", pa_config_parse_not_bool, &c->disable_lfe_remixing, NULL },
564 { "load-default-script-file", pa_config_parse_bool, &c->load_default_script_file, NULL },
565 { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL },
566 { "log-meta", pa_config_parse_bool, &c->log_meta, NULL },
567 { "log-time", pa_config_parse_bool, &c->log_time, NULL },
568 { "log-backtrace", pa_config_parse_unsigned, &c->log_backtrace, NULL },
569 #ifdef HAVE_SYS_RESOURCE_H
570 { "rlimit-fsize", parse_rlimit, &c->rlimit_fsize, NULL },
571 { "rlimit-data", parse_rlimit, &c->rlimit_data, NULL },
572 { "rlimit-stack", parse_rlimit, &c->rlimit_stack, NULL },
573 { "rlimit-core", parse_rlimit, &c->rlimit_core, NULL },
574 #ifdef RLIMIT_RSS
575 { "rlimit-rss", parse_rlimit, &c->rlimit_rss, NULL },
576 #endif
577 #ifdef RLIMIT_NOFILE
578 { "rlimit-nofile", parse_rlimit, &c->rlimit_nofile, NULL },
579 #endif
580 #ifdef RLIMIT_AS
581 { "rlimit-as", parse_rlimit, &c->rlimit_as, NULL },
582 #endif
583 #ifdef RLIMIT_NPROC
584 { "rlimit-nproc", parse_rlimit, &c->rlimit_nproc, NULL },
585 #endif
586 #ifdef RLIMIT_MEMLOCK
587 { "rlimit-memlock", parse_rlimit, &c->rlimit_memlock, NULL },
588 #endif
589 #ifdef RLIMIT_LOCKS
590 { "rlimit-locks", parse_rlimit, &c->rlimit_locks, NULL },
591 #endif
592 #ifdef RLIMIT_SIGPENDING
593 { "rlimit-sigpending", parse_rlimit, &c->rlimit_sigpending, NULL },
594 #endif
595 #ifdef RLIMIT_MSGQUEUE
596 { "rlimit-msgqueue", parse_rlimit, &c->rlimit_msgqueue, NULL },
597 #endif
598 #ifdef RLIMIT_NICE
599 { "rlimit-nice", parse_rlimit, &c->rlimit_nice, NULL },
600 #endif
601 #ifdef RLIMIT_RTPRIO
602 { "rlimit-rtprio", parse_rlimit, &c->rlimit_rtprio, NULL },
603 #endif
604 #ifdef RLIMIT_RTTIME
605 { "rlimit-rttime", parse_rlimit, &c->rlimit_rttime, NULL },
606 #endif
607 #endif
608 { NULL, NULL, NULL, NULL },
609 };
610
611 pa_xfree(c->config_file);
612 c->config_file = NULL;
613
614 f = filename ?
615 pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") :
616 pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);
617
618 if (!f && errno != ENOENT) {
619 pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno));
620 goto finish;
621 }
622
623 ci.default_channel_map_set = ci.default_sample_spec_set = FALSE;
624 ci.conf = c;
625
626 r = f ? pa_config_parse(c->config_file, f, table, NULL) : 0;
627
628 if (r >= 0) {
629
630 /* Make sure that channel map and sample spec fit together */
631
632 if (ci.default_sample_spec_set &&
633 ci.default_channel_map_set &&
634 c->default_channel_map.channels != c->default_sample_spec.channels) {
635 pa_log_error(_("The specified default channel map has a different number of channels than the specified default number of channels."));
636 r = -1;
637 goto finish;
638 } else if (ci.default_sample_spec_set)
639 pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
640 else if (ci.default_channel_map_set)
641 c->default_sample_spec.channels = c->default_channel_map.channels;
642 }
643
644 finish:
645 if (f)
646 fclose(f);
647
648 return r;
649 }
650
651 int pa_daemon_conf_env(pa_daemon_conf *c) {
652 char *e;
653 pa_assert(c);
654
655 if ((e = getenv(ENV_DL_SEARCH_PATH))) {
656 pa_xfree(c->dl_search_path);
657 c->dl_search_path = pa_xstrdup(e);
658 }
659 if ((e = getenv(ENV_SCRIPT_FILE))) {
660 pa_xfree(c->default_script_file);
661 c->default_script_file = pa_xstrdup(e);
662 }
663
664 return 0;
665 }
666
667 const char *pa_daemon_conf_get_default_script_file(pa_daemon_conf *c) {
668 pa_assert(c);
669
670 if (!c->default_script_file) {
671 if (c->system_instance)
672 c->default_script_file = pa_find_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE);
673 else
674 c->default_script_file = pa_find_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE);
675 }
676
677 return c->default_script_file;
678 }
679
680 FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) {
681 FILE *f;
682 pa_assert(c);
683
684 if (!c->default_script_file) {
685 if (c->system_instance)
686 f = pa_open_config_file(DEFAULT_SYSTEM_SCRIPT_FILE, NULL, ENV_SCRIPT_FILE, &c->default_script_file);
687 else
688 f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file);
689 } else
690 f = pa_fopen_cloexec(c->default_script_file, "r");
691
692 return f;
693 }
694
695 char *pa_daemon_conf_dump(pa_daemon_conf *c) {
696 static const char* const log_level_to_string[] = {
697 [PA_LOG_DEBUG] = "debug",
698 [PA_LOG_INFO] = "info",
699 [PA_LOG_NOTICE] = "notice",
700 [PA_LOG_WARN] = "warning",
701 [PA_LOG_ERROR] = "error"
702 };
703
704 #ifdef HAVE_DBUS
705 static const char* const server_type_to_string[] = {
706 [PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
707 [PA_SERVER_TYPE_USER] = "user",
708 [PA_SERVER_TYPE_SYSTEM] = "system",
709 [PA_SERVER_TYPE_NONE] = "none"
710 };
711 #endif
712
713 pa_strbuf *s;
714 char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
715
716 pa_assert(c);
717
718 s = pa_strbuf_new();
719
720 if (c->config_file)
721 pa_strbuf_printf(s, _("### Read from configuration file: %s ###\n"), c->config_file);
722
723 pa_assert(c->log_level < PA_LOG_LEVEL_MAX);
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", c->auto_log_target ? "auto" : (c->log_target == PA_LOG_SYSLOG ? "syslog" : "stderr"));
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, "default-sample-channels = %u\n", c->default_sample_spec.channels);
755 pa_strbuf_printf(s, "default-channel-map = %s\n", pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
756 pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
757 pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
758 pa_strbuf_printf(s, "enable-deferred-volume = %s\n", pa_yes_no(c->deferred_volume));
759 pa_strbuf_printf(s, "deferred-volume-safety-margin-usec = %u\n", c->deferred_volume_safety_margin_usec);
760 pa_strbuf_printf(s, "deferred-volume-extra-delay-usec = %d\n", c->deferred_volume_extra_delay_usec);
761 pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
762 pa_strbuf_printf(s, "log-meta = %s\n", pa_yes_no(c->log_meta));
763 pa_strbuf_printf(s, "log-time = %s\n", pa_yes_no(c->log_time));
764 pa_strbuf_printf(s, "log-backtrace = %u\n", c->log_backtrace);
765 #ifdef HAVE_SYS_RESOURCE_H
766 pa_strbuf_printf(s, "rlimit-fsize = %li\n", c->rlimit_fsize.is_set ? (long int) c->rlimit_fsize.value : -1);
767 pa_strbuf_printf(s, "rlimit-data = %li\n", c->rlimit_data.is_set ? (long int) c->rlimit_data.value : -1);
768 pa_strbuf_printf(s, "rlimit-stack = %li\n", c->rlimit_stack.is_set ? (long int) c->rlimit_stack.value : -1);
769 pa_strbuf_printf(s, "rlimit-core = %li\n", c->rlimit_core.is_set ? (long int) c->rlimit_core.value : -1);
770 #ifdef RLIMIT_RSS
771 pa_strbuf_printf(s, "rlimit-rss = %li\n", c->rlimit_rss.is_set ? (long int) c->rlimit_rss.value : -1);
772 #endif
773 #ifdef RLIMIT_AS
774 pa_strbuf_printf(s, "rlimit-as = %li\n", c->rlimit_as.is_set ? (long int) c->rlimit_as.value : -1);
775 #endif
776 #ifdef RLIMIT_NPROC
777 pa_strbuf_printf(s, "rlimit-nproc = %li\n", c->rlimit_nproc.is_set ? (long int) c->rlimit_nproc.value : -1);
778 #endif
779 #ifdef RLIMIT_NOFILE
780 pa_strbuf_printf(s, "rlimit-nofile = %li\n", c->rlimit_nofile.is_set ? (long int) c->rlimit_nofile.value : -1);
781 #endif
782 #ifdef RLIMIT_MEMLOCK
783 pa_strbuf_printf(s, "rlimit-memlock = %li\n", c->rlimit_memlock.is_set ? (long int) c->rlimit_memlock.value : -1);
784 #endif
785 #ifdef RLIMIT_LOCKS
786 pa_strbuf_printf(s, "rlimit-locks = %li\n", c->rlimit_locks.is_set ? (long int) c->rlimit_locks.value : -1);
787 #endif
788 #ifdef RLIMIT_SIGPENDING
789 pa_strbuf_printf(s, "rlimit-sigpending = %li\n", c->rlimit_sigpending.is_set ? (long int) c->rlimit_sigpending.value : -1);
790 #endif
791 #ifdef RLIMIT_MSGQUEUE
792 pa_strbuf_printf(s, "rlimit-msgqueue = %li\n", c->rlimit_msgqueue.is_set ? (long int) c->rlimit_msgqueue.value : -1);
793 #endif
794 #ifdef RLIMIT_NICE
795 pa_strbuf_printf(s, "rlimit-nice = %li\n", c->rlimit_nice.is_set ? (long int) c->rlimit_nice.value : -1);
796 #endif
797 #ifdef RLIMIT_RTPRIO
798 pa_strbuf_printf(s, "rlimit-rtprio = %li\n", c->rlimit_rtprio.is_set ? (long int) c->rlimit_rtprio.value : -1);
799 #endif
800 #ifdef RLIMIT_RTTIME
801 pa_strbuf_printf(s, "rlimit-rttime = %li\n", c->rlimit_rttime.is_set ? (long int) c->rlimit_rttime.value : -1);
802 #endif
803 #endif
804
805 return pa_strbuf_tostring_free(s);
806 }