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