1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2008 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, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <signal.h>
33
34 #ifdef HAVE_SYS_WAIT_H
35 #include <sys/wait.h>
36 #endif
37
38 #ifdef HAVE_NETDB_H
39 #include <netdb.h>
40 #endif
41
42 #include <pulse/version.h>
43 #include <pulse/xmalloc.h>
44 #include <pulse/util.h>
45 #include <pulse/mainloop.h>
46 #include <pulse/timeval.h>
47 #include <pulse/fork-detect.h>
48 #include <pulse/client-conf.h>
49
50 #include <pulsecore/core-error.h>
51 #include <pulsecore/i18n.h>
52 #include <pulsecore/native-common.h>
53 #include <pulsecore/pdispatch.h>
54 #include <pulsecore/pstream.h>
55 #include <pulsecore/hashmap.h>
56 #include <pulsecore/socket-client.h>
57 #include <pulsecore/pstream-util.h>
58 #include <pulsecore/core-rtclock.h>
59 #include <pulsecore/core-util.h>
60 #include <pulsecore/log.h>
61 #include <pulsecore/socket.h>
62 #include <pulsecore/creds.h>
63 #include <pulsecore/macro.h>
64 #include <pulsecore/proplist-util.h>
65
66 #include "internal.h"
67 #include "context.h"
68
69 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
70 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
71 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
72 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
73
74 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
75 [PA_COMMAND_REQUEST] = pa_command_request,
76 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
77 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
78 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
79 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
80 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
81 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
82 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
83 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
84 [PA_COMMAND_STARTED] = pa_command_stream_started,
85 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
86 [PA_COMMAND_EXTENSION] = pa_command_extension,
87 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
88 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
89 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event,
90 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
91 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
92 [PA_COMMAND_ENABLE_SRBCHANNEL] = pa_command_enable_srbchannel,
93 [PA_COMMAND_DISABLE_SRBCHANNEL] = pa_command_disable_srbchannel,
94 [PA_COMMAND_REGISTER_MEMFD_SHMID] = pa_command_register_memfd_shmid,
95 };
96 static void context_free(pa_context *c);
97
98 #ifdef HAVE_DBUS
99 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata);
100 #endif
101
pa_context_new(pa_mainloop_api * mainloop,const char * name)102 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
103 return pa_context_new_with_proplist(mainloop, name, NULL);
104 }
105
reset_callbacks(pa_context * c)106 static void reset_callbacks(pa_context *c) {
107 pa_assert(c);
108
109 c->state_callback = NULL;
110 c->state_userdata = NULL;
111
112 c->subscribe_callback = NULL;
113 c->subscribe_userdata = NULL;
114
115 c->event_callback = NULL;
116 c->event_userdata = NULL;
117
118 c->ext_device_manager.callback = NULL;
119 c->ext_device_manager.userdata = NULL;
120
121 c->ext_device_restore.callback = NULL;
122 c->ext_device_restore.userdata = NULL;
123
124 c->ext_stream_restore.callback = NULL;
125 c->ext_stream_restore.userdata = NULL;
126 }
127
pa_context_new_with_proplist(pa_mainloop_api * mainloop,const char * name,const pa_proplist * p)128 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, const pa_proplist *p) {
129 pa_context *c;
130 pa_mem_type_t type;
131
132 pa_assert(mainloop);
133
134 if (pa_detect_fork())
135 return NULL;
136
137 pa_init_i18n();
138
139 c = pa_xnew0(pa_context, 1);
140 PA_REFCNT_INIT(c);
141
142 c->error = pa_xnew0(pa_context_error, 1);
143 assert(c->error);
144
145 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
146
147 if (name)
148 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
149
150 #ifdef HAVE_DBUS
151 c->system_bus = c->session_bus = NULL;
152 #endif
153 c->mainloop = mainloop;
154 c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
155 c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
156 c->client_index = PA_INVALID_INDEX;
157 c->use_rtclock = pa_mainloop_is_our_api(mainloop);
158
159 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
160 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
161
162 c->error->error = PA_OK;
163 c->state = PA_CONTEXT_UNCONNECTED;
164
165 reset_callbacks(c);
166
167 #ifndef MSG_NOSIGNAL
168 #ifdef SIGPIPE
169 pa_check_signal_is_blocked(SIGPIPE);
170 #endif
171 #endif
172
173 c->conf = pa_client_conf_new();
174 pa_client_conf_load(c->conf, true, true);
175
176 c->srb_template.readfd = -1;
177 c->srb_template.writefd = -1;
178
179 c->memfd_on_local = (!c->conf->disable_memfd && pa_memfd_is_locally_supported());
180
181 type = (c->conf->disable_shm) ? PA_MEM_TYPE_PRIVATE :
182 ((!c->memfd_on_local) ?
183 PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_SHARED_MEMFD);
184
185 if (!(c->mempool = pa_mempool_new(type, c->conf->shm_size, true))) {
186
187 if (!c->conf->disable_shm) {
188 pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal private one.");
189 c->mempool = pa_mempool_new(PA_MEM_TYPE_PRIVATE, c->conf->shm_size, true);
190 }
191
192 if (!c->mempool) {
193 context_free(c);
194 return NULL;
195 }
196 }
197
198 return c;
199 }
200
context_unlink(pa_context * c)201 static void context_unlink(pa_context *c) {
202 pa_stream *s;
203
204 pa_assert(c);
205
206 s = c->streams ? pa_stream_ref(c->streams) : NULL;
207 while (s) {
208 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
209 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
210 pa_stream_unref(s);
211 s = n;
212 }
213
214 while (c->operations)
215 pa_operation_cancel(c->operations);
216
217 if (c->pdispatch) {
218 pa_pdispatch_unref(c->pdispatch);
219 c->pdispatch = NULL;
220 }
221
222 if (c->pstream) {
223 pa_pstream_unlink(c->pstream);
224 pa_pstream_unref(c->pstream);
225 c->pstream = NULL;
226 }
227
228 if (c->srb_template.memblock) {
229 pa_memblock_unref(c->srb_template.memblock);
230 c->srb_template.memblock = NULL;
231 }
232
233 if (c->client) {
234 pa_socket_client_unref(c->client);
235 c->client = NULL;
236 }
237
238 reset_callbacks(c);
239 }
240
context_free(pa_context * c)241 static void context_free(pa_context *c) {
242 pa_assert(c);
243
244 context_unlink(c);
245
246 #ifdef HAVE_DBUS
247 if (c->system_bus) {
248 if (c->filter_added)
249 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
250 pa_dbus_wrap_connection_free(c->system_bus);
251 }
252
253 if (c->session_bus) {
254 if (c->filter_added)
255 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
256 pa_dbus_wrap_connection_free(c->session_bus);
257 }
258 #endif
259
260 if (c->record_streams)
261 pa_hashmap_free(c->record_streams);
262 if (c->playback_streams)
263 pa_hashmap_free(c->playback_streams);
264
265 if (c->mempool)
266 pa_mempool_unref(c->mempool);
267
268 if (c->conf)
269 pa_client_conf_free(c->conf);
270
271 pa_strlist_free(c->server_list);
272
273 if (c->proplist)
274 pa_proplist_free(c->proplist);
275
276 pa_xfree(c->server);
277 pa_xfree(c->error);
278 pa_xfree(c);
279 }
280
pa_context_ref(pa_context * c)281 pa_context* pa_context_ref(pa_context *c) {
282 pa_assert(c);
283 pa_assert(PA_REFCNT_VALUE(c) >= 1);
284
285 PA_REFCNT_INC(c);
286 return c;
287 }
288
pa_context_unref(pa_context * c)289 void pa_context_unref(pa_context *c) {
290 pa_assert(c);
291 pa_assert(PA_REFCNT_VALUE(c) >= 1);
292
293 if (PA_REFCNT_DEC(c) <= 0)
294 context_free(c);
295 }
296
pa_context_set_state(pa_context * c,pa_context_state_t st)297 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
298 pa_assert(c);
299 pa_assert(PA_REFCNT_VALUE(c) >= 1);
300
301 if (c->state == st)
302 return;
303
304 pa_context_ref(c);
305
306 c->state = st;
307
308 if (c->state_callback)
309 c->state_callback(c, c->state_userdata);
310
311 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
312 context_unlink(c);
313
314 pa_context_unref(c);
315 }
316
pa_context_set_error(const pa_context * c,int error)317 int pa_context_set_error(const pa_context *c, int error) {
318 pa_assert(error >= 0);
319 pa_assert(error < PA_ERR_MAX);
320
321 if (c)
322 c->error->error = error;
323
324 return error;
325 }
326
pa_context_fail(pa_context * c,int error)327 void pa_context_fail(pa_context *c, int error) {
328 pa_assert(c);
329 pa_assert(PA_REFCNT_VALUE(c) >= 1);
330
331 pa_context_set_error(c, error);
332 pa_context_set_state(c, PA_CONTEXT_FAILED);
333 }
334
pstream_die_callback(pa_pstream * p,void * userdata)335 static void pstream_die_callback(pa_pstream *p, void *userdata) {
336 pa_context *c = userdata;
337
338 pa_assert(p);
339 pa_assert(c);
340
341 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
342 }
343
pstream_packet_callback(pa_pstream * p,pa_packet * packet,pa_cmsg_ancil_data * ancil_data,void * userdata)344 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, pa_cmsg_ancil_data *ancil_data, void *userdata) {
345 pa_context *c = userdata;
346
347 pa_assert(p);
348 pa_assert(packet);
349 pa_assert(c);
350
351 pa_context_ref(c);
352
353 if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0)
354 pa_context_fail(c, PA_ERR_PROTOCOL);
355
356 pa_context_unref(c);
357 }
358
handle_srbchannel_memblock(pa_context * c,pa_memblock * memblock)359 static void handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock) {
360 pa_srbchannel *sr;
361 pa_tagstruct *t;
362
363 pa_assert(c);
364
365 /* Memblock sanity check */
366 if (!memblock) {
367 pa_context_fail(c, PA_ERR_PROTOCOL);
368 return;
369 } else if (pa_memblock_is_read_only(memblock)) {
370 pa_context_fail(c, PA_ERR_PROTOCOL);
371 return;
372 } else if (pa_memblock_is_ours(memblock)) {
373 pa_context_fail(c, PA_ERR_PROTOCOL);
374 return;
375 }
376
377 /* Create the srbchannel */
378 c->srb_template.memblock = memblock;
379 pa_memblock_ref(memblock);
380 sr = pa_srbchannel_new_from_template(c->mainloop, &c->srb_template);
381 if (!sr) {
382 pa_log_warn("Failed to create srbchannel from template");
383 c->srb_template.readfd = -1;
384 c->srb_template.writefd = -1;
385 pa_memblock_unref(c->srb_template.memblock);
386 c->srb_template.memblock = NULL;
387 return;
388 }
389
390 /* Ack the enable command */
391 t = pa_tagstruct_new();
392 pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
393 pa_tagstruct_putu32(t, c->srb_setup_tag);
394 pa_pstream_send_tagstruct(c->pstream, t);
395
396 /* ...and switch over */
397 pa_pstream_set_srbchannel(c->pstream, sr);
398 }
399
pstream_memblock_callback(pa_pstream * p,uint32_t channel,int64_t offset,pa_seek_mode_t seek,const pa_memchunk * chunk,void * userdata)400 static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
401 pa_context *c = userdata;
402 pa_stream *s;
403
404 pa_assert(p);
405 pa_assert(chunk);
406 pa_assert(chunk->length > 0);
407 pa_assert(c);
408 pa_assert(PA_REFCNT_VALUE(c) >= 1);
409
410 pa_context_ref(c);
411
412 if (c->srb_template.readfd != -1 && c->srb_template.memblock == NULL) {
413 handle_srbchannel_memblock(c, chunk->memblock);
414 pa_context_unref(c);
415 return;
416 }
417
418 if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {
419
420 if (chunk->memblock) {
421 pa_memblockq_seek(s->record_memblockq, offset, seek, true);
422 pa_memblockq_push_align(s->record_memblockq, chunk);
423 } else
424 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, true);
425
426 if (s->read_callback) {
427 size_t l;
428
429 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
430 s->read_callback(s, l, s->read_userdata);
431 }
432 }
433
434 pa_context_unref(c);
435 }
436
pa_context_handle_error(pa_context * c,uint32_t command,pa_tagstruct * t,bool fail)437 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail) {
438 uint32_t err;
439 pa_assert(c);
440 pa_assert(PA_REFCNT_VALUE(c) >= 1);
441
442 if (command == PA_COMMAND_ERROR) {
443 pa_assert(t);
444
445 if (pa_tagstruct_getu32(t, &err) < 0 ||
446 !pa_tagstruct_eof(t)) {
447 pa_context_fail(c, PA_ERR_PROTOCOL);
448 return -1;
449 }
450
451 } else if (command == PA_COMMAND_TIMEOUT)
452 err = PA_ERR_TIMEOUT;
453 else {
454 pa_context_fail(c, PA_ERR_PROTOCOL);
455 return -1;
456 }
457
458 if (err == PA_OK) {
459 pa_context_fail(c, PA_ERR_PROTOCOL);
460 return -1;
461 }
462
463 if (err >= PA_ERR_MAX)
464 err = PA_ERR_UNKNOWN;
465
466 if (fail) {
467 pa_context_fail(c, (int) err);
468 return -1;
469 }
470
471 pa_context_set_error(c, (int) err);
472
473 return 0;
474 }
475
setup_complete_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)476 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
477 pa_context *c = userdata;
478
479 pa_assert(pd);
480 pa_assert(c);
481 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
482
483 pa_context_ref(c);
484
485 if (command != PA_COMMAND_REPLY) {
486 pa_context_handle_error(c, command, t, true);
487 goto finish;
488 }
489
490 switch(c->state) {
491 case PA_CONTEXT_AUTHORIZING: {
492 pa_tagstruct *reply;
493 bool shm_on_remote = false;
494 bool memfd_on_remote = false;
495
496 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
497 !pa_tagstruct_eof(t)) {
498 pa_context_fail(c, PA_ERR_PROTOCOL);
499 goto finish;
500 }
501
502 /* Minimum supported version */
503 if (c->version < 8) {
504 pa_context_fail(c, PA_ERR_VERSION);
505 goto finish;
506 }
507
508 /* Starting with protocol version 13 the MSB of the version
509 tag reflects if shm is available for this connection or
510 not. */
511 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 13) {
512 shm_on_remote = !!(c->version & PA_PROTOCOL_FLAG_SHM);
513
514 /* Starting with protocol version 31, the second MSB of the version
515 * tag reflects whether memfd is supported on the other PA end. */
516 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 31)
517 memfd_on_remote = !!(c->version & PA_PROTOCOL_FLAG_MEMFD);
518
519 /* Reserve the two most-significant _bytes_ of the version tag
520 * for flags. */
521 c->version &= PA_PROTOCOL_VERSION_MASK;
522 }
523
524 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
525
526 /* Enable shared memory support if possible */
527 if (c->do_shm)
528 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
529 c->do_shm = false;
530
531 if (c->do_shm) {
532
533 /* Only enable SHM if both sides are owned by the same
534 * user. This is a security measure because otherwise
535 * data private to the user might leak. */
536
537 #ifdef HAVE_CREDS
538 const pa_creds *creds;
539 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
540 c->do_shm = false;
541 #endif
542 }
543
544 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
545 pa_pstream_enable_shm(c->pstream, c->do_shm);
546
547 c->shm_type = PA_MEM_TYPE_PRIVATE;
548 if (c->do_shm) {
549 if (c->version >= 31 && memfd_on_remote && c->memfd_on_local) {
550 const char *reason;
551
552 pa_pstream_enable_memfd(c->pstream);
553 if (pa_mempool_is_memfd_backed(c->mempool))
554 if (pa_pstream_register_memfd_mempool(c->pstream, c->mempool, &reason))
555 pa_log("Failed to regester memfd mempool. Reason: %s", reason);
556
557 /* Even if memfd pool registration fails, the negotiated SHM type
558 * shall remain memfd as both endpoints claim to support it. */
559 c->shm_type = PA_MEM_TYPE_SHARED_MEMFD;
560 } else
561 c->shm_type = PA_MEM_TYPE_SHARED_POSIX;
562 }
563
564 pa_log_debug("Memfd possible: %s", pa_yes_no(c->memfd_on_local));
565 pa_log_debug("Negotiated SHM type: %s", pa_mem_type_to_string(c->shm_type));
566
567 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
568
569 if (c->version >= 13) {
570 pa_init_proplist(c->proplist);
571 pa_tagstruct_put_proplist(reply, c->proplist);
572 } else
573 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
574
575 pa_pstream_send_tagstruct(c->pstream, reply);
576 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
577
578 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
579 break;
580 }
581
582 case PA_CONTEXT_SETTING_NAME :
583
584 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
585 c->client_index == PA_INVALID_INDEX)) ||
586 !pa_tagstruct_eof(t)) {
587 pa_context_fail(c, PA_ERR_PROTOCOL);
588 goto finish;
589 }
590
591 pa_context_set_state(c, PA_CONTEXT_READY);
592 break;
593
594 default:
595 pa_assert_not_reached();
596 }
597
598 finish:
599 pa_context_unref(c);
600 }
601
setup_context(pa_context * c,pa_iochannel * io)602 static void setup_context(pa_context *c, pa_iochannel *io) {
603 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
604 pa_tagstruct *t;
605 uint32_t tag;
606
607 pa_assert(c);
608 pa_assert(io);
609
610 pa_context_ref(c);
611
612 pa_assert(!c->pstream);
613 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
614
615 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
616 pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
617 pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
618
619 pa_assert(!c->pdispatch);
620 c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX);
621
622 if (pa_client_conf_load_cookie(c->conf, cookie, sizeof(cookie)) < 0)
623 pa_log_info("No cookie loaded. Attempting to connect without.");
624
625 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
626
627 c->do_shm =
628 pa_mempool_is_shared(c->mempool) &&
629 c->is_local;
630
631 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
632
633 /* Starting with protocol version 13 we use the MSB of the version
634 * tag for informing the other side if we could do SHM or not.
635 * Starting from version 31, second MSB is used to flag memfd support. */
636 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? PA_PROTOCOL_FLAG_SHM : 0) |
637 (c->memfd_on_local ? PA_PROTOCOL_FLAG_MEMFD: 0));
638 pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie));
639
640 #ifdef HAVE_CREDS
641 {
642 pa_creds ucred;
643
644 if (pa_iochannel_creds_supported(io))
645 pa_iochannel_creds_enable(io);
646
647 ucred.uid = getuid();
648 ucred.gid = getgid();
649
650 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
651 }
652 #else
653 pa_pstream_send_tagstruct(c->pstream, t);
654 #endif
655
656 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
657
658 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
659
660 pa_context_unref(c);
661 }
662
prepend_per_user(pa_strlist * l)663 static pa_strlist *prepend_per_user(pa_strlist *l) {
664 char *ufn;
665
666 /* The per-user instance */
667 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
668 l = pa_strlist_prepend(l, ufn);
669 pa_xfree(ufn);
670 }
671
672 return l;
673 }
674
675 #ifndef OS_IS_WIN32
676
context_autospawn(pa_context * c)677 static int context_autospawn(pa_context *c) {
678 pid_t pid;
679 int status, r;
680 struct sigaction sa;
681
682 pa_context_ref(c);
683
684 if (sigaction(SIGCHLD, NULL, &sa) < 0) {
685 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno));
686 pa_context_fail(c, PA_ERR_INTERNAL);
687 goto fail;
688 }
689
690 #ifdef SA_NOCLDWAIT
691 if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) {
692 #else
693 if (sa.sa_handler == SIG_IGN) {
694 #endif
695 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
696 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
697 goto fail;
698 }
699
700 pa_log_debug("Trying to autospawn...");
701
702 if (c->spawn_api.prefork)
703 c->spawn_api.prefork();
704
705 if ((pid = fork()) < 0) {
706 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
707 pa_context_fail(c, PA_ERR_INTERNAL);
708
709 if (c->spawn_api.postfork)
710 c->spawn_api.postfork();
711
712 goto fail;
713 } else if (!pid) {
714 /* Child */
715
716 const char *state = NULL;
717 const char * argv[32];
718 unsigned n = 0;
719
720 if (c->spawn_api.atfork)
721 c->spawn_api.atfork();
722
723 /* We leave most of the cleaning up of the process environment
724 * to the executable. We only clean up the file descriptors to
725 * make sure the executable can actually be loaded
726 * correctly. */
727 pa_close_all(-1);
728
729 /* Setup argv */
730 argv[n++] = c->conf->daemon_binary;
731 argv[n++] = "--start";
732
733 while (n < PA_ELEMENTSOF(argv)-1) {
734 char *a;
735
736 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
737 break;
738
739 argv[n++] = a;
740 }
741
742 argv[n++] = NULL;
743 pa_assert(n <= PA_ELEMENTSOF(argv));
744
745 execv(argv[0], (char * const *) argv);
746 _exit(1);
747 }
748
749 /* Parent */
750
751 if (c->spawn_api.postfork)
752 c->spawn_api.postfork();
753
754 do {
755 r = waitpid(pid, &status, 0);
756 } while (r < 0 && errno == EINTR);
757
758 if (r < 0) {
759
760 if (errno != ECHILD) {
761 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
762 pa_context_fail(c, PA_ERR_INTERNAL);
763 goto fail;
764 }
765
766 /* hmm, something already reaped our child, so we assume
767 * startup worked, even if we cannot know */
768
769 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
770 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
771 goto fail;
772 }
773
774 pa_context_unref(c);
775
776 return 0;
777
778 fail:
779
780 pa_context_unref(c);
781
782 return -1;
783 }
784
785 #endif /* OS_IS_WIN32 */
786
787 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
788
789 #ifdef HAVE_DBUS
790 static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) {
791 DBusError error;
792
793 pa_assert(c);
794 pa_assert(conn);
795
796 dbus_error_init(&error);
797
798 if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, c->use_rtclock, type, &error)) || dbus_error_is_set(&error)) {
799 pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message);
800 goto fail;
801 }
802
803 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) {
804 pa_log_warn("Failed to add filter function");
805 goto fail;
806 }
807 c->filter_added = true;
808
809 if (pa_dbus_add_matches(
810 pa_dbus_wrap_connection_get(*conn), &error,
811 "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL) < 0) {
812
813 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error.name, error.message);
814 goto fail;
815 }
816
817 return;
818
819 fail:
820 if (*conn) {
821 pa_dbus_wrap_connection_free(*conn);
822 *conn = NULL;
823 }
824
825 dbus_error_free(&error);
826 }
827 #endif
828
829 static int try_next_connection(pa_context *c) {
830 char *u = NULL;
831 int r = -1;
832
833 pa_assert(c);
834 pa_assert(!c->client);
835
836 for (;;) {
837 pa_xfree(u);
838 u = NULL;
839
840 c->server_list = pa_strlist_pop(c->server_list, &u);
841
842 if (!u) {
843
844 #ifndef OS_IS_WIN32
845 if (c->do_autospawn) {
846
847 if ((r = context_autospawn(c)) < 0)
848 goto finish;
849
850 /* Autospawn only once */
851 c->do_autospawn = false;
852
853 /* Connect only to per-user sockets this time */
854 c->server_list = prepend_per_user(c->server_list);
855
856 /* Retry connection */
857 continue;
858 }
859 #endif
860
861 #ifdef HAVE_DBUS
862 if (c->no_fail && !c->server_specified) {
863 if (!c->session_bus)
864 track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus);
865 if (!c->system_bus)
866 track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus);
867
868 if (c->session_bus || c->system_bus) {
869 pa_log_debug("Waiting for PA on D-Bus...");
870 break;
871 }
872 } else
873 #endif
874 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
875
876 goto finish;
877 }
878
879 pa_log_debug("Trying to connect to %s...", u);
880
881 pa_xfree(c->server);
882 c->server = pa_xstrdup(u);
883
884 if (!(c->client = pa_socket_client_new_string(c->mainloop, c->use_rtclock, u, PA_NATIVE_DEFAULT_PORT)))
885 continue;
886
887 c->is_local = pa_socket_client_is_local(c->client);
888 pa_socket_client_set_callback(c->client, on_connection, c);
889 break;
890 }
891
892 r = 0;
893
894 finish:
895 pa_xfree(u);
896
897 return r;
898 }
899
900 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
901 pa_context *c = userdata;
902 int saved_errno = errno;
903
904 pa_assert(client);
905 pa_assert(c);
906 pa_assert(c->state == PA_CONTEXT_CONNECTING);
907
908 pa_context_ref(c);
909
910 pa_socket_client_unref(client);
911 c->client = NULL;
912
913 if (!io) {
914 /* Try the next item in the list */
915 if (saved_errno == ECONNREFUSED ||
916 saved_errno == ETIMEDOUT ||
917 saved_errno == EHOSTUNREACH) {
918 try_next_connection(c);
919 goto finish;
920 }
921
922 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
923 goto finish;
924 }
925
926 setup_context(c, io);
927
928 finish:
929 pa_context_unref(c);
930 }
931
932 #ifdef HAVE_DBUS
933 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
934 pa_context *c = userdata;
935 bool is_session;
936
937 pa_assert(bus);
938 pa_assert(message);
939 pa_assert(c);
940
941 if (c->state != PA_CONTEXT_CONNECTING)
942 goto finish;
943
944 if (!c->no_fail)
945 goto finish;
946
947 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
948
949 is_session = c->session_bus && bus == pa_dbus_wrap_connection_get(c->session_bus);
950 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session ? "session" : "system");
951
952 if (is_session)
953 /* The user instance via PF_LOCAL */
954 c->server_list = prepend_per_user(c->server_list);
955 else
956 /* The system wide instance via PF_LOCAL */
957 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
958
959 if (!c->client)
960 try_next_connection(c);
961
962 finish:
963 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
964 }
965 #endif
966
967 int pa_context_connect(
968 pa_context *c,
969 const char *server,
970 pa_context_flags_t flags,
971 const pa_spawn_api *api) {
972
973 int r = -1;
974
975 pa_assert(c);
976 pa_assert(PA_REFCNT_VALUE(c) >= 1);
977
978 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
979 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
980 PA_CHECK_VALIDITY(c, !(flags & ~(PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL)), PA_ERR_INVALID);
981 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
982
983 if (server)
984 c->conf->autospawn = false;
985 else
986 server = c->conf->default_server;
987
988 pa_context_ref(c);
989
990 c->no_fail = !!(flags & PA_CONTEXT_NOFAIL);
991 c->server_specified = !!server;
992 pa_assert(!c->server_list);
993
994 if (server) {
995 if (!(c->server_list = pa_strlist_parse(server))) {
996 pa_context_fail(c, PA_ERR_INVALIDSERVER);
997 goto finish;
998 }
999
1000 } else {
1001 char *d;
1002
1003 /* Prepend in reverse order */
1004
1005 /* Follow the X display */
1006 if (c->conf->auto_connect_display) {
1007 if ((d = getenv("DISPLAY"))) {
1008 d = pa_xstrndup(d, strcspn(d, ":"));
1009
1010 if (*d)
1011 c->server_list = pa_strlist_prepend(c->server_list, d);
1012
1013 pa_xfree(d);
1014 }
1015 }
1016
1017 /* Add TCP/IP on the localhost */
1018 if (c->conf->auto_connect_localhost) {
1019 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
1020 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
1021 }
1022
1023 /* The system wide instance via PF_LOCAL */
1024 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
1025
1026 /* The user instance via PF_LOCAL */
1027 c->server_list = prepend_per_user(c->server_list);
1028 }
1029
1030 /* Set up autospawning */
1031 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
1032
1033 #ifdef HAVE_GETUID
1034 if (getuid() == 0)
1035 pa_log_debug("Not doing autospawn since we are root.");
1036 else {
1037 c->do_autospawn = true;
1038
1039 if (api)
1040 c->spawn_api = *api;
1041 }
1042 #endif
1043 }
1044
1045 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
1046 r = try_next_connection(c);
1047
1048 finish:
1049 pa_context_unref(c);
1050
1051 return r;
1052 }
1053
1054 void pa_context_disconnect(pa_context *c) {
1055 pa_assert(c);
1056 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1057
1058 if (pa_detect_fork())
1059 return;
1060
1061 if (PA_CONTEXT_IS_GOOD(c->state))
1062 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
1063 }
1064
1065 pa_context_state_t pa_context_get_state(const pa_context *c) {
1066 pa_assert(c);
1067 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1068
1069 return c->state;
1070 }
1071
1072 int pa_context_errno(const pa_context *c) {
1073
1074 if (!c)
1075 return PA_ERR_INVALID;
1076
1077 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1078
1079 return c->error->error;
1080 }
1081
1082 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1083 pa_assert(c);
1084 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1085
1086 if (pa_detect_fork())
1087 return;
1088
1089 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1090 return;
1091
1092 c->state_callback = cb;
1093 c->state_userdata = userdata;
1094 }
1095
1096 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
1097 pa_assert(c);
1098 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1099
1100 if (pa_detect_fork())
1101 return;
1102
1103 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1104 return;
1105
1106 c->event_callback = cb;
1107 c->event_userdata = userdata;
1108 }
1109
1110 int pa_context_is_pending(const pa_context *c) {
1111 pa_assert(c);
1112 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1113
1114 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1115 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
1116
1117 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
1118 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
1119 c->client;
1120 }
1121
1122 static void set_dispatch_callbacks(pa_operation *o);
1123
1124 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
1125 set_dispatch_callbacks(userdata);
1126 }
1127
1128 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
1129 set_dispatch_callbacks(userdata);
1130 }
1131
1132 static void set_dispatch_callbacks(pa_operation *o) {
1133 int done = 1;
1134
1135 pa_assert(o);
1136 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1137 pa_assert(o->context);
1138 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
1139 pa_assert(o->context->state == PA_CONTEXT_READY);
1140
1141 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
1142 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
1143
1144 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
1145 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
1146 done = 0;
1147 }
1148
1149 if (pa_pstream_is_pending(o->context->pstream)) {
1150 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
1151 done = 0;
1152 }
1153
1154 if (done) {
1155 if (o->callback) {
1156 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
1157 cb(o->context, o->userdata);
1158 }
1159
1160 pa_operation_done(o);
1161 pa_operation_unref(o);
1162 }
1163 }
1164
1165 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1166 pa_operation *o;
1167
1168 pa_assert(c);
1169 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1170
1171 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1172 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1173 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1174
1175 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1176 set_dispatch_callbacks(pa_operation_ref(o));
1177
1178 return o;
1179 }
1180
1181 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1182 pa_operation *o = userdata;
1183 int success = 1;
1184
1185 pa_assert(pd);
1186 pa_assert(o);
1187 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1188
1189 if (!o->context)
1190 goto finish;
1191
1192 if (command != PA_COMMAND_REPLY) {
1193 if (pa_context_handle_error(o->context, command, t, false) < 0)
1194 goto finish;
1195
1196 success = 0;
1197 } else if (!pa_tagstruct_eof(t)) {
1198 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1199 goto finish;
1200 }
1201
1202 if (o->callback) {
1203 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1204 cb(o->context, success, o->userdata);
1205 }
1206
1207 finish:
1208 pa_operation_done(o);
1209 pa_operation_unref(o);
1210 }
1211
1212 pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa_pdispatch_cb_t internal_cb, pa_operation_cb_t cb, void *userdata) {
1213 pa_tagstruct *t;
1214 pa_operation *o;
1215 uint32_t tag;
1216
1217 pa_assert(c);
1218 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1219
1220 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1221 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1222
1223 o = pa_operation_new(c, NULL, cb, userdata);
1224
1225 t = pa_tagstruct_command(c, command, &tag);
1226 pa_pstream_send_tagstruct(c->pstream, t);
1227 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1228
1229 return o;
1230 }
1231
1232 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1233 pa_assert(c);
1234 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1235
1236 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1237 }
1238
1239 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1240 pa_tagstruct *t;
1241 pa_operation *o;
1242 uint32_t tag;
1243
1244 pa_assert(c);
1245 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1246
1247 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1248 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1249
1250 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1251 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1252 pa_tagstruct_puts(t, name);
1253 pa_pstream_send_tagstruct(c->pstream, t);
1254 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1255
1256 return o;
1257 }
1258
1259 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1260 pa_tagstruct *t;
1261 pa_operation *o;
1262 uint32_t tag;
1263
1264 pa_assert(c);
1265 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1266
1267 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1268 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1269
1270 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1271 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1272 pa_tagstruct_puts(t, name);
1273 pa_pstream_send_tagstruct(c->pstream, t);
1274 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1275
1276 return o;
1277 }
1278
1279 int pa_context_is_local(const pa_context *c) {
1280 pa_assert(c);
1281 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1282
1283 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1284 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1285
1286 return c->is_local;
1287 }
1288
1289 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1290 pa_operation *o;
1291
1292 pa_assert(c);
1293 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1294 pa_assert(name);
1295
1296 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1297 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1298
1299 if (c->version >= 13) {
1300 pa_proplist *p = pa_proplist_new();
1301
1302 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1303 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1304 pa_proplist_free(p);
1305 } else {
1306 pa_tagstruct *t;
1307 uint32_t tag;
1308
1309 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1310 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1311 pa_tagstruct_puts(t, name);
1312 pa_pstream_send_tagstruct(c->pstream, t);
1313 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1314 }
1315
1316 return o;
1317 }
1318
1319 const char* pa_get_library_version(void) {
1320 return pa_get_headers_version();
1321 }
1322
1323 const char* pa_context_get_server(const pa_context *c) {
1324 pa_assert(c);
1325 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1326
1327 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1328 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1329
1330 if (*c->server == '{') {
1331 char *e = strchr(c->server+1, '}');
1332 return e ? e+1 : c->server;
1333 }
1334
1335 return c->server;
1336 }
1337
1338 uint32_t pa_context_get_protocol_version(const pa_context *c) {
1339 return PA_PROTOCOL_VERSION;
1340 }
1341
1342 uint32_t pa_context_get_server_protocol_version(const pa_context *c) {
1343 pa_assert(c);
1344 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1345
1346 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1347 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1348
1349 return c->version;
1350 }
1351
1352 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1353 pa_tagstruct *t;
1354
1355 pa_assert(c);
1356 pa_assert(tag);
1357
1358 t = pa_tagstruct_new();
1359 pa_tagstruct_putu32(t, command);
1360 pa_tagstruct_putu32(t, *tag = c->ctag++);
1361
1362 return t;
1363 }
1364
1365 uint32_t pa_context_get_index(const pa_context *c) {
1366 pa_assert(c);
1367 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1368
1369 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1370 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1371 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1372
1373 return c->client_index;
1374 }
1375
1376 pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, const pa_proplist *p, pa_context_success_cb_t cb, void *userdata) {
1377 pa_operation *o;
1378 pa_tagstruct *t;
1379 uint32_t tag;
1380
1381 pa_assert(c);
1382 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1383
1384 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1385 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1386 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1387 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1388
1389 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1390
1391 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1392 pa_tagstruct_putu32(t, (uint32_t) mode);
1393 pa_tagstruct_put_proplist(t, p);
1394
1395 pa_pstream_send_tagstruct(c->pstream, t);
1396 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1397
1398 /* Please note that we don't update c->proplist here, because we
1399 * don't export that field */
1400
1401 return o;
1402 }
1403
1404 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1405 pa_operation *o;
1406 pa_tagstruct *t;
1407 uint32_t tag;
1408 const char * const *k;
1409
1410 pa_assert(c);
1411 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1412
1413 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1414 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1415 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1416 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1417
1418 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1419
1420 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1421
1422 for (k = keys; *k; k++)
1423 pa_tagstruct_puts(t, *k);
1424
1425 pa_tagstruct_puts(t, NULL);
1426
1427 pa_pstream_send_tagstruct(c->pstream, t);
1428 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1429
1430 /* Please note that we don't update c->proplist here, because we
1431 * don't export that field */
1432
1433 return o;
1434 }
1435
1436 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1437 pa_context *c = userdata;
1438 uint32_t idx;
1439 const char *name;
1440
1441 pa_assert(pd);
1442 pa_assert(command == PA_COMMAND_EXTENSION);
1443 pa_assert(t);
1444 pa_assert(c);
1445 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1446
1447 pa_context_ref(c);
1448
1449 if (c->version < 15) {
1450 pa_context_fail(c, PA_ERR_PROTOCOL);
1451 goto finish;
1452 }
1453
1454 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1455 pa_tagstruct_gets(t, &name) < 0) {
1456 pa_context_fail(c, PA_ERR_PROTOCOL);
1457 goto finish;
1458 }
1459
1460 if (pa_streq(name, "module-device-manager"))
1461 pa_ext_device_manager_command(c, tag, t);
1462 else if (pa_streq(name, "module-device-restore"))
1463 pa_ext_device_restore_command(c, tag, t);
1464 else if (pa_streq(name, "module-stream-restore"))
1465 pa_ext_stream_restore_command(c, tag, t);
1466 else
1467 pa_log(_("Received message for unknown extension '%s'"), name);
1468
1469 finish:
1470 pa_context_unref(c);
1471 }
1472
1473 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1474 pa_context *c = userdata;
1475
1476 #ifdef HAVE_CREDS
1477 pa_cmsg_ancil_data *ancil = NULL;
1478
1479 pa_assert(pd);
1480 pa_assert(command == PA_COMMAND_ENABLE_SRBCHANNEL);
1481 pa_assert(t);
1482 pa_assert(c);
1483 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1484
1485 ancil = pa_pdispatch_take_ancil_data(pd);
1486 if (!ancil)
1487 goto fail;
1488
1489 /* Currently only one srb channel is supported, might change in future versions */
1490 if (c->srb_template.readfd != -1)
1491 goto fail;
1492
1493 if (ancil->nfd != 2 || ancil->fds[0] == -1 || ancil->fds[1] == -1)
1494 goto fail;
1495
1496 pa_context_ref(c);
1497
1498 c->srb_template.readfd = ancil->fds[0];
1499 c->srb_template.writefd = ancil->fds[1];
1500 c->srb_setup_tag = tag;
1501
1502 pa_context_unref(c);
1503
1504 ancil->close_fds_on_cleanup = false;
1505 return;
1506
1507 fail:
1508 if (ancil)
1509 pa_cmsg_ancil_data_close_fds(ancil);
1510
1511 pa_context_fail(c, PA_ERR_PROTOCOL);
1512 return;
1513 #else
1514 pa_assert(c);
1515 pa_context_fail(c, PA_ERR_PROTOCOL);
1516 #endif
1517 }
1518
1519 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1520 pa_context *c = userdata;
1521 pa_tagstruct *t2;
1522
1523 pa_assert(pd);
1524 pa_assert(command == PA_COMMAND_DISABLE_SRBCHANNEL);
1525 pa_assert(t);
1526 pa_assert(c);
1527 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1528
1529 pa_pstream_set_srbchannel(c->pstream, NULL);
1530
1531 c->srb_template.readfd = -1;
1532 c->srb_template.writefd = -1;
1533 if (c->srb_template.memblock) {
1534 pa_memblock_unref(c->srb_template.memblock);
1535 c->srb_template.memblock = NULL;
1536 }
1537
1538 /* Send disable command back again */
1539 t2 = pa_tagstruct_new();
1540 pa_tagstruct_putu32(t2, PA_COMMAND_DISABLE_SRBCHANNEL);
1541 pa_tagstruct_putu32(t2, tag);
1542 pa_pstream_send_tagstruct(c->pstream, t2);
1543 }
1544
1545 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1546 pa_context *c = userdata;
1547
1548 pa_assert(pd);
1549 pa_assert(command == PA_COMMAND_REGISTER_MEMFD_SHMID);
1550 pa_assert(t);
1551 pa_assert(c);
1552 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1553
1554 if (pa_common_command_register_memfd_shmid(c->pstream, pd, c->version, command, t))
1555 pa_context_fail(c, PA_ERR_PROTOCOL);
1556 }
1557
1558 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1559 pa_context *c = userdata;
1560 pa_proplist *pl = NULL;
1561 const char *event;
1562
1563 pa_assert(pd);
1564 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1565 pa_assert(t);
1566 pa_assert(c);
1567 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1568
1569 pa_context_ref(c);
1570
1571 if (c->version < 15) {
1572 pa_context_fail(c, PA_ERR_PROTOCOL);
1573 goto finish;
1574 }
1575
1576 pl = pa_proplist_new();
1577
1578 if (pa_tagstruct_gets(t, &event) < 0 ||
1579 pa_tagstruct_get_proplist(t, pl) < 0 ||
1580 !pa_tagstruct_eof(t) || !event) {
1581 pa_context_fail(c, PA_ERR_PROTOCOL);
1582 goto finish;
1583 }
1584
1585 if (c->event_callback)
1586 c->event_callback(c, event, pl, c->event_userdata);
1587
1588 finish:
1589 pa_context_unref(c);
1590
1591 if (pl)
1592 pa_proplist_free(pl);
1593 }
1594
1595 pa_time_event* pa_context_rttime_new(const pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {
1596 struct timeval tv;
1597
1598 pa_assert(c);
1599 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1600 pa_assert(c->mainloop);
1601
1602 if (usec == PA_USEC_INVALID)
1603 return c->mainloop->time_new(c->mainloop, NULL, cb, userdata);
1604
1605 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1606
1607 return c->mainloop->time_new(c->mainloop, &tv, cb, userdata);
1608 }
1609
1610 void pa_context_rttime_restart(const pa_context *c, pa_time_event *e, pa_usec_t usec) {
1611 struct timeval tv;
1612
1613 pa_assert(c);
1614 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1615 pa_assert(c->mainloop);
1616
1617 if (usec == PA_USEC_INVALID)
1618 c->mainloop->time_restart(e, NULL);
1619 else {
1620 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1621 c->mainloop->time_restart(e, &tv);
1622 }
1623 }
1624
1625 size_t pa_context_get_tile_size(const pa_context *c, const pa_sample_spec *ss) {
1626 size_t fs, mbs;
1627
1628 pa_assert(c);
1629 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1630
1631 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
1632 PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
1633
1634 fs = ss ? pa_frame_size(ss) : 1;
1635 mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
1636 return PA_MAX(mbs, fs);
1637 }
1638
1639 int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path) {
1640 pa_assert(c);
1641 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1642
1643 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1644 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
1645 PA_CHECK_VALIDITY(c, !cookie_file_path || *cookie_file_path, PA_ERR_INVALID);
1646
1647 pa_client_conf_set_cookie_file_from_application(c->conf, cookie_file_path);
1648
1649 return 0;
1650 }
1651