diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-12-15 01:02:50 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-12-15 01:02:50 +0000 |
commit | 99e0779b51ccf4482dd35e78fe2f80744633004e (patch) | |
tree | dbcb8ccabe55118c59cd3653dcaac3d4b1a39b38 /polyp/socket-client.c | |
parent | bc5b917f93f39215b54593cc45228e97e14daec3 (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.c | 108 |
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; } |