]> code.delx.au - pulseaudio/blob - src/pulse/client-conf.c
client-conf: Don't create multiple cookie files
[pulseaudio] / src / pulse / client-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 <stdlib.h>
28 #include <unistd.h>
29 #include <errno.h>
30
31 #include <pulse/xmalloc.h>
32
33 #include <pulsecore/i18n.h>
34 #include <pulsecore/macro.h>
35 #include <pulsecore/core-error.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/conf-parser.h>
38 #include <pulsecore/core-util.h>
39 #include <pulsecore/authkey.h>
40
41 #include "client-conf.h"
42
43 #define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "client.conf"
44 #define DEFAULT_CLIENT_CONFIG_FILE_USER "client.conf"
45
46 #define ENV_CLIENT_CONFIG_FILE "PULSE_CLIENTCONFIG"
47 #define ENV_DEFAULT_SINK "PULSE_SINK"
48 #define ENV_DEFAULT_SOURCE "PULSE_SOURCE"
49 #define ENV_DEFAULT_SERVER "PULSE_SERVER"
50 #define ENV_DAEMON_BINARY "PULSE_BINARY"
51 #define ENV_COOKIE_FILE "PULSE_COOKIE"
52
53 static const pa_client_conf default_conf = {
54 .daemon_binary = NULL,
55 .extra_arguments = NULL,
56 .default_sink = NULL,
57 .default_source = NULL,
58 .default_server = NULL,
59 .default_dbus_server = NULL,
60 .cookie_file_from_env = NULL,
61 .cookie_from_x11_valid = false,
62 .cookie_file_from_application = NULL,
63 .cookie_file_from_client_conf = NULL,
64 .autospawn = true,
65 .disable_shm = false,
66 .shm_size = 0,
67 .auto_connect_localhost = false,
68 .auto_connect_display = false
69 };
70
71 pa_client_conf *pa_client_conf_new(void) {
72 pa_client_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf));
73
74 c->daemon_binary = pa_xstrdup(PA_BINARY);
75 c->extra_arguments = pa_xstrdup("--log-target=syslog");
76
77 return c;
78 }
79
80 void pa_client_conf_free(pa_client_conf *c) {
81 pa_assert(c);
82 pa_xfree(c->daemon_binary);
83 pa_xfree(c->extra_arguments);
84 pa_xfree(c->default_sink);
85 pa_xfree(c->default_source);
86 pa_xfree(c->default_server);
87 pa_xfree(c->default_dbus_server);
88 pa_xfree(c->cookie_file_from_env);
89 pa_xfree(c->cookie_file_from_application);
90 pa_xfree(c->cookie_file_from_client_conf);
91 pa_xfree(c);
92 }
93
94 int pa_client_conf_load(pa_client_conf *c) {
95 FILE *f = NULL;
96 char *fn = NULL;
97 int r = -1;
98
99 /* Prepare the configuration parse table */
100 pa_config_item table[] = {
101 { "daemon-binary", pa_config_parse_string, &c->daemon_binary, NULL },
102 { "extra-arguments", pa_config_parse_string, &c->extra_arguments, NULL },
103 { "default-sink", pa_config_parse_string, &c->default_sink, NULL },
104 { "default-source", pa_config_parse_string, &c->default_source, NULL },
105 { "default-server", pa_config_parse_string, &c->default_server, NULL },
106 { "default-dbus-server", pa_config_parse_string, &c->default_dbus_server, NULL },
107 { "autospawn", pa_config_parse_bool, &c->autospawn, NULL },
108 { "cookie-file", pa_config_parse_string, &c->cookie_file_from_client_conf, NULL },
109 { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
110 { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
111 { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL },
112 { "auto-connect-localhost", pa_config_parse_bool, &c->auto_connect_localhost, NULL },
113 { "auto-connect-display", pa_config_parse_bool, &c->auto_connect_display, NULL },
114 { NULL, NULL, NULL, NULL },
115 };
116
117 if (!(f = pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn)))
118 if (errno != ENOENT)
119 goto finish;
120
121 r = f ? pa_config_parse(fn, f, table, NULL, NULL) : 0;
122
123 finish:
124 pa_xfree(fn);
125
126 if (f)
127 fclose(f);
128
129 return r;
130 }
131
132 int pa_client_conf_load_cookie(pa_client_conf *c, uint8_t *cookie, size_t cookie_length) {
133 int r;
134
135 pa_assert(c);
136 pa_assert(cookie);
137 pa_assert(cookie_length > 0);
138
139 if (c->cookie_file_from_env) {
140 r = pa_authkey_load_auto(c->cookie_file_from_env, true, cookie, cookie_length);
141 if (r >= 0)
142 return 0;
143
144 pa_log_warn("Failed to load cookie from %s (configured with environment variable PULSE_COOKIE): %s",
145 c->cookie_file_from_env, pa_cstrerror(errno));
146 }
147
148 if (c->cookie_from_x11_valid) {
149 if (cookie_length == sizeof(c->cookie_from_x11)) {
150 memcpy(cookie, c->cookie_from_x11, cookie_length);
151 return 0;
152 }
153
154 pa_log_warn("Failed to load cookie from X11 root window property PULSE_COOKIE: size mismatch.");
155 }
156
157 if (c->cookie_file_from_application) {
158 r = pa_authkey_load_auto(c->cookie_file_from_application, true, cookie, cookie_length);
159 if (r >= 0)
160 return 0;
161
162 pa_log_warn("Failed to load cookie from %s (configured by the application): %s", c->cookie_file_from_application,
163 pa_cstrerror(errno));
164 }
165
166 if (c->cookie_file_from_client_conf) {
167 r = pa_authkey_load_auto(c->cookie_file_from_client_conf, true, cookie, cookie_length);
168 if (r >= 0)
169 return 0;
170
171 pa_log_warn("Failed to load cookie from %s (configured in client.conf): %s", c->cookie_file_from_client_conf,
172 pa_cstrerror(errno));
173 }
174
175 r = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE, false, cookie, cookie_length);
176 if (r >= 0)
177 return 0;
178
179 r = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE_FALLBACK, false, cookie, cookie_length);
180 if (r >= 0)
181 return 0;
182
183 r = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE, true, cookie, cookie_length);
184 if (r >= 0)
185 return 0;
186
187 pa_log("Failed to load cookie file from %s: %s", PA_NATIVE_COOKIE_FILE, pa_cstrerror(errno));
188 memset(cookie, 0, cookie_length);
189
190 return -1;
191 }
192
193 int pa_client_conf_env(pa_client_conf *c) {
194 char *e;
195
196 if ((e = getenv(ENV_DEFAULT_SINK))) {
197 pa_xfree(c->default_sink);
198 c->default_sink = pa_xstrdup(e);
199 }
200
201 if ((e = getenv(ENV_DEFAULT_SOURCE))) {
202 pa_xfree(c->default_source);
203 c->default_source = pa_xstrdup(e);
204 }
205
206 if ((e = getenv(ENV_DEFAULT_SERVER))) {
207 pa_xfree(c->default_server);
208 c->default_server = pa_xstrdup(e);
209
210 /* We disable autospawning automatically if a specific server was set */
211 c->autospawn = false;
212 }
213
214 if ((e = getenv(ENV_DAEMON_BINARY))) {
215 pa_xfree(c->daemon_binary);
216 c->daemon_binary = pa_xstrdup(e);
217 }
218
219 if ((e = getenv(ENV_COOKIE_FILE)) && *e) {
220 pa_xfree(c->cookie_file_from_env);
221 c->cookie_file_from_env = pa_xstrdup(e);
222 }
223
224 return 0;
225 }
226
227 void pa_client_conf_set_cookie_file_from_application(pa_client_conf *c, const char *cookie_file) {
228 pa_assert(c);
229 pa_assert(!cookie_file || *cookie_file);
230
231 pa_xfree(c->cookie_file_from_application);
232 c->cookie_file_from_application = pa_xstrdup(cookie_file);
233 }