$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 } }