Mercurial > libavformat.hg
changeset 5516:afe4a96b6832 libavformat
Provide fallback implementations of getaddrinfo() and freeaddrinfo().
Patch by Martin Storsj <$firstname()$firstname,st>.
author | rbultje |
---|---|
date | Mon, 11 Jan 2010 17:27:07 +0000 |
parents | fa3115c9b043 |
children | 4ccdf5d8d424 |
files | network.h os_support.c |
diffstat | 2 files changed, 108 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/network.h Mon Jan 11 17:14:16 2010 +0000 +++ b/network.h Mon Jan 11 17:27:07 2010 +0000 @@ -68,4 +68,42 @@ int inet_aton (const char * str, struct in_addr * add); #endif +#if !HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + int ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; +#endif + +/* getaddrinfo constants */ +#ifndef EAI_FAIL +#define EAI_FAIL 4 +#endif + +#ifndef AI_PASSIVE +#define AI_PASSIVE 1 +#endif + +#ifndef AI_CANONNAME +#define AI_CANONNAME 2 +#endif + +#ifndef AI_NUMERICHOST +#define AI_NUMERICHOST 4 +#endif + +#if !HAVE_GETADDRINFO +int ff_getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res); +void ff_freeaddrinfo(struct addrinfo *res); +#define getaddrinfo ff_getaddrinfo +#define freeaddrinfo ff_freeaddrinfo +#endif + #endif /* AVFORMAT_NETWORK_H */
--- a/os_support.c Mon Jan 11 17:14:16 2010 +0000 +++ b/os_support.c Mon Jan 11 17:27:07 2010 +0000 @@ -60,6 +60,76 @@ } #endif /* !HAVE_INET_ATON */ +#if !HAVE_GETADDRINFO +int ff_getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct hostent *h = NULL; + struct addrinfo *ai; + struct sockaddr_in *sin; + + sin = av_mallocz(sizeof(struct sockaddr_in)); + if (!sin) + return EAI_FAIL; + sin->sin_family = AF_INET; + + if (node) { + if (!inet_aton(node, &sin->sin_addr)) { + if (hints && (hints->ai_flags & AI_NUMERICHOST)) { + av_free(sin); + return EAI_FAIL; + } + h = gethostbyname(node); + if (!h) { + av_free(sin); + return EAI_FAIL; + } + memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); + } + } else { + if (hints && (hints->ai_flags & AI_PASSIVE)) { + sin->sin_addr.s_addr = INADDR_ANY; + } else + sin->sin_addr.s_addr = INADDR_LOOPBACK; + } + + /* Note: getaddrinfo allows service to be a string, which + * should be looked up using getservbyname. */ + if (service) + sin->sin_port = htons(atoi(service)); + + ai = av_mallocz(sizeof(struct addrinfo)); + if (!ai) { + av_free(sin); + return EAI_FAIL; + } + + *res = ai; + ai->ai_family = AF_INET; + ai->ai_socktype = hints ? hints->ai_socktype : 0; + switch (ai->ai_socktype) { + case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break; + case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break; + default: ai->ai_protocol = 0; break; + } + + ai->ai_addr = (struct sockaddr *)sin; + ai->ai_addrlen = sizeof(struct sockaddr_in); + if (hints && (hints->ai_flags & AI_CANONNAME)) + ai->ai_canonname = h ? av_strdup(h->h_name) : NULL; + + ai->ai_next = NULL; + return 0; +} + +void ff_freeaddrinfo(struct addrinfo *res) +{ + av_free(res->ai_canonname); + av_free(res->ai_addr); + av_free(res); +} +#endif + /* resolve host with also IP address parsing */ int resolve_host(struct in_addr *sin_addr, const char *hostname) {