pa_client_conf_from_x11(c->conf, NULL);
#endif
pa_client_conf_env(c->conf);
-
+
return c;
}
while (c->streams)
pa_stream_set_state(c->streams, PA_STREAM_TERMINATED);
-
+
if (c->client)
pa_socket_client_unref(c->client);
if (c->pdispatch)
pa_context_ref(c);
+ c->state = st;
+ if (c->state_callback)
+ c->state_callback(c, c->state_userdata);
+
if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED) {
pa_stream *s;
c->client = NULL;
}
- c->state = st;
- if (c->state_callback)
- c->state_callback(c, c->state_userdata);
-
pa_context_unref(c);
}
pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
}
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata) {
pa_context *c = userdata;
assert(p);
pa_context_ref(c);
- if (pa_pdispatch_run(c->pdispatch, packet, c) < 0)
+ if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
pa_context_fail(c, PA_ERR_PROTOCOL);
pa_context_unref(c);
assert(c->ref >= 1);
pa_context_ref(c);
-
+
if ((s = pa_dynarray_get(c->record_streams, channel))) {
+ assert(seek == PA_SEEK_RELATIVE && offset == 0);
+
pa_memblockq_seek(s->record_memblockq, offset, seek);
pa_memblockq_push_align(s->record_memblockq, chunk);
-
+
if (s->read_callback) {
size_t l;
switch(c->state) {
case PA_CONTEXT_AUTHORIZING: {
pa_tagstruct *reply;
+
+ if (pa_tagstruct_getu32(t, &c->version) < 0 ||
+ !pa_tagstruct_eof(t)) {
+ pa_context_fail(c, PA_ERR_PROTOCOL);
+ goto finish;
+ }
+
+ /* Minimum supported version */
+ if (c->version < 8) {
+ pa_context_fail(c, PA_ERR_VERSION);
+ goto finish;
+ }
+
reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
pa_tagstruct_puts(reply, c->name);
pa_pstream_send_tagstruct(c->pstream, reply);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
break;
}
t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
+ pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
- pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c);
+ pa_pstream_send_tagstruct_with_creds(c->pstream, t, 1);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
pa_context_ref(c);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
- pa_log(__FILE__": socketpair() failed: %s\n", strerror(errno));
+ pa_log(__FILE__": socketpair() failed: %s", strerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
}
c->spawn_api.prefork();
if ((pid = fork()) < 0) {
- pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
+ pa_log(__FILE__": fork() failed: %s", strerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
if (c->spawn_api.postfork)
c->spawn_api.postfork();
if (r < 0) {
- pa_log(__FILE__": waitpid() failed: %s\n", strerror(errno));
+ pa_log(__FILE__": waitpid() failed: %s", strerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
goto finish;
}
- pa_log_debug(__FILE__": Trying to connect to %s...\n", u);
+ pa_log_debug(__FILE__": Trying to connect to %s...", u);
pa_xfree(c->server);
c->server = pa_xstrdup(u);
assert(c);
assert(c->ref >= 1);
-/* pa_log("pstream: %i\n", pa_pstream_is_pending(c->pstream)); */
-/* pa_log("pdispatch: %i\n", pa_pdispatch_is_pending(c->pdispatch)); */
-
+ PA_CHECK_VALIDITY(c,
+ c->state == PA_CONTEXT_CONNECTING ||
+ c->state == PA_CONTEXT_AUTHORIZING ||
+ c->state == PA_CONTEXT_SETTING_NAME ||
+ c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
(c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
c->client;
done = 0;
}
- if (!done)
- pa_operation_ref(o);
- else {
+ if (done) {
if (o->callback) {
pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
cb(o->context, o->userdata);
}
pa_operation_done(o);
- }
-
- pa_operation_unref(o);
+ pa_operation_unref(o);
+ }
}
pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
assert(pd);
assert(o);
assert(o->ref >= 1);
- assert(o->context);
+
+ if (!o->context)
+ goto finish;
if (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t) < 0)
t = pa_tagstruct_command(c, PA_COMMAND_EXIT, &tag);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o));
+ 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);
return o;
}
t = pa_tagstruct_command(c, command, &tag);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o));
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o));
+ 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);
return o;
}
t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o));
+ 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);
return o;
}
t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o));
+ 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);
return o;
}
return c->server;
}
+uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) {
+ return PA_PROTOCOL_VERSION;
+}
+
+uint32_t pa_context_get_server_protocol_version(pa_context *c) {
+ assert(c);
+ assert(c->ref >= 1);
+
+ return c->version;
+}
+
pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
pa_tagstruct *t;