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