]> code.delx.au - pulseaudio/blob - src/pulse/context.c
notify clients about tlength changes
[pulseaudio] / 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
58 #include <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
60
61 #include <pulsecore/native-common.h>
62 #include <pulsecore/pdispatch.h>
63 #include <pulsecore/pstream.h>
64 #include <pulsecore/dynarray.h>
65 #include <pulsecore/socket-client.h>
66 #include <pulsecore/pstream-util.h>
67 #include <pulsecore/core-util.h>
68 #include <pulsecore/log.h>
69 #include <pulsecore/socket-util.h>
70 #include <pulsecore/creds.h>
71 #include <pulsecore/macro.h>
72 #include <pulsecore/proplist-util.h>
73
74 #include "internal.h"
75
76 #include "client-conf.h"
77 #include "fork-detect.h"
78
79 #ifdef HAVE_X11
80 #include "client-conf-x11.h"
81 #endif
82
83 #include "context.h"
84
85 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
86
87 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
88 [PA_COMMAND_REQUEST] = pa_command_request,
89 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
90 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
91 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
92 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
93 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
94 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
95 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
96 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
97 [PA_COMMAND_STARTED] = pa_command_stream_started,
98 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
99 [PA_COMMAND_EXTENSION] = pa_command_extension,
100 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
101 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
102 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event,
103 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
104 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr
105 };
106 static void context_free(pa_context *c);
107
108 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
109 return pa_context_new_with_proplist(mainloop, name, NULL);
110 }
111
112 static void reset_callbacks(pa_context *c) {
113 pa_assert(c);
114
115 c->state_callback = NULL;
116 c->state_userdata = NULL;
117
118 c->subscribe_callback = NULL;
119 c->subscribe_userdata = NULL;
120
121 c->event_callback = NULL;
122 c->event_userdata = NULL;
123
124 c->ext_stream_restore.callback = NULL;
125 c->ext_stream_restore.userdata = NULL;
126 }
127
128 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) {
129 pa_context *c;
130
131 pa_assert(mainloop);
132
133 if (pa_detect_fork())
134 return NULL;
135
136 pa_init_i18n();
137
138 c = pa_xnew(pa_context, 1);
139 PA_REFCNT_INIT(c);
140
141 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
142
143 if (name)
144 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
145
146 c->mainloop = mainloop;
147 c->client = NULL;
148 c->pstream = NULL;
149 c->pdispatch = NULL;
150 c->playback_streams = pa_dynarray_new();
151 c->record_streams = pa_dynarray_new();
152 c->client_index = PA_INVALID_INDEX;
153
154 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
155 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
156
157 c->error = PA_OK;
158 c->state = PA_CONTEXT_UNCONNECTED;
159 c->ctag = 0;
160 c->csyncid = 0;
161
162 reset_callbacks(c);
163
164 c->is_local = FALSE;
165 c->server_list = NULL;
166 c->server = NULL;
167
168 c->do_shm = FALSE;
169
170 c->do_autospawn = FALSE;
171 memset(&c->spawn_api, 0, sizeof(c->spawn_api));
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 #ifdef HAVE_X11
181 pa_client_conf_from_x11(c->conf, NULL);
182 #endif
183 pa_client_conf_load(c->conf, NULL);
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 if (c->record_streams)
241 pa_dynarray_free(c->record_streams, NULL, NULL);
242 if (c->playback_streams)
243 pa_dynarray_free(c->playback_streams, NULL, NULL);
244
245 if (c->mempool)
246 pa_mempool_free(c->mempool);
247
248 if (c->conf)
249 pa_client_conf_free(c->conf);
250
251 pa_strlist_free(c->server_list);
252
253 if (c->proplist)
254 pa_proplist_free(c->proplist);
255
256 pa_xfree(c->server);
257 pa_xfree(c);
258 }
259
260 pa_context* pa_context_ref(pa_context *c) {
261 pa_assert(c);
262 pa_assert(PA_REFCNT_VALUE(c) >= 1);
263
264 PA_REFCNT_INC(c);
265 return c;
266 }
267
268 void pa_context_unref(pa_context *c) {
269 pa_assert(c);
270 pa_assert(PA_REFCNT_VALUE(c) >= 1);
271
272 if (PA_REFCNT_DEC(c) <= 0)
273 context_free(c);
274 }
275
276 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
277 pa_assert(c);
278 pa_assert(PA_REFCNT_VALUE(c) >= 1);
279
280 if (c->state == st)
281 return;
282
283 pa_context_ref(c);
284
285 c->state = st;
286
287 if (c->state_callback)
288 c->state_callback(c, c->state_userdata);
289
290 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
291 context_unlink(c);
292
293 pa_context_unref(c);
294 }
295
296 int pa_context_set_error(pa_context *c, int error) {
297 pa_assert(error >= 0);
298 pa_assert(error < PA_ERR_MAX);
299
300 if (c)
301 c->error = error;
302
303 return error;
304 }
305
306 void pa_context_fail(pa_context *c, int error) {
307 pa_assert(c);
308 pa_assert(PA_REFCNT_VALUE(c) >= 1);
309
310 pa_context_set_error(c, error);
311 pa_context_set_state(c, PA_CONTEXT_FAILED);
312 }
313
314 static void pstream_die_callback(pa_pstream *p, void *userdata) {
315 pa_context *c = userdata;
316
317 pa_assert(p);
318 pa_assert(c);
319
320 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
321 }
322
323 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
324 pa_context *c = userdata;
325
326 pa_assert(p);
327 pa_assert(packet);
328 pa_assert(c);
329
330 pa_context_ref(c);
331
332 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
333 pa_context_fail(c, PA_ERR_PROTOCOL);
334
335 pa_context_unref(c);
336 }
337
338 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) {
339 pa_context *c = userdata;
340 pa_stream *s;
341
342 pa_assert(p);
343 pa_assert(chunk);
344 pa_assert(chunk->length > 0);
345 pa_assert(c);
346 pa_assert(PA_REFCNT_VALUE(c) >= 1);
347
348 pa_context_ref(c);
349
350 if ((s = pa_dynarray_get(c->record_streams, channel))) {
351
352 if (chunk->memblock) {
353 pa_memblockq_seek(s->record_memblockq, offset, seek);
354 pa_memblockq_push_align(s->record_memblockq, chunk);
355 } else
356 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek);
357
358 if (s->read_callback) {
359 size_t l;
360
361 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
362 s->read_callback(s, l, s->read_userdata);
363 }
364 }
365
366 pa_context_unref(c);
367 }
368
369 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa_bool_t fail) {
370 uint32_t err;
371 pa_assert(c);
372 pa_assert(PA_REFCNT_VALUE(c) >= 1);
373
374 if (command == PA_COMMAND_ERROR) {
375 pa_assert(t);
376
377 if (pa_tagstruct_getu32(t, &err) < 0 ||
378 !pa_tagstruct_eof(t)) {
379 pa_context_fail(c, PA_ERR_PROTOCOL);
380 return -1;
381 }
382
383 } else if (command == PA_COMMAND_TIMEOUT)
384 err = PA_ERR_TIMEOUT;
385 else {
386 pa_context_fail(c, PA_ERR_PROTOCOL);
387 return -1;
388 }
389
390 if (err == PA_OK) {
391 pa_context_fail(c, PA_ERR_PROTOCOL);
392 return -1;
393 }
394
395 if (err >= PA_ERR_MAX)
396 err = PA_ERR_UNKNOWN;
397
398 if (fail) {
399 pa_context_fail(c, (int) err);
400 return -1;
401 }
402
403 pa_context_set_error(c, (int) err);
404
405 return 0;
406 }
407
408 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
409 pa_context *c = userdata;
410
411 pa_assert(pd);
412 pa_assert(c);
413 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
414
415 pa_context_ref(c);
416
417 if (command != PA_COMMAND_REPLY) {
418 pa_context_handle_error(c, command, t, TRUE);
419 goto finish;
420 }
421
422 switch(c->state) {
423 case PA_CONTEXT_AUTHORIZING: {
424 pa_tagstruct *reply;
425 pa_bool_t shm_on_remote = FALSE;
426
427 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
428 !pa_tagstruct_eof(t)) {
429 pa_context_fail(c, PA_ERR_PROTOCOL);
430 goto finish;
431 }
432
433 /* Minimum supported version */
434 if (c->version < 8) {
435 pa_context_fail(c, PA_ERR_VERSION);
436 goto finish;
437 }
438
439 /* Starting with protocol version 13 the MSB of the version
440 tag reflects if shm is available for this connection or
441 not. */
442 if (c->version >= 13) {
443 shm_on_remote = !!(c->version & 0x80000000U);
444 c->version &= 0x7FFFFFFFU;
445 }
446
447 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
448
449 /* Enable shared memory support if possible */
450 if (c->do_shm)
451 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
452 c->do_shm = FALSE;
453
454 if (c->do_shm) {
455
456 /* Only enable SHM if both sides are owned by the same
457 * user. This is a security measure because otherwise
458 * data private to the user might leak. */
459
460 #ifdef HAVE_CREDS
461 const pa_creds *creds;
462 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
463 c->do_shm = FALSE;
464 #endif
465 }
466
467 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
468 pa_pstream_enable_shm(c->pstream, c->do_shm);
469
470 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
471
472 if (c->version >= 13) {
473 pa_init_proplist(c->proplist);
474 pa_tagstruct_put_proplist(reply, c->proplist);
475 } else
476 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
477
478 pa_pstream_send_tagstruct(c->pstream, reply);
479 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
480
481 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
482 break;
483 }
484
485 case PA_CONTEXT_SETTING_NAME :
486
487 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
488 c->client_index == PA_INVALID_INDEX)) ||
489 !pa_tagstruct_eof(t)) {
490 pa_context_fail(c, PA_ERR_PROTOCOL);
491 goto finish;
492 }
493
494 pa_context_set_state(c, PA_CONTEXT_READY);
495 break;
496
497 default:
498 pa_assert_not_reached();
499 }
500
501 finish:
502 pa_context_unref(c);
503 }
504
505 static void setup_context(pa_context *c, pa_iochannel *io) {
506 pa_tagstruct *t;
507 uint32_t tag;
508
509 pa_assert(c);
510 pa_assert(io);
511
512 pa_context_ref(c);
513
514 pa_assert(!c->pstream);
515 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
516
517 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
518 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
519 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
520
521 pa_assert(!c->pdispatch);
522 c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
523
524 if (!c->conf->cookie_valid)
525 pa_log_info(_("No cookie loaded. Attempting to connect without."));
526
527 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
528
529 c->do_shm =
530 pa_mempool_is_shared(c->mempool) &&
531 c->is_local;
532
533 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
534
535 /* Starting with protocol version 13 we use the MSB of the version
536 * tag for informing the other side if we could do SHM or not */
537 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
538 pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
539
540 #ifdef HAVE_CREDS
541 {
542 pa_creds ucred;
543
544 if (pa_iochannel_creds_supported(io))
545 pa_iochannel_creds_enable(io);
546
547 ucred.uid = getuid();
548 ucred.gid = getgid();
549
550 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
551 }
552 #else
553 pa_pstream_send_tagstruct(c->pstream, t);
554 #endif
555
556 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
557
558 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
559
560 pa_context_unref(c);
561 }
562
563 #ifdef ENABLE_LEGACY_RUNTIME_DIR
564 static char *get_old_legacy_runtime_dir(void) {
565 char *p, u[128];
566 struct stat st;
567
568 if (!pa_get_user_name(u, sizeof(u)))
569 return NULL;
570
571 p = pa_sprintf_malloc("/tmp/pulse-%s", u);
572
573 if (stat(p, &st) < 0) {
574 pa_xfree(p);
575 return NULL;
576 }
577
578 if (st.st_uid != getuid()) {
579 pa_xfree(p);
580 return NULL;
581 }
582
583 return p;
584 }
585
586 static char *get_very_old_legacy_runtime_dir(void) {
587 char *p, h[128];
588 struct stat st;
589
590 if (!pa_get_home_dir(h, sizeof(h)))
591 return NULL;
592
593 p = pa_sprintf_malloc("%s/.pulse", h);
594
595 if (stat(p, &st) < 0) {
596 pa_xfree(p);
597 return NULL;
598 }
599
600 if (st.st_uid != getuid()) {
601 pa_xfree(p);
602 return NULL;
603 }
604
605 return p;
606 }
607 #endif
608
609 static pa_strlist *prepend_per_user(pa_strlist *l) {
610 char *ufn;
611
612 #ifdef ENABLE_LEGACY_RUNTIME_DIR
613 static char *legacy_dir;
614
615 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
616 if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
617 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
618 l = pa_strlist_prepend(l, p);
619 pa_xfree(p);
620 pa_xfree(legacy_dir);
621 }
622
623 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
624 if ((legacy_dir = get_old_legacy_runtime_dir())) {
625 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
626 l = pa_strlist_prepend(l, p);
627 pa_xfree(p);
628 pa_xfree(legacy_dir);
629 }
630 #endif
631
632 /* The per-user instance */
633 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
634 l = pa_strlist_prepend(l, ufn);
635 pa_xfree(ufn);
636 }
637
638 return l;
639 }
640
641 #ifndef OS_IS_WIN32
642
643 static int context_autospawn(pa_context *c) {
644 pid_t pid;
645 int status, r;
646
647 pa_log_debug("Trying to autospawn...");
648
649 pa_context_ref(c);
650
651 if (c->spawn_api.prefork)
652 c->spawn_api.prefork();
653
654 if ((pid = fork()) < 0) {
655 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
656 pa_context_fail(c, PA_ERR_INTERNAL);
657
658 if (c->spawn_api.postfork)
659 c->spawn_api.postfork();
660
661 goto fail;
662 } else if (!pid) {
663 /* Child */
664
665 const char *state = NULL;
666 #define MAX_ARGS 64
667 const char * argv[MAX_ARGS+1];
668 int n;
669
670 if (c->spawn_api.atfork)
671 c->spawn_api.atfork();
672
673 pa_close_all(-1);
674
675 /* Setup argv */
676
677 n = 0;
678
679 argv[n++] = c->conf->daemon_binary;
680 argv[n++] = "--start";
681
682 while (n < MAX_ARGS) {
683 char *a;
684
685 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
686 break;
687
688 argv[n++] = a;
689 }
690
691 argv[n++] = NULL;
692
693 execv(argv[0], (char * const *) argv);
694 _exit(1);
695 #undef MAX_ARGS
696 }
697
698 /* Parent */
699
700 if (c->spawn_api.postfork)
701 c->spawn_api.postfork();
702
703 do {
704 r = waitpid(pid, &status, 0);
705 } while (r < 0 && errno == EINTR);
706
707 if (r < 0) {
708 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
709 pa_context_fail(c, PA_ERR_INTERNAL);
710 goto fail;
711 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
712 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
713 goto fail;
714 }
715
716 pa_context_unref(c);
717
718 return 0;
719
720 fail:
721
722 pa_context_unref(c);
723
724 return -1;
725 }
726
727 #endif /* OS_IS_WIN32 */
728
729 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
730
731 static int try_next_connection(pa_context *c) {
732 char *u = NULL;
733 int r = -1;
734
735 pa_assert(c);
736 pa_assert(!c->client);
737
738 for (;;) {
739 pa_xfree(u);
740 u = NULL;
741
742 c->server_list = pa_strlist_pop(c->server_list, &u);
743
744 if (!u) {
745
746 #ifndef OS_IS_WIN32
747 if (c->do_autospawn) {
748
749 if ((r = context_autospawn(c)) < 0)
750 goto finish;
751
752 /* Autospawn only once */
753 c->do_autospawn = FALSE;
754
755 /* Connect only to per-user sockets this time */
756 c->server_list = prepend_per_user(c->server_list);
757
758 /* Retry connection */
759 continue;
760 }
761 #endif
762
763 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
764 goto finish;
765 }
766
767 pa_log_debug("Trying to connect to %s...", u);
768
769 pa_xfree(c->server);
770 c->server = pa_xstrdup(u);
771
772 if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
773 continue;
774
775 c->is_local = !!pa_socket_client_is_local(c->client);
776 pa_socket_client_set_callback(c->client, on_connection, c);
777 break;
778 }
779
780 r = 0;
781
782 finish:
783 pa_xfree(u);
784
785 return r;
786 }
787
788 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
789 pa_context *c = userdata;
790 int saved_errno = errno;
791
792 pa_assert(client);
793 pa_assert(c);
794 pa_assert(c->state == PA_CONTEXT_CONNECTING);
795
796 pa_context_ref(c);
797
798 pa_socket_client_unref(client);
799 c->client = NULL;
800
801 if (!io) {
802 /* Try the item in the list */
803 if (saved_errno == ECONNREFUSED ||
804 saved_errno == ETIMEDOUT ||
805 saved_errno == EHOSTUNREACH) {
806 try_next_connection(c);
807 goto finish;
808 }
809
810 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
811 goto finish;
812 }
813
814 setup_context(c, io);
815
816 finish:
817 pa_context_unref(c);
818 }
819
820 int pa_context_connect(
821 pa_context *c,
822 const char *server,
823 pa_context_flags_t flags,
824 const pa_spawn_api *api) {
825
826 int r = -1;
827
828 pa_assert(c);
829 pa_assert(PA_REFCNT_VALUE(c) >= 1);
830
831 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
832 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
833 PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
834 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
835
836 if (!server)
837 server = c->conf->default_server;
838
839 pa_context_ref(c);
840
841 pa_assert(!c->server_list);
842
843 if (server) {
844 if (!(c->server_list = pa_strlist_parse(server))) {
845 pa_context_fail(c, PA_ERR_INVALIDSERVER);
846 goto finish;
847 }
848
849 } else {
850 char *d;
851
852 /* Prepend in reverse order */
853
854 /* Follow the X display */
855 if ((d = getenv("DISPLAY"))) {
856 char *e;
857 d = pa_xstrdup(d);
858 if ((e = strchr(d, ':')))
859 *e = 0;
860
861 if (*d)
862 c->server_list = pa_strlist_prepend(c->server_list, d);
863
864 pa_xfree(d);
865 }
866
867 /* Add TCP/IP on the localhost */
868 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
869 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
870
871 /* The system wide instance via PF_LOCAL */
872 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
873
874 /* The user instance via PF_LOCAL */
875 c->server_list = prepend_per_user(c->server_list);
876
877 /* Set up autospawning */
878 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
879
880 if (getuid() == 0)
881 pa_log_debug("Not doing autospawn since we are root.");
882 else {
883 c->do_autospawn = TRUE;
884
885 if (api)
886 c->spawn_api = *api;
887 }
888 }
889 }
890
891 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
892 r = try_next_connection(c);
893
894 finish:
895 pa_context_unref(c);
896
897 return r;
898 }
899
900 void pa_context_disconnect(pa_context *c) {
901 pa_assert(c);
902 pa_assert(PA_REFCNT_VALUE(c) >= 1);
903
904 if (pa_detect_fork())
905 return;
906
907 if (PA_CONTEXT_IS_GOOD(c->state))
908 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
909 }
910
911 pa_context_state_t pa_context_get_state(pa_context *c) {
912 pa_assert(c);
913 pa_assert(PA_REFCNT_VALUE(c) >= 1);
914
915 return c->state;
916 }
917
918 int pa_context_errno(pa_context *c) {
919 pa_assert(c);
920 pa_assert(PA_REFCNT_VALUE(c) >= 1);
921
922 return c->error;
923 }
924
925 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
926 pa_assert(c);
927 pa_assert(PA_REFCNT_VALUE(c) >= 1);
928
929 if (pa_detect_fork())
930 return;
931
932 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
933 return;
934
935 c->state_callback = cb;
936 c->state_userdata = userdata;
937 }
938
939 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
940 pa_assert(c);
941 pa_assert(PA_REFCNT_VALUE(c) >= 1);
942
943 if (pa_detect_fork())
944 return;
945
946 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
947 return;
948
949 c->event_callback = cb;
950 c->event_userdata = userdata;
951 }
952
953 int pa_context_is_pending(pa_context *c) {
954 pa_assert(c);
955 pa_assert(PA_REFCNT_VALUE(c) >= 1);
956
957 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
958 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
959
960 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
961 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
962 c->client;
963 }
964
965 static void set_dispatch_callbacks(pa_operation *o);
966
967 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
968 set_dispatch_callbacks(userdata);
969 }
970
971 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
972 set_dispatch_callbacks(userdata);
973 }
974
975 static void set_dispatch_callbacks(pa_operation *o) {
976 int done = 1;
977
978 pa_assert(o);
979 pa_assert(PA_REFCNT_VALUE(o) >= 1);
980 pa_assert(o->context);
981 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
982 pa_assert(o->context->state == PA_CONTEXT_READY);
983
984 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
985 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
986
987 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
988 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
989 done = 0;
990 }
991
992 if (pa_pstream_is_pending(o->context->pstream)) {
993 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
994 done = 0;
995 }
996
997 if (done) {
998 if (o->callback) {
999 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
1000 cb(o->context, o->userdata);
1001 }
1002
1003 pa_operation_done(o);
1004 pa_operation_unref(o);
1005 }
1006 }
1007
1008 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1009 pa_operation *o;
1010
1011 pa_assert(c);
1012 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1013
1014 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1015 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1016 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1017
1018 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1019 set_dispatch_callbacks(pa_operation_ref(o));
1020
1021 return o;
1022 }
1023
1024 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1025 pa_operation *o = userdata;
1026 int success = 1;
1027
1028 pa_assert(pd);
1029 pa_assert(o);
1030 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1031
1032 if (!o->context)
1033 goto finish;
1034
1035 if (command != PA_COMMAND_REPLY) {
1036 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1037 goto finish;
1038
1039 success = 0;
1040 } else if (!pa_tagstruct_eof(t)) {
1041 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1042 goto finish;
1043 }
1044
1045 if (o->callback) {
1046 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1047 cb(o->context, success, o->userdata);
1048 }
1049
1050 finish:
1051 pa_operation_done(o);
1052 pa_operation_unref(o);
1053 }
1054
1055 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) {
1056 pa_tagstruct *t;
1057 pa_operation *o;
1058 uint32_t tag;
1059
1060 pa_assert(c);
1061 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1062
1063 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1064 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1065
1066 o = pa_operation_new(c, NULL, cb, userdata);
1067
1068 t = pa_tagstruct_command(c, command, &tag);
1069 pa_pstream_send_tagstruct(c->pstream, t);
1070 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1071
1072 return o;
1073 }
1074
1075 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1076 pa_assert(c);
1077 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1078
1079 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1080 }
1081
1082 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1083 pa_tagstruct *t;
1084 pa_operation *o;
1085 uint32_t tag;
1086
1087 pa_assert(c);
1088 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1089
1090 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1091 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1092
1093 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1094 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1095 pa_tagstruct_puts(t, name);
1096 pa_pstream_send_tagstruct(c->pstream, t);
1097 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);
1098
1099 return o;
1100 }
1101
1102 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1103 pa_tagstruct *t;
1104 pa_operation *o;
1105 uint32_t tag;
1106
1107 pa_assert(c);
1108 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1109
1110 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1111 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1112
1113 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1114 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1115 pa_tagstruct_puts(t, name);
1116 pa_pstream_send_tagstruct(c->pstream, t);
1117 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);
1118
1119 return o;
1120 }
1121
1122 int pa_context_is_local(pa_context *c) {
1123 pa_assert(c);
1124 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1125
1126 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1127 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1128
1129 return !!c->is_local;
1130 }
1131
1132 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1133 pa_operation *o;
1134
1135 pa_assert(c);
1136 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1137 pa_assert(name);
1138
1139 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1140 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1141
1142 if (c->version >= 13) {
1143 pa_proplist *p = pa_proplist_new();
1144
1145 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1146 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1147 pa_proplist_free(p);
1148 } else {
1149 pa_tagstruct *t;
1150 uint32_t tag;
1151
1152 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1153 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1154 pa_tagstruct_puts(t, name);
1155 pa_pstream_send_tagstruct(c->pstream, t);
1156 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);
1157 }
1158
1159 return o;
1160 }
1161
1162 const char* pa_get_library_version(void) {
1163 return PACKAGE_VERSION;
1164 }
1165
1166 const char* pa_context_get_server(pa_context *c) {
1167 pa_assert(c);
1168 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1169
1170 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1171 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1172
1173 if (*c->server == '{') {
1174 char *e = strchr(c->server+1, '}');
1175 return e ? e+1 : c->server;
1176 }
1177
1178 return c->server;
1179 }
1180
1181 uint32_t pa_context_get_protocol_version(pa_context *c) {
1182 return PA_PROTOCOL_VERSION;
1183 }
1184
1185 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
1186 pa_assert(c);
1187 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1188
1189 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1190 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1191
1192 return c->version;
1193 }
1194
1195 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1196 pa_tagstruct *t;
1197
1198 pa_assert(c);
1199 pa_assert(tag);
1200
1201 t = pa_tagstruct_new(NULL, 0);
1202 pa_tagstruct_putu32(t, command);
1203 pa_tagstruct_putu32(t, *tag = c->ctag++);
1204
1205 return t;
1206 }
1207
1208 uint32_t pa_context_get_index(pa_context *c) {
1209 pa_assert(c);
1210 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1211
1212 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1213 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1214 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1215
1216 return c->client_index;
1217 }
1218
1219 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) {
1220 pa_operation *o;
1221 pa_tagstruct *t;
1222 uint32_t tag;
1223
1224 pa_assert(c);
1225 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1226
1227 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1228 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1229 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1230 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1231
1232 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1233
1234 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1235 pa_tagstruct_putu32(t, (uint32_t) mode);
1236 pa_tagstruct_put_proplist(t, p);
1237
1238 pa_pstream_send_tagstruct(c->pstream, t);
1239 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);
1240
1241 /* Please note that we don't update c->proplist here, because we
1242 * don't export that field */
1243
1244 return o;
1245 }
1246
1247 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1248 pa_operation *o;
1249 pa_tagstruct *t;
1250 uint32_t tag;
1251 const char * const *k;
1252
1253 pa_assert(c);
1254 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1255
1256 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1257 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1258 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1259 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1260
1261 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1262
1263 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1264
1265 for (k = keys; *k; k++)
1266 pa_tagstruct_puts(t, *k);
1267
1268 pa_tagstruct_puts(t, NULL);
1269
1270 pa_pstream_send_tagstruct(c->pstream, t);
1271 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);
1272
1273 /* Please note that we don't update c->proplist here, because we
1274 * don't export that field */
1275
1276 return o;
1277 }
1278
1279 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1280 pa_context *c = userdata;
1281 uint32_t idx;
1282 const char *name;
1283
1284 pa_assert(pd);
1285 pa_assert(command == PA_COMMAND_EXTENSION);
1286 pa_assert(t);
1287 pa_assert(c);
1288 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1289
1290 pa_context_ref(c);
1291
1292 if (c->version < 15) {
1293 pa_context_fail(c, PA_ERR_PROTOCOL);
1294 goto finish;
1295 }
1296
1297 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1298 pa_tagstruct_gets(t, &name) < 0) {
1299 pa_context_fail(c, PA_ERR_PROTOCOL);
1300 goto finish;
1301 }
1302
1303 if (!strcmp(name, "module-stream-restore"))
1304 pa_ext_stream_restore_command(c, tag, t);
1305 else
1306 pa_log(_("Received message for unknown extension '%s'"), name);
1307
1308 finish:
1309 pa_context_unref(c);
1310 }
1311
1312
1313 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1314 pa_context *c = userdata;
1315 pa_proplist *pl = NULL;
1316 const char *event;
1317
1318 pa_assert(pd);
1319 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1320 pa_assert(t);
1321 pa_assert(c);
1322 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1323
1324 pa_context_ref(c);
1325
1326 if (c->version < 15) {
1327 pa_context_fail(c, PA_ERR_PROTOCOL);
1328 goto finish;
1329 }
1330
1331 pl = pa_proplist_new();
1332
1333 if (pa_tagstruct_gets(t, &event) < 0 ||
1334 pa_tagstruct_get_proplist(t, pl) < 0 ||
1335 !pa_tagstruct_eof(t) || !event) {
1336 pa_context_fail(c, PA_ERR_PROTOCOL);
1337 goto finish;
1338 }
1339
1340 if (c->event_callback)
1341 c->event_callback(c, event, pl, c->event_userdata);
1342
1343 finish:
1344 pa_context_unref(c);
1345
1346 if (pl)
1347 pa_proplist_free(pl);
1348 }