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