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