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