• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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