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