finish modernizations in pulse/, s/assert/pa_assert/g
[profile/ivi/pulseaudio.git] / src / pulse / context.c
1 /* $Id$ */
2
3 /***
4   This file is part of PulseAudio.
5
6   Copyright 2004-2006 Lennart Poettering
7   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
8
9   PulseAudio is free software; you can redistribute it and/or modify
10   it under the terms of the GNU Lesser General Public License as published
11   by the Free Software Foundation; either version 2 of the License,
12   or (at your option) any later version.
13
14   PulseAudio is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with PulseAudio; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22   USA.
23 ***/
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36 #include <signal.h>
37 #include <limits.h>
38
39 #ifdef HAVE_SYS_WAIT_H
40 #include <sys/wait.h>
41 #endif
42
43 #ifdef HAVE_SYS_SOCKET_H
44 #include <sys/socket.h>
45 #endif
46 #ifdef HAVE_SYS_UN_H
47 #include <sys/un.h>
48 #endif
49 #ifdef HAVE_NETDB_H
50 #include <netdb.h>
51 #endif
52
53 #include "../pulsecore/winsock.h"
54
55 #include <pulsecore/core-error.h>
56 #include <pulse/version.h>
57 #include <pulse/xmalloc.h>
58
59 #include <pulsecore/native-common.h>
60 #include <pulsecore/pdispatch.h>
61 #include <pulsecore/pstream.h>
62 #include <pulsecore/dynarray.h>
63 #include <pulsecore/socket-client.h>
64 #include <pulsecore/pstream-util.h>
65 #include <pulsecore/core-util.h>
66 #include <pulsecore/log.h>
67 #include <pulsecore/socket-util.h>
68 #include <pulsecore/creds.h>
69 #include <pulsecore/macro.h>
70
71 #include "internal.h"
72
73 #include "client-conf.h"
74
75 #ifdef HAVE_X11
76 #include "client-conf-x11.h"
77 #endif
78
79 #include "context.h"
80
81 #define AUTOSPAWN_LOCK "autospawn.lock"
82
83 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
84     [PA_COMMAND_REQUEST] = pa_command_request,
85     [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
86     [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
87     [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
88     [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
89     [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event
90 };
91
92 static void unlock_autospawn_lock_file(pa_context *c) {
93     pa_assert(c);
94
95     if (c->autospawn_lock_fd >= 0) {
96         char lf[PATH_MAX];
97         pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
98
99         pa_unlock_lockfile(lf, c->autospawn_lock_fd);
100         c->autospawn_lock_fd = -1;
101     }
102 }
103
104 static void context_free(pa_context *c);
105
106 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
107     pa_context *c;
108
109     pa_assert(mainloop);
110     pa_assert(name);
111
112     c = pa_xnew(pa_context, 1);
113     PA_REFCNT_INIT(c);
114     c->name = pa_xstrdup(name);
115     c->mainloop = mainloop;
116     c->client = NULL;
117     c->pstream = NULL;
118     c->pdispatch = NULL;
119     c->playback_streams = pa_dynarray_new();
120     c->record_streams = pa_dynarray_new();
121
122     PA_LLIST_HEAD_INIT(pa_stream, c->streams);
123     PA_LLIST_HEAD_INIT(pa_operation, c->operations);
124
125     c->error = PA_OK;
126     c->state = PA_CONTEXT_UNCONNECTED;
127     c->ctag = 0;
128     c->csyncid = 0;
129
130     c->state_callback = NULL;
131     c->state_userdata = NULL;
132
133     c->subscribe_callback = NULL;
134     c->subscribe_userdata = NULL;
135
136     c->is_local = -1;
137     c->server_list = NULL;
138     c->server = NULL;
139     c->autospawn_lock_fd = -1;
140     memset(&c->spawn_api, 0, sizeof(c->spawn_api));
141     c->do_autospawn = 0;
142
143 #ifndef MSG_NOSIGNAL
144 #ifdef SIGPIPE
145     pa_check_signal_is_blocked(SIGPIPE);
146 #endif
147 #endif
148
149     c->conf = pa_client_conf_new();
150     pa_client_conf_load(c->conf, NULL);
151 #ifdef HAVE_X11
152     pa_client_conf_from_x11(c->conf, NULL);
153 #endif
154     pa_client_conf_env(c->conf);
155
156     if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm))) {
157
158         if (!c->conf->disable_shm)
159             c->mempool = pa_mempool_new(0);
160
161         if (!c->mempool) {
162             context_free(c);
163             return NULL;
164         }
165     }
166
167     return c;
168 }
169
170 static void context_free(pa_context *c) {
171     pa_assert(c);
172
173     unlock_autospawn_lock_file(c);
174
175     while (c->operations)
176         pa_operation_cancel(c->operations);
177
178     while (c->streams)
179         pa_stream_set_state(c->streams, PA_STREAM_TERMINATED);
180
181     if (c->client)
182         pa_socket_client_unref(c->client);
183     if (c->pdispatch)
184         pa_pdispatch_unref(c->pdispatch);
185     if (c->pstream) {
186         pa_pstream_unlink(c->pstream);
187         pa_pstream_unref(c->pstream);
188     }
189
190     if (c->record_streams)
191         pa_dynarray_free(c->record_streams, NULL, NULL);
192     if (c->playback_streams)
193         pa_dynarray_free(c->playback_streams, NULL, NULL);
194
195     if (c->mempool)
196         pa_mempool_free(c->mempool);
197
198     if (c->conf)
199         pa_client_conf_free(c->conf);
200
201     pa_strlist_free(c->server_list);
202
203     pa_xfree(c->name);
204     pa_xfree(c->server);
205     pa_xfree(c);
206 }
207
208 pa_context* pa_context_ref(pa_context *c) {
209     pa_assert(c);
210     pa_assert(PA_REFCNT_VALUE(c) >= 1);
211
212     PA_REFCNT_INC(c);
213     return c;
214 }
215
216 void pa_context_unref(pa_context *c) {
217     pa_assert(c);
218     pa_assert(PA_REFCNT_VALUE(c) >= 1);
219
220     if (PA_REFCNT_DEC(c) <= 0)
221         context_free(c);
222 }
223
224 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
225     pa_assert(c);
226     pa_assert(PA_REFCNT_VALUE(c) >= 1);
227
228     if (c->state == st)
229         return;
230
231     pa_context_ref(c);
232
233     c->state = st;
234     if (c->state_callback)
235         c->state_callback(c, c->state_userdata);
236
237     if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED) {
238         pa_stream *s;
239
240         s = c->streams ? pa_stream_ref(c->streams) : NULL;
241         while (s) {
242             pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
243             pa_stream_set_state(s, st == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
244             pa_stream_unref(s);
245             s = n;
246         }
247
248         if (c->pdispatch)
249             pa_pdispatch_unref(c->pdispatch);
250         c->pdispatch = NULL;
251
252         if (c->pstream) {
253             pa_pstream_unlink(c->pstream);
254             pa_pstream_unref(c->pstream);
255         }
256         c->pstream = NULL;
257
258         if (c->client)
259             pa_socket_client_unref(c->client);
260         c->client = NULL;
261     }
262
263     pa_context_unref(c);
264 }
265
266 void pa_context_fail(pa_context *c, int error) {
267     pa_assert(c);
268     pa_assert(PA_REFCNT_VALUE(c) >= 1);
269
270     pa_context_set_error(c, error);
271     pa_context_set_state(c, PA_CONTEXT_FAILED);
272 }
273
274 int pa_context_set_error(pa_context *c, int error) {
275     pa_assert(error >= 0);
276     pa_assert(error < PA_ERR_MAX);
277
278     if (c)
279         c->error = error;
280
281     return error;
282 }
283
284 static void pstream_die_callback(pa_pstream *p, void *userdata) {
285     pa_context *c = userdata;
286
287     pa_assert(p);
288     pa_assert(c);
289
290     pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
291 }
292
293 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
294     pa_context *c = userdata;
295
296     pa_assert(p);
297     pa_assert(packet);
298     pa_assert(c);
299
300     pa_context_ref(c);
301
302     if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
303         pa_context_fail(c, PA_ERR_PROTOCOL);
304
305     pa_context_unref(c);
306 }
307
308 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) {
309     pa_context *c = userdata;
310     pa_stream *s;
311
312     pa_assert(p);
313     pa_assert(chunk);
314     pa_assert(chunk->memblock);
315     pa_assert(chunk->length);
316     pa_assert(c);
317     pa_assert(PA_REFCNT_VALUE(c) >= 1);
318
319     pa_context_ref(c);
320
321     if ((s = pa_dynarray_get(c->record_streams, channel))) {
322
323         pa_assert(seek == PA_SEEK_RELATIVE);
324         pa_assert(offset == 0);
325
326         pa_memblockq_seek(s->record_memblockq, offset, seek);
327         pa_memblockq_push_align(s->record_memblockq, chunk);
328
329         if (s->read_callback) {
330             size_t l;
331
332             if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
333                 s->read_callback(s, l, s->read_userdata);
334         }
335     }
336
337     pa_context_unref(c);
338 }
339
340 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) {
341     pa_assert(c);
342     pa_assert(PA_REFCNT_VALUE(c) >= 1);
343
344     if (command == PA_COMMAND_ERROR) {
345         pa_assert(t);
346
347         if (pa_tagstruct_getu32(t, &c->error) < 0) {
348             pa_context_fail(c, PA_ERR_PROTOCOL);
349             return -1;
350
351         }
352     } else if (command == PA_COMMAND_TIMEOUT)
353         c->error = PA_ERR_TIMEOUT;
354     else {
355         pa_context_fail(c, PA_ERR_PROTOCOL);
356         return -1;
357     }
358
359     return 0;
360 }
361
362 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
363     pa_context *c = userdata;
364
365     pa_assert(pd);
366     pa_assert(c);
367     pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
368
369     pa_context_ref(c);
370
371     if (command != PA_COMMAND_REPLY) {
372
373         if (pa_context_handle_error(c, command, t) < 0)
374             pa_context_fail(c, PA_ERR_PROTOCOL);
375
376         pa_context_fail(c, c->error);
377         goto finish;
378     }
379
380     switch(c->state) {
381         case PA_CONTEXT_AUTHORIZING: {
382             pa_tagstruct *reply;
383
384             if (pa_tagstruct_getu32(t, &c->version) < 0 ||
385                 !pa_tagstruct_eof(t)) {
386                 pa_context_fail(c, PA_ERR_PROTOCOL);
387                 goto finish;
388             }
389
390             /* Minimum supported version */
391             if (c->version < 8) {
392                 pa_context_fail(c, PA_ERR_VERSION);
393                 goto finish;
394             }
395
396             /* Enable shared memory support if possible */
397             if (c->version >= 10 &&
398                 pa_mempool_is_shared(c->mempool) &&
399                 c->is_local) {
400
401                 /* Only enable SHM if both sides are owned by the same
402                  * user. This is a security measure because otherwise
403                  * data private to the user might leak. */
404
405 #ifdef HAVE_CREDS
406                 const pa_creds *creds;
407                 if ((creds = pa_pdispatch_creds(pd)))
408                     if (getuid() == creds->uid)
409                         pa_pstream_use_shm(c->pstream, 1);
410 #endif
411             }
412
413             reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
414             pa_tagstruct_puts(reply, c->name);
415             pa_pstream_send_tagstruct(c->pstream, reply);
416             pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
417
418             pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
419             break;
420         }
421
422         case PA_CONTEXT_SETTING_NAME :
423             pa_context_set_state(c, PA_CONTEXT_READY);
424             break;
425
426         default:
427             pa_assert(0);
428     }
429
430 finish:
431     pa_context_unref(c);
432 }
433
434 static void setup_context(pa_context *c, pa_iochannel *io) {
435     pa_tagstruct *t;
436     uint32_t tag;
437
438     pa_assert(c);
439     pa_assert(io);
440
441     pa_context_ref(c);
442
443     pa_assert(!c->pstream);
444     c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
445
446     pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
447     pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
448     pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
449
450     pa_assert(!c->pdispatch);
451     c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
452
453     if (!c->conf->cookie_valid)
454         pa_log_warn("No cookie loaded. Attempting to connect without.");
455
456     t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
457     pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
458     pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
459
460 #ifdef HAVE_CREDS
461 {
462     pa_creds ucred;
463
464     if (pa_iochannel_creds_supported(io))
465         pa_iochannel_creds_enable(io);
466
467     ucred.uid = getuid();
468     ucred.gid = getgid();
469
470     pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
471 }
472 #else
473     pa_pstream_send_tagstruct(c->pstream, t);
474 #endif
475
476     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
477
478     pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
479
480     pa_context_unref(c);
481 }
482
483 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
484
485 #ifndef OS_IS_WIN32
486
487 static int context_connect_spawn(pa_context *c) {
488     pid_t pid;
489     int status, r;
490     int fds[2] = { -1, -1} ;
491     pa_iochannel *io;
492
493     pa_context_ref(c);
494
495     if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
496         pa_log("socketpair(): %s", pa_cstrerror(errno));
497         pa_context_fail(c, PA_ERR_INTERNAL);
498         goto fail;
499     }
500
501     pa_fd_set_cloexec(fds[0], 1);
502
503     pa_socket_low_delay(fds[0]);
504     pa_socket_low_delay(fds[1]);
505
506     if (c->spawn_api.prefork)
507         c->spawn_api.prefork();
508
509     if ((pid = fork()) < 0) {
510         pa_log("fork(): %s", pa_cstrerror(errno));
511         pa_context_fail(c, PA_ERR_INTERNAL);
512
513         if (c->spawn_api.postfork)
514             c->spawn_api.postfork();
515
516         goto fail;
517     } else if (!pid) {
518         /* Child */
519
520         char t[128];
521         const char *state = NULL;
522 #define MAX_ARGS 64
523         const char * argv[MAX_ARGS+1];
524         int n;
525
526         /* Not required, since fds[0] has CLOEXEC enabled anyway */
527         close(fds[0]);
528
529         if (c->spawn_api.atfork)
530             c->spawn_api.atfork();
531
532         /* Setup argv */
533
534         n = 0;
535
536         argv[n++] = c->conf->daemon_binary;
537         argv[n++] = "--daemonize=yes";
538
539         pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
540         argv[n++] = strdup(t);
541
542         while (n < MAX_ARGS) {
543             char *a;
544
545             if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
546                 break;
547
548             argv[n++] = a;
549         }
550
551         argv[n++] = NULL;
552
553         execv(argv[0], (char * const *) argv);
554         _exit(1);
555 #undef MAX_ARGS
556     }
557
558     /* Parent */
559
560     r = waitpid(pid, &status, 0);
561
562     if (c->spawn_api.postfork)
563         c->spawn_api.postfork();
564
565     if (r < 0) {
566         pa_log("waitpid(): %s", pa_cstrerror(errno));
567         pa_context_fail(c, PA_ERR_INTERNAL);
568         goto fail;
569     } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
570         pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
571         goto fail;
572     }
573
574     close(fds[1]);
575
576     c->is_local = 1;
577
578     io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
579
580     setup_context(c, io);
581     unlock_autospawn_lock_file(c);
582
583     pa_context_unref(c);
584
585     return 0;
586
587 fail:
588     if (fds[0] != -1)
589         close(fds[0]);
590     if (fds[1] != -1)
591         close(fds[1]);
592
593     unlock_autospawn_lock_file(c);
594
595     pa_context_unref(c);
596
597     return -1;
598 }
599
600 #endif /* OS_IS_WIN32 */
601
602 static int try_next_connection(pa_context *c) {
603     char *u = NULL;
604     int r = -1;
605
606     pa_assert(c);
607     pa_assert(!c->client);
608
609     for (;;) {
610         pa_xfree(u);
611         u = NULL;
612
613         c->server_list = pa_strlist_pop(c->server_list, &u);
614
615         if (!u) {
616
617 #ifndef OS_IS_WIN32
618             if (c->do_autospawn) {
619                 r = context_connect_spawn(c);
620                 goto finish;
621             }
622 #endif
623
624             pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
625             goto finish;
626         }
627
628         pa_log_debug("Trying to connect to %s...", u);
629
630         pa_xfree(c->server);
631         c->server = pa_xstrdup(u);
632
633         if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
634             continue;
635
636         c->is_local = pa_socket_client_is_local(c->client);
637         pa_socket_client_set_callback(c->client, on_connection, c);
638         break;
639     }
640
641     r = 0;
642
643 finish:
644     pa_xfree(u);
645
646     return r;
647 }
648
649 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
650     pa_context *c = userdata;
651
652     pa_assert(client);
653     pa_assert(c);
654     pa_assert(c->state == PA_CONTEXT_CONNECTING);
655
656     pa_context_ref(c);
657
658     pa_socket_client_unref(client);
659     c->client = NULL;
660
661     if (!io) {
662         /* Try the item in the list */
663         if (errno == ECONNREFUSED || errno == ETIMEDOUT || errno == EHOSTUNREACH) {
664             try_next_connection(c);
665             goto finish;
666         }
667
668         pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
669         goto finish;
670     }
671
672     unlock_autospawn_lock_file(c);
673     setup_context(c, io);
674
675 finish:
676     pa_context_unref(c);
677 }
678
679 int pa_context_connect(
680         pa_context *c,
681         const char *server,
682         pa_context_flags_t flags,
683         const pa_spawn_api *api) {
684
685     int r = -1;
686
687     pa_assert(c);
688     pa_assert(PA_REFCNT_VALUE(c) >= 1);
689
690     PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
691     PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
692     PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
693
694     if (!server)
695         server = c->conf->default_server;
696
697     pa_context_ref(c);
698
699     pa_assert(!c->server_list);
700
701     if (server) {
702         if (!(c->server_list = pa_strlist_parse(server))) {
703             pa_context_fail(c, PA_ERR_INVALIDSERVER);
704             goto finish;
705         }
706     } else {
707         char *d;
708         char ufn[PATH_MAX];
709
710         /* Prepend in reverse order */
711
712         if ((d = getenv("DISPLAY"))) {
713             char *e;
714             d = pa_xstrdup(d);
715             if ((e = strchr(d, ':')))
716                 *e = 0;
717
718             if (*d)
719                 c->server_list = pa_strlist_prepend(c->server_list, d);
720
721             pa_xfree(d);
722         }
723
724         c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
725         c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
726
727         /* The system wide instance */
728         c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH "/" PA_NATIVE_DEFAULT_UNIX_SOCKET);
729
730         /* The per-user instance */
731         c->server_list = pa_strlist_prepend(c->server_list, pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET, ufn, sizeof(ufn)));
732
733         /* Wrap the connection attempts in a single transaction for sane autospawn locking */
734         if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
735             char lf[PATH_MAX];
736
737             pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
738             pa_make_secure_parent_dir(lf, 0700, (uid_t)-1, (gid_t)-1);
739             pa_assert(c->autospawn_lock_fd <= 0);
740             c->autospawn_lock_fd = pa_lock_lockfile(lf);
741
742             if (api)
743                 c->spawn_api = *api;
744             c->do_autospawn = 1;
745         }
746
747     }
748
749     pa_context_set_state(c, PA_CONTEXT_CONNECTING);
750     r = try_next_connection(c);
751
752 finish:
753     pa_context_unref(c);
754
755     return r;
756 }
757
758 void pa_context_disconnect(pa_context *c) {
759     pa_assert(c);
760     pa_assert(PA_REFCNT_VALUE(c) >= 1);
761
762     pa_context_set_state(c, PA_CONTEXT_TERMINATED);
763 }
764
765 pa_context_state_t pa_context_get_state(pa_context *c) {
766     pa_assert(c);
767     pa_assert(PA_REFCNT_VALUE(c) >= 1);
768
769     return c->state;
770 }
771
772 int pa_context_errno(pa_context *c) {
773     pa_assert(c);
774     pa_assert(PA_REFCNT_VALUE(c) >= 1);
775
776     return c->error;
777 }
778
779 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
780     pa_assert(c);
781     pa_assert(PA_REFCNT_VALUE(c) >= 1);
782
783     c->state_callback = cb;
784     c->state_userdata = userdata;
785 }
786
787 int pa_context_is_pending(pa_context *c) {
788     pa_assert(c);
789     pa_assert(PA_REFCNT_VALUE(c) >= 1);
790
791     PA_CHECK_VALIDITY(c,
792                       c->state == PA_CONTEXT_CONNECTING ||
793                       c->state == PA_CONTEXT_AUTHORIZING ||
794                       c->state == PA_CONTEXT_SETTING_NAME ||
795                       c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
796
797     return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
798         (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
799         c->client;
800 }
801
802 static void set_dispatch_callbacks(pa_operation *o);
803
804 static void pdispatch_drain_callback(PA_GCC_UNUSED pa_pdispatch*pd, void *userdata) {
805     set_dispatch_callbacks(userdata);
806 }
807
808 static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) {
809     set_dispatch_callbacks(userdata);
810 }
811
812 static void set_dispatch_callbacks(pa_operation *o) {
813     int done = 1;
814
815     pa_assert(o);
816     pa_assert(PA_REFCNT_VALUE(o) >= 1);
817     pa_assert(o->context);
818     pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
819     pa_assert(o->context->state == PA_CONTEXT_READY);
820
821     pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
822     pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
823
824     if (pa_pdispatch_is_pending(o->context->pdispatch)) {
825         pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
826         done = 0;
827     }
828
829     if (pa_pstream_is_pending(o->context->pstream)) {
830         pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
831         done = 0;
832     }
833
834     if (done) {
835         if (o->callback) {
836             pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
837             cb(o->context, o->userdata);
838         }
839
840         pa_operation_done(o);
841         pa_operation_unref(o);
842     }
843 }
844
845 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
846     pa_operation *o;
847
848     pa_assert(c);
849     pa_assert(PA_REFCNT_VALUE(c) >= 1);
850
851     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
852     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
853
854     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
855     set_dispatch_callbacks(pa_operation_ref(o));
856
857     return o;
858 }
859
860 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
861     pa_operation *o = userdata;
862     int success = 1;
863
864     pa_assert(pd);
865     pa_assert(o);
866     pa_assert(PA_REFCNT_VALUE(o) >= 1);
867
868     if (!o->context)
869         goto finish;
870
871     if (command != PA_COMMAND_REPLY) {
872         if (pa_context_handle_error(o->context, command, t) < 0)
873             goto finish;
874
875         success = 0;
876     } else if (!pa_tagstruct_eof(t)) {
877         pa_context_fail(o->context, PA_ERR_PROTOCOL);
878         goto finish;
879     }
880
881     if (o->callback) {
882         pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
883         cb(o->context, success, o->userdata);
884     }
885
886 finish:
887     pa_operation_done(o);
888     pa_operation_unref(o);
889 }
890
891 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
892     pa_tagstruct *t;
893     pa_operation *o;
894     uint32_t tag;
895
896     pa_assert(c);
897     pa_assert(PA_REFCNT_VALUE(c) >= 1);
898
899     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
900
901     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
902
903     t = pa_tagstruct_command(c, PA_COMMAND_EXIT, &tag);
904     pa_pstream_send_tagstruct(c->pstream, t);
905     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);
906
907     return o;
908 }
909
910 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) {
911     pa_tagstruct *t;
912     pa_operation *o;
913     uint32_t tag;
914
915     pa_assert(c);
916     pa_assert(PA_REFCNT_VALUE(c) >= 1);
917
918     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
919
920     o = pa_operation_new(c, NULL, cb, userdata);
921
922     t = pa_tagstruct_command(c, command, &tag);
923     pa_pstream_send_tagstruct(c->pstream, t);
924     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
925
926     return o;
927 }
928
929 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
930     pa_tagstruct *t;
931     pa_operation *o;
932     uint32_t tag;
933
934     pa_assert(c);
935     pa_assert(PA_REFCNT_VALUE(c) >= 1);
936
937     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
938
939     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
940
941     t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
942     pa_tagstruct_puts(t, name);
943     pa_pstream_send_tagstruct(c->pstream, t);
944     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);
945
946     return o;
947 }
948
949 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
950     pa_tagstruct *t;
951     pa_operation *o;
952     uint32_t tag;
953
954     pa_assert(c);
955     pa_assert(PA_REFCNT_VALUE(c) >= 1);
956
957     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
958
959     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
960
961     t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
962     pa_tagstruct_puts(t, name);
963     pa_pstream_send_tagstruct(c->pstream, t);
964     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);
965
966     return o;
967 }
968
969 int pa_context_is_local(pa_context *c) {
970     pa_assert(c);
971
972     return c->is_local;
973 }
974
975 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
976     pa_tagstruct *t;
977     pa_operation *o;
978     uint32_t tag;
979
980     pa_assert(c);
981     pa_assert(PA_REFCNT_VALUE(c) >= 1);
982     pa_assert(name);
983
984     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
985
986     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
987
988     t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
989     pa_tagstruct_puts(t, name);
990     pa_pstream_send_tagstruct(c->pstream, t);
991     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);
992
993     return o;
994 }
995
996 const char* pa_get_library_version(void) {
997     return PACKAGE_VERSION;
998 }
999
1000 const char* pa_context_get_server(pa_context *c) {
1001     pa_assert(c);
1002     pa_assert(PA_REFCNT_VALUE(c) >= 1);
1003
1004     if (!c->server)
1005         return NULL;
1006
1007     if (*c->server == '{') {
1008         char *e = strchr(c->server+1, '}');
1009         return e ? e+1 : c->server;
1010     }
1011
1012     return c->server;
1013 }
1014
1015 uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) {
1016     return PA_PROTOCOL_VERSION;
1017 }
1018
1019 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
1020     pa_assert(c);
1021     pa_assert(PA_REFCNT_VALUE(c) >= 1);
1022
1023     return c->version;
1024 }
1025
1026 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1027     pa_tagstruct *t;
1028
1029     pa_assert(c);
1030     pa_assert(tag);
1031
1032     t = pa_tagstruct_new(NULL, 0);
1033     pa_tagstruct_putu32(t, command);
1034     pa_tagstruct_putu32(t, *tag = c->ctag++);
1035
1036     return t;
1037 }