SOURCES: mc-ipv6.patch (NEW) - from fedora
arekm
arekm at pld-linux.org
Mon Sep 10 19:33:28 CEST 2007
Author: arekm Date: Mon Sep 10 17:33:28 2007 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- from fedora
---- Files affected:
SOURCES:
mc-ipv6.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/mc-ipv6.patch
diff -u /dev/null SOURCES/mc-ipv6.patch:1.1
--- /dev/null Mon Sep 10 19:33:28 2007
+++ SOURCES/mc-ipv6.patch Mon Sep 10 19:33:23 2007
@@ -0,0 +1,413 @@
+--- mc-2006-09-12-21/vfs/ftpfs.c.ipv6 2006-03-08 16:17:55.000000000 +0100
++++ mc-2006-09-12-21/vfs/ftpfs.c 2006-09-26 10:43:27.000000000 +0200
+@@ -639,12 +639,13 @@ ftpfs_get_proxy_host_and_port (const cha
+ static int
+ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
+ {
+- struct sockaddr_in server_address;
+- struct hostent *hp;
+- int my_socket;
++ struct addrinfo hints, *res, *restmp;
++ int my_socket = 0;
+ char *host;
+- int port = SUP.port;
++ char *port;
++ int tmp_port;
+ int free_host = 0;
++ int e;
+
+ (void) me;
+
+@@ -657,62 +658,83 @@ ftpfs_open_socket (struct vfs_class *me,
+ return -1;
+ }
+
++ port = malloc (sizeof (char) * 6);
++ if (port == NULL) {
++ ftpfs_errno = errno;
++ return -1;
++ }
++
+ /* Hosts to connect to that start with a ! should use proxy */
++ tmp_port = SUP.port;
++
+ if (SUP.proxy){
+- ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &port);
++ ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &tmp_port);
+ free_host = 1;
+ }
+
+- enable_interrupt_key(); /* clear the interrupt flag */
+-
+- /* Get host address */
+- memset ((char *) &server_address, 0, sizeof (server_address));
+- server_address.sin_family = AF_INET;
+- server_address.sin_addr.s_addr = inet_addr (host);
+- if (server_address.sin_addr.s_addr == INADDR_NONE) {
+- hp = gethostbyname (host);
+- if (hp == NULL){
+- disable_interrupt_key();
+- print_vfs_message (_("ftpfs: Invalid host address."));
+- ftpfs_errno = EINVAL;
+- if (free_host)
+- g_free (host);
+- return -1;
+- }
+- server_address.sin_family = hp->h_addrtype;
+-
+- /* We copy only 4 bytes, we cannot trust hp->h_length, as it comes from the DNS */
+- memcpy ((char *) &server_address.sin_addr, (char *) hp->h_addr, 4);
++ if (snprintf (port, 6, "%hu", (unsigned short)tmp_port) < 0) {
++ g_free (port);
++ if (free_host)
++ g_free (host);
++ ftpfs_errno = errno;
++ return -1;
+ }
+
+- server_address.sin_port = htons (port);
++ enable_interrupt_key(); /* clear the interrupt flag */
+
+- /* Connect */
+- if ((my_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+- disable_interrupt_key();
+- ftpfs_errno = errno;
+- if (free_host)
+- g_free (host);
+- return -1;
+- }
+-
+- print_vfs_message (_("ftpfs: making connection to %s"), host);
+- if (free_host)
++ memset (&hints, 0, sizeof (struct addrinfo));
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_flags = AI_ADDRCONFIG;
++
++ if ((e = getaddrinfo (host, port, &hints, &res)) != 0) {
++ disable_interrupt_key();
++ print_vfs_message (_("ftpfs: %s"), gai_strerror (e));
++ if (free_host)
+ g_free (host);
+-
+- if (connect (my_socket, (struct sockaddr *) &server_address,
+- sizeof (server_address)) < 0){
+- ftpfs_errno = errno;
+- if (errno == EINTR && got_interrupt ())
++ g_free (port);
++ ftpfs_errno = EINVAL;
++ return -1;
++ }
++ g_free (port);
++
++ for (restmp = res; res != NULL; res = res->ai_next) {
++ my_socket = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
++ if (my_socket < 0) {
++ if (res->ai_next == NULL) {
++ disable_interrupt_key();
++ print_vfs_message (_("ftpfs: %s"), unix_error_string (errno));
++ if (free_host)
++ g_free (host);
++ freeaddrinfo (restmp);
++ ftpfs_errno = errno;
++ return -1;
++ } else
++ continue;
++ } else {
++ print_vfs_message (_("ftpfs: making connection to %s"), host);
++ if (free_host)
++ g_free (host);
++
++ if (connect (my_socket, res->ai_addr, res->ai_addrlen) < 0) {
++ ftpfs_errno = errno;
++ close (my_socket);
++ if (errno == EINTR && got_interrupt ()) {
+ print_vfs_message (_("ftpfs: connection interrupted by user"));
+- else
++ } else if (res->ai_next == NULL) {
+ print_vfs_message (_("ftpfs: connection to server failed: %s"),
+- unix_error_string(errno));
+- disable_interrupt_key();
+- close (my_socket);
+- return -1;
++ unix_error_string (errno));
++ } else
++ continue;
++ freeaddrinfo (restmp);
++ disable_interrupt_key ();
++ return -1;
++ } else
++ break;
++ }
+ }
+- disable_interrupt_key();
++
++ freeaddrinfo (restmp);
++ disable_interrupt_key ();
+ return my_socket;
+ }
+
+@@ -861,93 +883,179 @@ ftpfs_get_current_directory (struct vfs_
+
+ /* Setup Passive ftp connection, we use it for source routed connections */
+ static int
+-ftpfs_setup_passive (struct vfs_class *me, struct vfs_s_super *super, int my_socket, struct sockaddr_in *sa)
++ftpfs_setup_passive (struct vfs_class *me, struct vfs_s_super *super, int my_socket, struct sockaddr_storage *sa, socklen_t *salen)
+ {
++ char *c;
++
++ if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "EPSV") == COMPLETE) {
++ int port;
++ /* (|||<port>|) */
++ c = strchr (reply_str, '|');
++ if (c == NULL)
++ return 0;
++ if(strlen(c) > 3)
++ c+=3;
++ else
++ return 0;
++
++ port = atoi (c);
++ if (port < 0 || port > 65535)
++ return 0;
++ port = htons (port);
++
++ switch (sa->ss_family) {
++ case AF_INET:
++ ((struct sockaddr_in *)sa)->sin_port = port;
++ break;
++ case AF_INET6:
++ ((struct sockaddr_in6 *)sa)->sin6_port = port;
++ break;
++ default:
++ print_vfs_message (_("ftpfs: invalid address family"));
++ ERRNOR (EINVAL, -1);
++ }
++ } else if (sa->ss_family == AF_INET) {
+ int xa, xb, xc, xd, xe, xf;
+ char n [6];
+- char *c;
+
+ if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "PASV") != COMPLETE)
+- return 0;
+-
++ return 0;
++
+ /* Parse remote parameters */
+ for (c = reply_str + 4; (*c) && (!isdigit ((unsigned char) *c)); c++)
+- ;
++ ;
+ if (!*c)
+- return 0;
++ return 0;
+ if (!isdigit ((unsigned char) *c))
+- return 0;
++ return 0;
+ if (sscanf (c, "%d,%d,%d,%d,%d,%d", &xa, &xb, &xc, &xd, &xe, &xf) != 6)
+- return 0;
++ return 0;
+ n [0] = (unsigned char) xa;
+ n [1] = (unsigned char) xb;
+ n [2] = (unsigned char) xc;
+ n [3] = (unsigned char) xd;
+ n [4] = (unsigned char) xe;
+ n [5] = (unsigned char) xf;
++
++ memcpy (&(((struct sockaddr_in *)sa)->sin_addr.s_addr), (void *)n, 4);
++ memcpy (&(((struct sockaddr_in *)sa)->sin_port), (void *)&n[4], 2);
++ } else
++ return 0;
+
+- memcpy (&(sa->sin_addr.s_addr), (void *)n, 4);
+- memcpy (&(sa->sin_port), (void *)&n[4], 2);
+- if (connect (my_socket, (struct sockaddr *) sa, sizeof (struct sockaddr_in)) < 0)
+- return 0;
+- return 1;
++ if (connect (my_socket, (struct sockaddr *) sa, *salen ) < 0)
++ return 0;
++
++ return 1;
+ }
+
+ static int
+ ftpfs_initconn (struct vfs_class *me, struct vfs_s_super *super)
+ {
+- struct sockaddr_in data_addr;
+- int data;
+- socklen_t len = sizeof(data_addr);
+- struct protoent *pe;
++ struct sockaddr_storage data_addr;
++ socklen_t data_addrlen;
++ int data_sock;
+
+- pe = getprotobyname ("tcp");
+- if (pe == NULL)
+- ERRNOR (EIO, -1);
+ again:
+- if (getsockname (SUP.sock, (struct sockaddr *) &data_addr, &len) == -1)
+- ERRNOR (EIO, -1);
+- data_addr.sin_port = 0;
+-
+- data = socket (AF_INET, SOCK_STREAM, pe->p_proto);
+- if (data < 0)
+- ERRNOR (EIO, -1);
++ memset (&data_addr, 0, sizeof (struct sockaddr_storage));
++ data_addrlen = sizeof (struct sockaddr_storage);
+
+- if (SUP.use_passive_connection) {
+- if (ftpfs_setup_passive (me, super, data, &data_addr))
+- return data;
+-
+- SUP.use_passive_connection = 0;
+- print_vfs_message (_("ftpfs: could not setup passive mode"));
++ if (getpeername (SUP.sock, (struct sockaddr *) &data_addr, &data_addrlen) == -1)
++ return -1;
++
++ switch (data_addr.ss_family) {
++ case AF_INET:
++ ((struct sockaddr_in *)&data_addr)->sin_port = 0;
++ break;
++ case AF_INET6:
++ ((struct sockaddr_in6 *)&data_addr)->sin6_port = 0;
++ break;
++ default:
++ print_vfs_message (_("ftpfs: invalid address family"));
++ ERRNOR(EINVAL, -1);
++ }
+
+- /* data or data_addr may be damaged by ftpfs_setup_passive */
+- close (data);
+- goto again;
++ data_sock = socket (data_addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
++ if (data_sock < 0) {
++ if (SUP.use_passive_connection) {
++ print_vfs_message (_("ftpfs: could not setup passive mode: %s"), unix_error_string (errno));
++ SUP.use_passive_connection = 0;
++ goto again;
+ }
++ print_vfs_message (_("ftpfs: could not create socket: %s"), unix_error_string (errno));
++ return -1;
++ }
+
++ if (SUP.use_passive_connection) {
++ if (ftpfs_setup_passive (me, super, data_sock, &data_addr, &data_addrlen))
++ return data_sock;
++
++ SUP.use_passive_connection = 0;
++ print_vfs_message (_("ftpfs: could not setup passive mode"));
++
++ close (data_sock);
++ goto again;
++ }
++
+ /* If passive setup fails, fallback to active connections */
+ /* Active FTP connection */
+- if ((bind (data, (struct sockaddr *)&data_addr, len) == 0) &&
+- (getsockname (data, (struct sockaddr *) &data_addr, &len) == 0) &&
+- (listen (data, 1) == 0))
++ if ((bind (data_sock, (struct sockaddr *)&data_addr, data_addrlen) == 0) &&
++ (getsockname (data_sock, (struct sockaddr *)&data_addr, &data_addrlen) == 0) &&
++ (listen (data_sock, 1) == 0))
+ {
+- unsigned char *a = (unsigned char *)&data_addr.sin_addr;
+- unsigned char *p = (unsigned char *)&data_addr.sin_port;
++ unsigned short int port;
++ char *addr;
++ unsigned int af;
++
++ switch (data_addr.ss_family) {
++ case AF_INET:
++ af = FTP_INET;
++ port = ((struct sockaddr_in *)&data_addr)->sin_port;
++ break;
++ case AF_INET6:
++ af = FTP_INET6;
++ port = ((struct sockaddr_in6 *)&data_addr)->sin6_port;
++ break;
++ default:
++ print_vfs_message (_("ftpfs: invalid address family"));
++ ERRNOR (EINVAL, -1);
++ }
++ port = ntohs (port);
++
++ addr = malloc (NI_MAXHOST);
++ if (addr == NULL)
++ ERRNOR (ENOMEM, -1);
++
++ if (getnameinfo ((struct sockaddr *)&data_addr, data_addrlen, addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) {
++ g_free (addr);
++ ERRNOR (EIO, -1);
++ }
++
++ if (ftpfs_command (me, super, WAIT_REPLY, "EPRT |%u|%s|%hu|", af, addr, port) == COMPLETE) {
++ g_free (addr);
++ return data_sock;
++ }
++ g_free (addr);
++
++ if (FTP_INET == af) {
++ unsigned char *a = (unsigned char *)&((struct sockaddr_in *)&data_addr)->sin_addr;
++ unsigned char *p = (unsigned char *)&port;
+
+- if (ftpfs_command (me, super, WAIT_REPLY, "PORT %d,%d,%d,%d,%d,%d", a[0], a[1],
+- a[2], a[3], p[0], p[1]) == COMPLETE)
+- return data;
++ if (ftpfs_command (me, super, WAIT_REPLY, "PORT %u,%u,%u,%u,%u,%u", a[0], a[1], a[2], a[3],
++ p[0], p[1]) == COMPLETE)
++ return data_sock;
++ }
+ }
+- close (data);
+- ftpfs_errno = EIO;
+- return -1;
++
++ close (data_sock);
++ ftpfs_errno = EIO;
++ return -1;
+ }
+
+ static int
+ ftpfs_open_data_connection (struct vfs_class *me, struct vfs_s_super *super, const char *cmd,
+ const char *remote, int isbinary, int reget)
+ {
+- struct sockaddr_in from;
++ struct sockaddr_storage from;
+ int s, j, data;
+ socklen_t fromlen = sizeof(from);
+
+--- mc-2006-09-12-21/vfs/ftpfs.h.ipv6 2005-05-29 14:10:08.000000000 +0200
++++ mc-2006-09-12-21/vfs/ftpfs.h 2006-09-26 10:42:36.000000000 +0200
+@@ -15,6 +15,9 @@ extern int ftpfs_first_cd_then_ls;
+ void ftpfs_init_passwd (void);
+ void init_ftpfs (void);
+
++#define FTP_INET 1
++#define FTP_INET6 2
++
+ #define OPT_FLUSH 1
+ #define OPT_IGNORE_ERROR 2
+
+--- mc-2006-08-12-18/vfs/utilvfs.c.ipv6 2006-01-30 18:01:58.000000000 +0100
++++ mc-2006-08-12-18/vfs/utilvfs.c 2010-12-14 20:41:09.000000000 +0100
+@@ -109,7 +109,21 @@ vfs_split_url (const char *path, char **
+ }
+
+ /* Check if the host comes with a port spec, if so, chop it */
+- colon = strchr (rest, ':');
++ if ('[' == *rest) {
++ colon = strchr (++rest, ']');
++ if (colon) {
++ colon[0] = '\0';
++ colon[1] = '\0';
++ colon++;
++ } else {
++ g_free (pcopy);
++ *host = NULL;
++ *port = 0;
++ return NULL;
++ }
++ } else
++ colon = strchr (rest, ':');
++
+ if (colon) {
+ *colon = 0;
+ if (sscanf (colon + 1, "%d", port) == 1) {
================================================================
More information about the pld-cvs-commit
mailing list