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