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