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