script-fu: make rest of server IPv6-aware (#198367)
This commit is contained in:
parent
15e586a226
commit
e345da65f0
@ -1,18 +1,24 @@
|
|||||||
commit 859c381a9764d9d91e1ed8539a5919afbbbf2dbc
|
From 1979c0b0e66db34e69863c89e4eb544c89e9d41a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nils Philippsen <nils@redhat.com>
|
||||||
|
Date: Tue, 29 Jun 2010 16:06:45 +0200
|
||||||
|
Subject: [PATCH] patch: script-fu-ipv6
|
||||||
|
|
||||||
|
Squashed commit of the following:
|
||||||
|
|
||||||
|
commit e0ae4b85c33d4241e95594b0d9788dafb27132c6
|
||||||
Author: Nils Philippsen <nils@redhat.com>
|
Author: Nils Philippsen <nils@redhat.com>
|
||||||
Date: Mon Jun 28 16:36:44 2010 +0200
|
Date: Tue Jun 29 16:03:31 2010 +0200
|
||||||
|
|
||||||
patch: script-fu-ipv6
|
Bug 623045 - script-fu: make server IPv6 aware
|
||||||
|
|
||||||
Squashed commit of the following:
|
use getnameinfo() instead of inet_ntoa()
|
||||||
|
use two sockets for IPv4, IPv6
|
||||||
commit e567516ade8ebf74598542f8b319f80eee873c65
|
(manually cherry picked from commit 04538534fc581de0507ef2ec1148853ff1e96dbe)
|
||||||
Author: Nils Philippsen <nils@redhat.com>
|
---
|
||||||
Date: Mon Jun 28 16:07:01 2010 +0200
|
configure.in | 8 +-
|
||||||
|
plug-ins/script-fu/script-fu-server.c | 141 +++++++++++++++++++++++++-------
|
||||||
Bug 623045 - script-fu: make logging IPv6-aware
|
plug-ins/script-fu/servertest.py | 76 ++++++++++++------
|
||||||
|
3 files changed, 166 insertions(+), 59 deletions(-)
|
||||||
use getnameinfo() instead of inet_ntoa()
|
|
||||||
|
|
||||||
diff --git a/configure.in b/configure.in
|
diff --git a/configure.in b/configure.in
|
||||||
index 71f031d..a99cbe4 100644
|
index 71f031d..a99cbe4 100644
|
||||||
@ -38,12 +44,59 @@ index 71f031d..a99cbe4 100644
|
|||||||
|
|
||||||
SOCKET_LIBS="$LIBS"
|
SOCKET_LIBS="$LIBS"
|
||||||
diff --git a/plug-ins/script-fu/script-fu-server.c b/plug-ins/script-fu/script-fu-server.c
|
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
|
--- a/plug-ins/script-fu/script-fu-server.c
|
||||||
+++ b/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)
|
@@ -137,7 +137,8 @@ static void server_start (gint port,
|
||||||
/* Service the server socket if it has input pending. */
|
const gchar *logfile);
|
||||||
if (FD_ISSET (server_sock, &fds))
|
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_in clientname;
|
||||||
+ struct sockaddr_storage client;
|
+ struct sockaddr_storage client;
|
||||||
@ -53,15 +106,22 @@ index db1de13..8fb8a10 100644
|
|||||||
|
|
||||||
/* Connection request on original socket. */
|
/* Connection request on original socket. */
|
||||||
- guint size = sizeof (clientname);
|
- guint size = sizeof (clientname);
|
||||||
+ guint size = sizeof (client);
|
- gint new = accept (server_sock,
|
||||||
gint new = accept (server_sock,
|
|
||||||
- (struct sockaddr *) &clientname, &size);
|
- (struct sockaddr *) &clientname, &size);
|
||||||
+ (struct sockaddr *) &client, &size);
|
+ guint size = sizeof (client);
|
||||||
+ guint portno;
|
+ gint new;
|
||||||
|
+ guint portno;
|
||||||
|
+
|
||||||
|
+ if (! FD_ISSET (server_socks[sockno], &fds))
|
||||||
|
+ {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ new = accept (server_socks[sockno], (struct sockaddr *) &client, &size);
|
||||||
|
|
||||||
if (new < 0)
|
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 */
|
/* Associate the client address with the socket */
|
||||||
@ -76,6 +136,9 @@ index db1de13..8fb8a10 100644
|
|||||||
+ (void) getnameinfo ((struct sockaddr *) &client, size, clientname,
|
+ (void) getnameinfo ((struct sockaddr *) &client, size, clientname,
|
||||||
+ sizeof (clientname), NULL, 0, NI_NUMERICHOST);
|
+ sizeof (clientname), NULL, 0, NI_NUMERICHOST);
|
||||||
+
|
+
|
||||||
|
+ g_hash_table_insert (clients, GINT_TO_POINTER (new),
|
||||||
|
+ g_strdup (clientname));
|
||||||
|
+
|
||||||
+ /* Determine port number */
|
+ /* Determine port number */
|
||||||
+ switch (client.ss_family)
|
+ switch (client.ss_family)
|
||||||
+ {
|
+ {
|
||||||
@ -90,9 +153,6 @@ index db1de13..8fb8a10 100644
|
|||||||
+ default:
|
+ default:
|
||||||
+ portno = 0;
|
+ portno = 0;
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
+ g_hash_table_insert (clients, GINT_TO_POINTER (new),
|
|
||||||
+ g_strdup (clientname));
|
|
||||||
|
|
||||||
server_log ("Server: connect from host %s, port %d.\n",
|
server_log ("Server: connect from host %s, port %d.\n",
|
||||||
- inet_ntoa (clientname.sin_addr),
|
- inet_ntoa (clientname.sin_addr),
|
||||||
@ -101,3 +161,228 @@ index db1de13..8fb8a10 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Service the client sockets. */
|
/* 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 <host> <port>" % 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 <host> <port>" % 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
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ Summary: GNU Image Manipulation Program
|
|||||||
Name: gimp
|
Name: gimp
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
Version: 2.6.9
|
Version: 2.6.9
|
||||||
Release: 3%{?dist}
|
Release: 4%{?dist}
|
||||||
%define binver 2.6
|
%define binver 2.6
|
||||||
%define gimp_lang_ver 20
|
%define gimp_lang_ver 20
|
||||||
%define interfacever 2.0
|
%define interfacever 2.0
|
||||||
@ -481,6 +481,9 @@ fi
|
|||||||
%{_libdir}/gimp/%{interfacever}/plug-ins/help-browser
|
%{_libdir}/gimp/%{interfacever}/plug-ins/help-browser
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 29 2010 Nils Philippsen <nils@redhat.com> - 2:2.6.9-4
|
||||||
|
- script-fu: make rest of server IPv6-aware (#198367)
|
||||||
|
|
||||||
* Mon Jun 28 2010 Nils Philippsen <nils@redhat.com> - 2:2.6.9-3
|
* Mon Jun 28 2010 Nils Philippsen <nils@redhat.com> - 2:2.6.9-3
|
||||||
- script-fu: make logging IPv6-aware (#198367)
|
- script-fu: make logging IPv6-aware (#198367)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user