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