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