+
+#ifndef HAVE_GETADDRINFO
+
+int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
+{
+ /* Only support IPv4 if OS doesn't provide this function. */
+ struct sockaddr_in sin;
+
+ if (hints && hints->ai_family != AF_INET)
+ return 1;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+
+ if (node) {
+ if (hints && hints->ai_flags & AI_NUMERICHOST) {
+ if (!inet_aton(node, &sin.sin_addr))
+ return 2;
+ } else {
+ struct hostent *he;
+ he = gethostbyname(node);
+ if (!he)
+ return 3;
+ memcpy(&sin.sin_addr, he->h_addr, he->h_length);
+ }
+ } else if (hints && hints->ai_flags & AI_PASSIVE) {
+ /* leave it unspecifed */
+ } else {
+ inet_aton("127.0.0.1", &sin.sin_addr);
+ }
+
+ if (!service)
+ sin.sin_port = ntohs(0);
+ else if (!(sin.sin_port = ntohs(atoi(service))))
+ return 4;
+
+ *res = calloc(1, sizeof(**res) + sizeof(sin));
+ (*res)->ai_family = sin.sin_family;
+ (*res)->ai_socktype = hints && hints->ai_socktype ? hints->ai_socktype : SOCK_STREAM;
+ (*res)->ai_protocol = hints && hints->ai_socktype ? hints->ai_socktype : 0;
+ (*res)->ai_addrlen = sizeof(sin);
+ (*res)->ai_addr = (struct sockaddr*)(*res + 1);
+ memcpy((*res)->ai_addr, &sin, (*res)->ai_addrlen);
+ (*res)->ai_canonname = 0;
+ (*res)->ai_next = 0;
+ return 0;
+}
+
+/* TODO: implement fallback getnameinfo() */
+
+void freeaddrinfo(struct addrinfo *res)
+{
+ struct addrinfo *next;
+ for (; res; res = next) {
+ next = res->ai_next;
+ free(res);
+ }
+}
+
+#endif
+