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