diff --git a/gimp-2.6.9-script-fu-ipv6.patch b/gimp-2.6.9-script-fu-ipv6.patch index a1341d3..e45e139 100644 --- a/gimp-2.6.9-script-fu-ipv6.patch +++ b/gimp-2.6.9-script-fu-ipv6.patch @@ -1,18 +1,24 @@ -commit 859c381a9764d9d91e1ed8539a5919afbbbf2dbc -Author: Nils Philippsen -Date: Mon Jun 28 16:36:44 2010 +0200 +From 1979c0b0e66db34e69863c89e4eb544c89e9d41a Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Tue, 29 Jun 2010 16:06:45 +0200 +Subject: [PATCH] patch: script-fu-ipv6 - patch: script-fu-ipv6 - - Squashed commit of the following: - - commit e567516ade8ebf74598542f8b319f80eee873c65 - Author: Nils Philippsen - Date: Mon Jun 28 16:07:01 2010 +0200 - - Bug 623045 - script-fu: make logging IPv6-aware - - use getnameinfo() instead of inet_ntoa() +Squashed commit of the following: + +commit e0ae4b85c33d4241e95594b0d9788dafb27132c6 +Author: Nils Philippsen +Date: Tue Jun 29 16:03:31 2010 +0200 + + Bug 623045 - script-fu: make server IPv6 aware + + use getnameinfo() instead of inet_ntoa() + use two sockets for IPv4, IPv6 + (manually cherry picked from commit 04538534fc581de0507ef2ec1148853ff1e96dbe) +--- + configure.in | 8 +- + plug-ins/script-fu/script-fu-server.c | 141 +++++++++++++++++++++++++------- + plug-ins/script-fu/servertest.py | 76 ++++++++++++------ + 3 files changed, 166 insertions(+), 59 deletions(-) diff --git a/configure.in b/configure.in index 71f031d..a99cbe4 100644 @@ -38,12 +44,59 @@ index 71f031d..a99cbe4 100644 SOCKET_LIBS="$LIBS" diff --git a/plug-ins/script-fu/script-fu-server.c b/plug-ins/script-fu/script-fu-server.c -index db1de13..8fb8a10 100644 +index db1de13..c4776a2 100644 --- a/plug-ins/script-fu/script-fu-server.c +++ b/plug-ins/script-fu/script-fu-server.c -@@ -310,12 +310,16 @@ script_fu_server_listen (gint timeout) - /* Service the server socket if it has input pending. */ - if (FD_ISSET (server_sock, &fds)) +@@ -137,7 +137,8 @@ static void server_start (gint port, + const gchar *logfile); + static gboolean execute_command (SFCommand *cmd); + static gint read_from_client (gint filedes); +-static gint make_socket (guint port); ++static gint make_socket (const struct addrinfo ++ *ai); + static void server_log (const gchar *format, + ...) G_GNUC_PRINTF (1, 2); + static void server_quit (void); +@@ -151,7 +152,10 @@ static void print_socket_api_error (const gchar *api_name); + /* + * Local variables + */ +-static gint server_sock; ++static gint server_socks[2], ++ server_socks_used = 0; ++static const gint server_socks_len = sizeof (server_socks) / ++ sizeof (server_socks[0]); + static GList *command_queue = NULL; + static gint queue_length = 0; + static gint request_no = 0; +@@ -285,6 +289,7 @@ script_fu_server_listen (gint timeout) + struct timeval tv; + struct timeval *tvp = NULL; + SELECT_MASK fds; ++ gint sockno; + + /* Set time struct */ + if (timeout) +@@ -295,7 +300,10 @@ script_fu_server_listen (gint timeout) + } + + FD_ZERO (&fds); +- FD_SET (server_sock, &fds); ++ for (sockno = 0; sockno < server_socks_used; sockno++) ++ { ++ FD_SET (server_socks[sockno], &fds); ++ } + g_hash_table_foreach (clients, script_fu_server_add_fd, &fds); + + /* Block until input arrives on one or more active sockets +@@ -307,15 +315,25 @@ script_fu_server_listen (gint timeout) + return; + } + +- /* Service the server socket if it has input pending. */ +- if (FD_ISSET (server_sock, &fds)) ++ /* Service the server sockets if any has input pending. */ ++ for (sockno = 0; sockno < server_socks_used; sockno++) { - struct sockaddr_in clientname; + struct sockaddr_storage client; @@ -53,15 +106,22 @@ index db1de13..8fb8a10 100644 /* Connection request on original socket. */ - guint size = sizeof (clientname); -+ guint size = sizeof (client); - gint new = accept (server_sock, +- gint new = accept (server_sock, - (struct sockaddr *) &clientname, &size); -+ (struct sockaddr *) &client, &size); -+ guint portno; ++ guint size = sizeof (client); ++ gint new; ++ guint portno; ++ ++ if (! FD_ISSET (server_socks[sockno], &fds)) ++ { ++ continue; ++ } ++ ++ new = accept (server_socks[sockno], (struct sockaddr *) &client, &size); if (new < 0) { -@@ -324,13 +328,34 @@ script_fu_server_listen (gint timeout) +@@ -324,13 +342,34 @@ script_fu_server_listen (gint timeout) } /* Associate the client address with the socket */ @@ -76,6 +136,9 @@ index db1de13..8fb8a10 100644 + (void) getnameinfo ((struct sockaddr *) &client, size, clientname, + sizeof (clientname), NULL, 0, NI_NUMERICHOST); + ++ g_hash_table_insert (clients, GINT_TO_POINTER (new), ++ g_strdup (clientname)); ++ + /* Determine port number */ + switch (client.ss_family) + { @@ -90,9 +153,6 @@ index db1de13..8fb8a10 100644 + default: + portno = 0; + } -+ -+ g_hash_table_insert (clients, GINT_TO_POINTER (new), -+ g_strdup (clientname)); server_log ("Server: connect from host %s, port %d.\n", - inet_ntoa (clientname.sin_addr), @@ -101,3 +161,228 @@ index db1de13..8fb8a10 100644 } /* Service the client sockets. */ +@@ -392,18 +431,46 @@ static void + server_start (gint port, + const gchar *logfile) + { +- const gchar *progress; ++ struct addrinfo *ai, ++ *ai_curr; ++ struct addrinfo hints; ++ gint e, ++ sockno; ++ gchar *port_s; + +- /* First of all, create the socket and set it up to accept connections. */ +- /* This may fail if there's a server running on this port already. */ +- server_sock = make_socket (port); ++ const gchar *progress; + +- if (listen (server_sock, 5) < 0) ++ memset (&hints, 0, sizeof (hints)); ++ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; ++ hints.ai_socktype = SOCK_STREAM; ++ ++ port_s = g_strdup_printf ("%d", port); ++ e = getaddrinfo (NULL, port_s, &hints, &ai); ++ g_free (port_s); ++ ++ if (e != 0) + { +- print_socket_api_error ("listen"); ++ g_printerr ("getaddrinfo: %s", gai_strerror (e)); + return; + } + ++ for (ai_curr = ai, sockno = 0; ++ ai_curr != NULL && sockno < server_socks_len; ++ ai_curr = ai_curr->ai_next, sockno++) ++ { ++ /* Create the socket and set it up to accept connections. */ ++ /* This may fail if there's a server running on this port already. */ ++ server_socks[sockno] = make_socket (ai_curr); ++ ++ if (listen (server_socks[sockno], 5) < 0) ++ { ++ print_socket_api_error ("listen"); ++ return; ++ } ++ } ++ ++ server_socks_used = sockno; ++ + /* Setup up the server log file */ + if (logfile && *logfile) + server_log_file = g_fopen (logfile, "a"); +@@ -592,11 +659,10 @@ read_from_client (gint filedes) + } + + static gint +-make_socket (guint port) ++make_socket (const struct addrinfo *ai) + { +- struct sockaddr_in name; +- gint sock; +- gint v = 1; ++ gint sock; ++ gint v = 1; + + /* Win32 needs the winsock library initialized. */ + #ifdef G_OS_WIN32 +@@ -620,7 +686,7 @@ make_socket (guint port) + #endif + + /* Create the socket. */ +- sock = socket (PF_INET, SOCK_STREAM, 0); ++ sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) + { + print_socket_api_error ("socket"); +@@ -629,12 +695,20 @@ make_socket (guint port) + + setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)); + +- /* Give the socket a name. */ +- name.sin_family = AF_INET; +- name.sin_port = htons (port); +- name.sin_addr.s_addr = htonl (INADDR_ANY); ++#ifdef IPV6_V6ONLY ++ /* Only listen on IPv6 addresses, otherwise bind() will fail. */ ++ if (ai->ai_family == AF_INET6) ++ { ++ v = 1; ++ if (setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v)) < 0) ++ { ++ print_socket_api_error ("setsockopt"); ++ gimp_quit(); ++ } ++ } ++#endif + +- if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) ++ if (bind (sock, ai->ai_addr, ai->ai_addrlen) < 0) + { + print_socket_api_error ("bind"); + gimp_quit (); +@@ -672,7 +746,12 @@ script_fu_server_shutdown_fd (gpointer key, + static void + server_quit (void) + { +- CLOSESOCKET (server_sock); ++ gint sockno; ++ ++ for (sockno = 0; sockno < server_socks_used; sockno++) ++ { ++ CLOSESOCKET (server_socks[sockno]); ++ } + + if (clients) + { +diff --git a/plug-ins/script-fu/servertest.py b/plug-ins/script-fu/servertest.py +index b636557..5fb673a 100644 +--- a/plug-ins/script-fu/servertest.py ++++ b/plug-ins/script-fu/servertest.py +@@ -2,38 +2,66 @@ + + import readline, socket, sys + +-if len (sys.argv) == 1: +- HOST = 'localhost' +- PORT = 10008 +-elif len (sys.argv) == 3: +- HOST = sys.argv[1] +- PORT = int (sys.argv[2]) +-else: +- print >> sys.stderr, "Usage: %s " % sys.argv[0] +- print >> sys.stderr, " (if omitted connect to localhost, port 10008)" +- sys.exit () ++if len(sys.argv) < 1 or len(sys.argv) > 3: ++ print >>sys.stderr, "Usage: %s " % sys.argv[0] ++ print >>sys.stderr, " (if omitted connect to localhost, port 10008)" ++ sys.exit(1) + ++HOST = "localhost" ++PORT = 10008 + +-sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) +-sock.connect ((HOST, PORT)) ++try: ++ HOST = sys.argv[1] ++ try: ++ PORT = int(sys.argv[2]) ++ except IndexError: ++ pass ++except IndexError: ++ pass ++ ++addresses = socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM) ++ ++connected = False ++ ++for addr in addresses: ++ (family, socktype, proto, canonname, sockaddr) = addr ++ ++ numeric_addr = sockaddr[0] ++ ++ if canonname: ++ print "Trying %s ('%s')." % (numeric_addr, canonname) ++ else: ++ print "Trying %s." % numeric_addr ++ ++ try: ++ sock = socket.socket(family, socket.SOCK_STREAM) ++ sock.connect((HOST, PORT)) ++ connected = True ++ break ++ except: ++ pass ++ ++if not connected: ++ print "Failed." ++ sys.exit(1) + + try: +- cmd = raw_input ("Script-Fu-Remote - Testclient\n> ") ++ cmd = raw_input("Script-Fu-Remote - Testclient\n> ") + +- while len (cmd) > 0: +- sock.send ('G%c%c%s' % (len (cmd) / 256, len (cmd) % 256, cmd)) ++ while len(cmd) > 0: ++ sock.send('G%c%c%s' % (len(cmd) / 256, len(cmd) % 256, cmd)) + + data = "" +- while len (data) < 4: +- data += sock.recv (4 - len (data)) ++ while len(data) < 4: ++ data += sock.recv(4 - len(data)) + +- if len (data) >= 4: ++ if len(data) >= 4: + if data[0] == 'G': +- l = ord (data[2]) * 256 + ord (data[3]) ++ l = ord(data[2]) * 256 + ord(data[3]) + msg = "" +- while len (msg) < l: +- msg += sock.recv (l - len (msg)) +- if ord (data[1]): ++ while len(msg) < l: ++ msg += sock.recv(l - len(msg)) ++ if ord(data[1]): + print "(ERR):", msg + else: + print " (OK):", msg +@@ -41,9 +69,9 @@ try: + print "invalid magic: %s\n" % data + else: + print "short response: %s\n" % data +- cmd = raw_input ("> ") ++ cmd = raw_input("> ") + + except EOFError: + print + +-sock.close ++sock.close() +-- +1.7.0.1 + diff --git a/gimp.spec b/gimp.spec index 6393779..354ff23 100644 --- a/gimp.spec +++ b/gimp.spec @@ -31,7 +31,7 @@ Summary: GNU Image Manipulation Program Name: gimp Epoch: 2 Version: 2.6.9 -Release: 3%{?dist} +Release: 4%{?dist} %define binver 2.6 %define gimp_lang_ver 20 %define interfacever 2.0 @@ -481,6 +481,9 @@ fi %{_libdir}/gimp/%{interfacever}/plug-ins/help-browser %changelog +* Tue Jun 29 2010 Nils Philippsen - 2:2.6.9-4 +- script-fu: make rest of server IPv6-aware (#198367) + * Mon Jun 28 2010 Nils Philippsen - 2:2.6.9-3 - script-fu: make logging IPv6-aware (#198367)