summaryrefslogtreecommitdiffstats
path: root/polyp/socket-client.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-12-15 01:02:50 +0000
committerLennart Poettering <lennart@poettering.net>2004-12-15 01:02:50 +0000
commit99e0779b51ccf4482dd35e78fe2f80744633004e (patch)
treedbcb8ccabe55118c59cd3653dcaac3d4b1a39b38 /polyp/socket-client.c
parentbc5b917f93f39215b54593cc45228e97e14daec3 (diff)
* Publish server info in mDNS in addition to sinks/sources
* Split off address parser * Add port= argument to module-zeroconf-publish git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@324 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'polyp/socket-client.c')
-rw-r--r--polyp/socket-client.c108
1 files changed, 22 insertions, 86 deletions
diff --git a/polyp/socket-client.c b/polyp/socket-client.c
index c58c7bd4..0581e553 100644
--- a/polyp/socket-client.c
+++ b/polyp/socket-client.c
@@ -39,6 +39,7 @@
#include "util.h"
#include "xmalloc.h"
#include "log.h"
+#include "parseaddr.h"
struct pa_socket_client {
int ref;
@@ -254,121 +255,56 @@ struct pa_socket_client* pa_socket_client_new_ipv6(struct pa_mainloop_api *m, ui
return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
}
-/* Parse addresses in one of the following forms:
- * HOSTNAME
- * HOSTNAME:PORT
- * [HOSTNAME]
- * [HOSTNAME]:PORT
- *
- * Return a newly allocated string of the hostname and fill in *port if specified */
-
-static char *parse_address(const char *s, uint16_t *port) {
- assert(s && port);
- if (*s == '[') {
- char *e;
- if (!(e = strchr(s+1, ']')))
- return NULL;
-
- if (e[1] == ':')
- *port = atoi(e+2);
- else if (e[1] != 0)
- return NULL;
-
- return pa_xstrndup(s+1, e-s-1);
- } else {
- char *e;
-
- if (!(e = strrchr(s, ':')))
- return pa_xstrdup(s);
-
- *port = atoi(e+1);
- return pa_xstrndup(s, e-s);
- }
-}
-
struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m, const char*name, uint16_t default_port) {
- const char *p;
struct pa_socket_client *c = NULL;
- enum { KIND_UNIX, KIND_TCP_AUTO, KIND_TCP4, KIND_TCP6 } kind = KIND_TCP_AUTO;
+ struct pa_parsed_address a;
assert(m && name);
- if (*name == '{') {
- char hn[256], *pfx;
- /* The URL starts with a host specification for detecting local connections */
-
- if (!pa_get_host_name(hn, sizeof(hn)))
- return NULL;
-
- pfx = pa_sprintf_malloc("{%s}", hn);
- if (!pa_startswith(name, pfx))
- /* Not local */
- return NULL;
-
- p = name + strlen(pfx);
- } else
- p = name;
-
- if (*p == '/')
- kind = KIND_UNIX;
- else if (pa_startswith(p, "unix:")) {
- kind = KIND_UNIX;
- p += sizeof("unix:")-1;
- } else if (pa_startswith(p, "tcp:") || pa_startswith(p, "tcp4:")) {
- kind = KIND_TCP4;
- p += sizeof("tcp:")-1;
- } else if (pa_startswith(p, "tcp6:")) {
- kind = KIND_TCP6;
- p += sizeof("tcp6:")-1;
- }
+ if (pa_parse_address(name, &a) < 0)
+ return NULL;
- switch (kind) {
- case KIND_UNIX:
- return pa_socket_client_new_unix(m, p);
+ switch (a.type) {
+ case PA_PARSED_ADDRESS_UNIX:
+ c = pa_socket_client_new_unix(m, a.path_or_host);
+ break;
- case KIND_TCP_AUTO: /* Fallthrough */
- case KIND_TCP4:
- case KIND_TCP6: {
- uint16_t port = default_port;
- char *h;
+ case PA_PARSED_ADDRESS_TCP4: /* Fallthrough */
+ case PA_PARSED_ADDRESS_TCP6: /* Fallthrough */
+ case PA_PARSED_ADDRESS_TCP_AUTO:{
int ret;
struct addrinfo hints, *res;
- if (!(h = parse_address(p, &port)))
- return NULL;
-
memset(&hints, 0, sizeof(hints));
- hints.ai_family = kind == KIND_TCP4 ? AF_INET : (kind == KIND_TCP6 ? AF_INET6 : AF_UNSPEC);
+ hints.ai_family = a.type == PA_PARSED_ADDRESS_TCP4 ? AF_INET : (a.type == PA_PARSED_ADDRESS_TCP6 ? AF_INET6 : AF_UNSPEC);
- ret = getaddrinfo(h, NULL, &hints, &res);
- pa_xfree(h);
+ ret = getaddrinfo(a.path_or_host, NULL, &hints, &res);
if (ret < 0 || !res || !res->ai_addr)
- return NULL;
+ goto finish;
if (res->ai_family == AF_INET) {
if (res->ai_addrlen != sizeof(struct sockaddr_in))
- return NULL;
+ goto finish;
assert(res->ai_addr->sa_family == res->ai_family);
- ((struct sockaddr_in*) res->ai_addr)->sin_port = htons(port);
+ ((struct sockaddr_in*) res->ai_addr)->sin_port = htons(a.port);
} else if (res->ai_family == AF_INET6) {
if (res->ai_addrlen != sizeof(struct sockaddr_in6))
- return NULL;
+ goto finish;
assert(res->ai_addr->sa_family == res->ai_family);
- ((struct sockaddr_in6*) res->ai_addr)->sin6_port = htons(port);
+ ((struct sockaddr_in6*) res->ai_addr)->sin6_port = htons(a.port);
} else
- return NULL;
+ goto finish;
c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
- return c;
}
}
- /* Should never be reached */
- assert(0);
- return NULL;
+finish:
+ pa_xfree(a.path_or_host);
+ return c;
}