$NetBSD: patch-ao,v 1.4 2002/10/14 09:47:00 rh Exp $

--- Input/mpg123/http.c.orig	Tue Jan  8 00:08:04 2002
+++ Input/mpg123/http.c
@@ -332,8 +332,13 @@ static void *http_buffer_loop(void *arg)
 	gboolean redirect;
 	int udp_sock = 0;
 	fd_set set;
+#ifdef USE_IPV6
+	struct addrinfo hints, *res, *res0;
+	char service[6];
+#else
 	struct hostent *hp;
 	struct sockaddr_in address;
+#endif
 	struct timeval tv;
 
 	url = (gchar *) arg;
@@ -355,6 +360,45 @@ static void *http_buffer_loop(void *arg)
 		chost = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_host : host;
 		cport = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_port : port;
 
+#ifdef USE_IPV6
+		snprintf(service, 6, "%d", cport);
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_socktype = SOCK_STREAM;
+		if (! getaddrinfo(chost, service, &hints, &res0)) {
+			eof = TRUE;
+			for (res = res0; res; res = res->ai_next) {
+				if ((sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
+					continue;
+				fcntl(sock, F_SETFL, O_NONBLOCK);
+				status = g_strdup_printf(_("CONNECTING TO %s:%d"), chost, cport);
+				mpg123_ip.set_info_text(status);
+				g_free(status);
+				((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(cport);
+				if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
+					if (errno != EINPROGRESS) {
+						close(sock);
+						continue;
+					}
+				}
+				eof = FALSE;
+				break;
+			}
+			freeaddrinfo(res0);
+			if (eof) {
+				status = g_strdup_printf(_("Couldn't connect to host %s:%d"), chost, cport);
+				show_error_message(status);
+				g_free(status);
+				mpg123_ip.set_info_text(NULL);
+			}
+		} else {
+			status = g_strdup_printf(_("Couldn't look up host %s"), chost);
+			show_error_message(status);
+			g_free(status);
+
+			mpg123_ip.set_info_text(NULL);
+			eof = TRUE;
+		}
+#else
 		sock = socket(AF_INET, SOCK_STREAM, 0);
 		fcntl(sock, F_SETFL, O_NONBLOCK);
 		address.sin_family = AF_INET;
@@ -372,9 +416,11 @@ static void *http_buffer_loop(void *arg)
 			mpg123_ip.set_info_text(NULL);
 			eof = TRUE;
 		}
+#endif
 
 		if (!eof)
 		{
+#ifndef USE_IPV6
 			memcpy(&address.sin_addr.s_addr, *(hp->h_addr_list), sizeof (address.sin_addr.s_addr));
 			address.sin_port = g_htons(cport);
 
@@ -393,6 +439,7 @@ static void *http_buffer_loop(void *arg)
 					eof = TRUE;
 				}
 			}
+#endif
 			while (going)
 			{
 				tv.tv_sec = 0;
@@ -697,14 +744,23 @@ char *mpg123_http_get_title(char *url)
 /* Find a good local udp port and bind udp_sock to it, return the port */
 static int udp_establish_listener(int *sock)
 {
+#ifdef USE_IPV6
+	struct sockaddr_in6 sin;
+	socklen_t sinlen = sizeof (struct sockaddr_in6);
+#else
 	struct sockaddr_in sin;
 	socklen_t sinlen = sizeof (struct sockaddr_in);
+#endif
 	
 #ifdef DEBUG_UDP
 	fprintf (stderr,"Establishing udp listener\n");
 #endif
 	
+#ifdef USE_IPV6
+	if ((*sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+#else
 	if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+#endif
 	{
 		g_log(NULL, G_LOG_LEVEL_CRITICAL,
 		      "udp_establish_listener(): unable to create socket");
@@ -712,8 +768,12 @@ static int udp_establish_listener(int *s
 	}
 
 	memset(&sin, 0, sinlen);
+#ifdef USE_IPV6
+	sin.sin6_family = AF_INET6;
+#else
 	sin.sin_family = AF_INET;
 	sin.sin_addr.s_addr = g_htonl(INADDR_ANY);
+#endif
 			
 	if (bind(*sock, (struct sockaddr *)&sin, sinlen) < 0)
 	{
@@ -743,7 +803,11 @@ static int udp_establish_listener(int *s
 	fprintf (stderr,"Listening on local %s:%d\n", inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
 #endif
 	
+#ifdef USE_IPV6
+	return g_ntohs(sin.sin6_port);
+#else
 	return g_ntohs(sin.sin_port);
+#endif
 }
 
 static int udp_check_for_data(int sock)
@@ -752,10 +816,14 @@ static int udp_check_for_data(int sock)
 	char *valptr;
 	gchar *title;
 	gint len, i;
+#ifdef USE_IPV6
+	struct sockaddr_in6 from;
+#else
 	struct sockaddr_in from;
+#endif
 	socklen_t fromlen;
 
-	fromlen = sizeof(struct sockaddr_in);
+	fromlen = sizeof(from);
 	
 	if ((len = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen)) < 0)
 	{
@@ -840,7 +908,14 @@ static int udp_check_for_data(int sock)
 #ifdef DEBUG_UDP
 			else
 				fprintf(stderr,"Sent ack: %s", obuf);
+#ifdef USE_IPV6
+{
+			char adr[INET6_ADDRSTRLEN];
+			inet_ntop(AF_INET6, &from.sin6_addr, adr, INET6_ADDRSTRLEN);
+			fprintf (stderr,"Remote: [%s]:%d\n", adr, g_ntohs(from.sin6_port));
+#else
 			fprintf (stderr,"Remote: %s:%d\n", inet_ntoa(from.sin_addr), g_ntohs(from.sin_port));
+#endif
 #endif
 		}
 	}
