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