return -1;
}
- if (*verbose)
+ if (*verbose) {
snprintf(txt, sizeof(txt), "Module successfully loaded, index: %u.\n", m->index);
- pa_strbuf_puts(buf, txt);
+ pa_strbuf_puts(buf, txt);
+ }
return 0;
}
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
#include "polyp.h"
#include "protocol-native-spec.h"
#define DEFAULT_TIMEOUT (5*60)
#define DEFAULT_SERVER "/tmp/polypaudio/native"
+#define DEFAULT_PORT "4713"
struct pa_context {
char *name;
struct pa_context *c = userdata;
struct pa_tagstruct *t;
uint32_t tag;
- assert(client && io && c && c->state == CONTEXT_CONNECTING);
+ assert(client && c && c->state == CONTEXT_CONNECTING);
pa_socket_client_free(client);
c->client = NULL;
c->state = CONTEXT_AUTHORIZING;
}
+static struct sockaddr *resolve_server(const char *server, size_t *len) {
+ struct sockaddr *sa;
+ struct addrinfo hints, *result = NULL;
+ char *port;
+ assert(server && len);
+
+ if ((port = strrchr(server, ':')))
+ port++;
+ if (!port)
+ port = DEFAULT_PORT;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+
+ if (getaddrinfo(server, port, &hints, &result) != 0)
+ return NULL;
+ assert(result);
+
+ sa = malloc(*len = result->ai_addrlen);
+ assert(sa);
+ memcpy(sa, result->ai_addr, *len);
+
+ freeaddrinfo(result);
+
+ return sa;
+
+}
+
int pa_context_connect(struct pa_context *c, const char *server, void (*complete) (struct pa_context*c, int success, void *userdata), void *userdata) {
assert(c && c->state == CONTEXT_UNCONNECTED);
return -1;
}
+ if (!server)
+ if (!(server = getenv("POLYP_SERVER")))
+ server = DEFAULT_SERVER;
+
assert(!c->client);
- if (!(c->client = pa_socket_client_new_unix(c->mainloop, server ? server : DEFAULT_SERVER))) {
- c->error = PA_ERROR_CONNECTIONREFUSED;
- return -1;
+
+ if (*server == '/') {
+ if (!(c->client = pa_socket_client_new_unix(c->mainloop, server))) {
+ c->error = PA_ERROR_CONNECTIONREFUSED;
+ return -1;
+ }
+ } else {
+ struct sockaddr* sa;
+ size_t sa_len;
+
+ if (!(sa = resolve_server(server, &sa_len))) {
+ c->error = PA_ERROR_INVALIDSERVER;
+ return -1;
+ }
+
+ c->client = pa_socket_client_new_sockaddr(c->mainloop, sa, sa_len);
+ free(sa);
+
+ if (!c->client) {
+ c->error = PA_ERROR_CONNECTIONREFUSED;
+ return -1;
+ }
}
c->connect_complete_callback = complete;
PA_ERROR_INTERNAL,
PA_ERROR_CONNECTIONTERMINATED,
PA_ERROR_KILLED,
+ PA_ERROR_INVALIDSERVER,
PA_ERROR_MAX
};
static void connect_io_cb(struct pa_mainloop_api*m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
struct pa_socket_client *c = userdata;
- assert(m && c && c->io_source == id && fd >= 0 && events == PA_MAINLOOP_API_IO_EVENT_OUTPUT);
+ assert(m && c && c->io_source == id && fd >= 0);
m->cancel_io(m, c->io_source);
c->io_source = NULL;
do_call(c);
pa_make_nonblock_fd(c->fd);
if ((r = connect(c->fd, sa, len)) < 0) {
- if (r != EINPROGRESS) {
+ if (errno != EINPROGRESS) {
fprintf(stderr, "connect(): %s\n", strerror(errno));
return -1;
}
pa_socket_client_free(c);
return NULL;
}
+
+struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) {
+ struct pa_socket_client *c;
+ assert(m && sa);
+ c = pa_socket_client_new(m);
+ assert(c);
+
+ if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "socket(): %s\n", strerror(errno));
+ goto fail;
+ }
+
+ if (sa->sa_family == AF_INET)
+ pa_socket_tcp_low_delay(c->fd);
+ else
+ pa_socket_low_delay(c->fd);
+
+ if (do_connect(c, sa, salen) < 0)
+ goto fail;
+ return c;
+
+fail:
+ pa_socket_client_free(c);
+ return NULL;
+
+}
+
void pa_socket_client_free(struct pa_socket_client *c) {
assert(c && c->mainloop);
if (c->io_source)
struct pa_socket_client* pa_socket_client_new_ipv4(struct pa_mainloop_api *m, uint32_t address, uint16_t port);
struct pa_socket_client* pa_socket_client_new_unix(struct pa_mainloop_api *m, const char *filename);
+struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen);
void pa_socket_client_free(struct pa_socket_client *c);
+- modargs memory leak
+
+- clean secure directory handling (with username)
+
- native library/protocol:
more functions (esp. latency)
-- daemonizing
-
- prefix modules/libraries with pa_
- xmms+esound latency testing
- doxygen
- make mcalign merge chunks
- modinfo
+- daemonizing
drivers:
- libao