8ceb32
From a2ef22d59904d5e53c3d58093b561fa1ab7127a6 Mon Sep 17 00:00:00 2001
8ceb32
From: Nils Philippsen <nils@redhat.com>
8ceb32
Date: Thu, 16 Aug 2012 10:58:54 +0200
8ceb32
Subject: [PATCH] patch: ipv6
8ceb32
8ceb32
Squashed commit of the following:
8ceb32
8ceb32
commit 9f9d5c46fdef5ba7baccb81ab8170cfc24797de6
8ceb32
Author: Nils Philippsen <nils@redhat.com>
8ceb32
Date:   Fri Nov 19 12:27:42 2010 +0100
8ceb32
8ceb32
    support IPv6 (#198422)
8ceb32
---
8ceb32
 src/xsane-save.c | 96 ++++++++++++++++++++++++++++++++++++--------------------
8ceb32
 1 file changed, 62 insertions(+), 34 deletions(-)
8ceb32
8ceb32
diff --git a/src/xsane-save.c b/src/xsane-save.c
8ceb32
index 84f5d59..87ef685 100644
8ceb32
--- a/src/xsane-save.c
8ceb32
+++ b/src/xsane-save.c
8ceb32
@@ -29,6 +29,8 @@
8ceb32
 #include <time.h>
8ceb32
 #include <sys/wait.h> 
8ceb32
 
8ceb32
+#include <glib.h>
8ceb32
+
8ceb32
 /* the following test is always false */
8ceb32
 #ifdef _native_WIN32
8ceb32
 # include <winsock.h>
8ceb32
@@ -7488,55 +7490,81 @@ void write_email_attach_file(int fd_socket, char *boundary, FILE *infile, char *
8ceb32
 /* returns fd_socket if sucessfull, < 0 when error occured */
8ceb32
 int open_socket(char *server, int port)
8ceb32
 {
8ceb32
- int fd_socket;
8ceb32
- struct sockaddr_in sin;
8ceb32
- struct hostent *he;
8ceb32
+ int fd_socket, e;
8ceb32
+
8ceb32
+ struct addrinfo *ai_list, *ai;
8ceb32
+ struct addrinfo hints;
8ceb32
+ gchar *port_s;
8ceb32
+ gint connected;
8ceb32
+
8ceb32
+  memset(&hints, '\0', sizeof(hints));
8ceb32
+  hints.ai_flags = AI_ADDRCONFIG;
8ceb32
+  hints.ai_socktype = SOCK_STREAM;
8ceb32
+
8ceb32
+  port_s = g_strdup_printf("%d", port);
8ceb32
+  e = getaddrinfo(server, port_s, &hints, &ai_list);
8ceb32
+  g_free(port_s);
8ceb32
 
8ceb32
-  he = gethostbyname(server);
8ceb32
-  if (!he)
8ceb32
+  if (e != 0)
8ceb32
   {
8ceb32
-    DBG(DBG_error, "open_socket: Could not get hostname of \"%s\"\n", server);
8ceb32
+    DBG(DBG_error, "open_socket: Could not lookup \"%s\"\n", server);
8ceb32
    return -1;
8ceb32
   }
8ceb32
-  else
8ceb32
+
8ceb32
+  connected = 0;
8ceb32
+  for (ai = ai_list; ai != NULL && !connected; ai = ai->ai_next)
8ceb32
   {
8ceb32
-    DBG(DBG_info, "open_socket: connecting to \"%s\" = %d.%d.%d.%d\n",
8ceb32
-        he->h_name,
8ceb32
-        (unsigned char) he->h_addr_list[0][0],
8ceb32
-        (unsigned char) he->h_addr_list[0][1],
8ceb32
-        (unsigned char) he->h_addr_list[0][2],
8ceb32
-        (unsigned char) he->h_addr_list[0][3]);
8ceb32
-  }
8ceb32
+    gchar hostname[NI_MAXHOST];
8ceb32
+    gchar hostaddr[NI_MAXHOST];
8ceb32
+
8ceb32
+    /* If all else fails */
8ceb32
+    strncpy(hostname, "(unknown name)", NI_MAXHOST-1);
8ceb32
+    strncpy(hostaddr, "(unknown address)", NI_MAXHOST-1);
8ceb32
+
8ceb32
+    /* Determine canonical name and IPv4/IPv6 address */
8ceb32
+    (void) getnameinfo(ai->ai_addr, ai->ai_addrlen, hostname, sizeof(hostname),
8ceb32
+                       NULL, 0, 0);
8ceb32
+    (void) getnameinfo(ai->ai_addr, ai->ai_addrlen, hostaddr, sizeof(hostaddr),
8ceb32
+                       NULL, 0, NI_NUMERICHOST);
8ceb32
+
8ceb32
+    DBG(DBG_info, "open_socket: connecting to \"%s\" (\"%s\"): %s\n",
8ceb32
+        server, hostname, hostaddr);
8ceb32
  
8ceb32
-  if (he->h_addrtype != AF_INET)
8ceb32
-  {
8ceb32
-    DBG(DBG_error, "open_socket: Unknown address family: %d\n", he->h_addrtype);
8ceb32
-   return -1;
8ceb32
-  }
8ceb32
+    if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6))
8ceb32
+    {
8ceb32
+      DBG(DBG_error, "open_socket: Unknown address family: %d\n", ai->ai_family);
8ceb32
+      continue;
8ceb32
+    }
8ceb32
 
8ceb32
-  fd_socket = socket(AF_INET, SOCK_STREAM, 0);
8ceb32
+    fd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
8ceb32
 
8ceb32
-  if (fd_socket < 0)
8ceb32
-  {
8ceb32
-    DBG(DBG_error, "open_socket: Could not create socket: %s\n", strerror(errno));
8ceb32
-   return -1;
8ceb32
-  }
8ceb32
+    if (fd_socket < 0)
8ceb32
+    {
8ceb32
+      DBG(DBG_error, "open_socket: Could not create socket: %s\n", strerror(errno));
8ceb32
+      continue;
8ceb32
+    }
8ceb32
 
8ceb32
-/*  setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)); */
8ceb32
+    /*  setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)); */
8ceb32
 
8ceb32
-  sin.sin_port = htons(port);
8ceb32
-  sin.sin_family = AF_INET;
8ceb32
-  memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length);
8ceb32
+    if (connect(fd_socket, ai->ai_addr, ai->ai_addrlen) != 0)
8ceb32
+    {
8ceb32
+      DBG(DBG_error, "open_socket: Could not connect with port %d of socket: %s\n", port, strerror(errno));
8ceb32
+      continue;
8ceb32
+    }
8ceb32
+
8ceb32
+    /* All went well */
8ceb32
+    connected = 1;
8ceb32
+  }
8ceb32
 
8ceb32
-  if (connect(fd_socket, &sin, sizeof(sin)))
8ceb32
+  if (!connected)
8ceb32
   {
8ceb32
-    DBG(DBG_error, "open_socket: Could not connect with port %d of socket: %s\n", ntohs(sin.sin_port), strerror(errno));
8ceb32
-   return -1;
8ceb32
+    DBG(DBG_info, "open_socket: Could not connect to any address");
8ceb32
+    return -1;
8ceb32
   }
8ceb32
 
8ceb32
-  DBG(DBG_info, "open_socket: Connected with port %d\n", ntohs(sin.sin_port));
8ceb32
+  DBG(DBG_info, "open_socket: Connected with port %d\n", port);
8ceb32
 
8ceb32
- return fd_socket;
8ceb32
+  return fd_socket;
8ceb32
 }
8ceb32
 
8ceb32
 /* ---------------------------------------------------------------------------------------------------------------------- */
8ceb32
-- 
8ceb32
1.7.11.4
8ceb32