Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 220543 Details for
Bug 157005
net-ftp/oftpd-0.3.7: Fix for ipv6 support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
oftpd-0.3.7-ipv6rel2-1.patch
oftpd-0.3.7-ipv6rel2-1.patch (text/plain), 43.72 KB, created by
Mario Fetka (geos_one)
on 2010-02-20 22:21:29 UTC
(
hide
)
Description:
oftpd-0.3.7-ipv6rel2-1.patch
Filename:
MIME Type:
Creator:
Mario Fetka (geos_one)
Created:
2010-02-20 22:21:29 UTC
Size:
43.72 KB
patch
obsolete
>Submitted By: Mario Fetka (geos_one) (mario dot fetka at gmail dot com) >Date: 2010-01-05 >Initial Package Version: 0.3.6 >Origin: ftp://ftp.deepspace6.net/pub/ds6/sources/oftpd/oftpd-0.3.6-ipv6rel2.patch.gz >Upstream Status: unknown >Description: add better ipv6 support to oftpd > >diff -Naur oftpd-0.3.7.orig/src/Makefile.am oftpd-0.3.7/src/Makefile.am >--- oftpd-0.3.7.orig/src/Makefile.am 2001-04-17 23:05:16.000000000 +0000 >+++ oftpd-0.3.7/src/Makefile.am 2010-01-05 21:50:11.109303546 +0000 >@@ -1,2 +1,2 @@ > bin_PROGRAMS = oftpd >-oftpd_SOURCES = file_list.c file_list.h ftp_command.c ftp_command.h ftp_listener.c ftp_listener.h ftp_session.c ftp_session.h oftpd.c oftpd.h telnet_session.c telnet_session.h watchdog.c watchdog.h error.c error.h af_portability.h daemon_assert.c daemon_assert.h >+oftpd_SOURCES = file_list.c file_list.h ftp_command.c ftp_command.h ftp_listener.c ftp_listener.h ftp_session.c ftp_session.h oftpd.c oftpd.h telnet_session.c telnet_session.h watchdog.c watchdog.h error.c error.h af_portability.h af_portability.c daemon_assert.c daemon_assert.h >diff -Naur oftpd-0.3.7.orig/src/af_portability.c oftpd-0.3.7/src/af_portability.c >--- oftpd-0.3.7.orig/src/af_portability.c 1970-01-01 00:00:00.000000000 +0000 >+++ oftpd-0.3.7/src/af_portability.c 2010-01-05 21:50:11.109303546 +0000 >@@ -0,0 +1,32 @@ >+#include <stdlib.h> >+#include <netdb.h> >+#include <netinet/in.h> >+ >+unsigned short int sockaddr_port(const struct sockaddr *sa, socklen_t salen) >+{ >+#ifdef INET6 >+ char sbuf[NI_MAXSERV]; >+#endif >+ unsigned short int port = 0; >+ >+#ifdef INET6 >+ if (getnameinfo(sa, salen, NULL, 0, sbuf, sizeof(sbuf), >+ NI_NUMERICSERV) == 0) >+ port = atoi(sbuf); >+ else >+#endif >+ switch (sa->sa_family) { >+ case AF_INET: >+ port = ntohs(((struct sockaddr_in *)sa)->sin_port); >+ break; >+#ifdef INET6 >+ case AF_INET6: >+ port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port); >+ break; >+#endif >+ default: >+ /* everything went wrong :-P */ >+ exit(1); >+ } >+ return port; >+} >diff -Naur oftpd-0.3.7.orig/src/af_portability.h oftpd-0.3.7/src/af_portability.h >--- oftpd-0.3.7.orig/src/af_portability.h 2001-03-28 22:31:01.000000000 +0000 >+++ oftpd-0.3.7/src/af_portability.h 2010-01-05 21:50:11.109303546 +0000 >@@ -2,10 +2,9 @@ > #define AF_PORTABILITY_H > > #include <netinet/in.h> >-#include <sys/socket.h> > > /* _x_ must be a pointer to a sockaddr structure */ >- >+/* > #define SAFAM(_x_) (((struct sockaddr *)(_x_))->sa_family) > > #ifdef HAVE_NEW_SS_FAMILY >@@ -26,6 +25,7 @@ > #define SINADDR(_x_) SIN4ADDR(_x_) > #define SINPORT(_x_) SIN4PORT(_x_) > #endif >+*/ > > #ifndef INET_ADDRSTRLEN > #define INET_ADDRSTRLEN 16 >@@ -43,10 +43,13 @@ > #define IP_ADDRSTRLEN INET_ADDRSTRLEN > #endif > >+unsigned short int sockaddr_port(const struct sockaddr *sa, socklen_t salen); >+/* > #ifdef INET6 > typedef struct sockaddr_storage sockaddr_storage_t; > #else > typedef struct sockaddr_in sockaddr_storage_t; > #endif >+*/ > > #endif /* AF_PORTABILITY_H */ >diff -Naur oftpd-0.3.7.orig/src/config.h.in oftpd-0.3.7/src/config.h.in >--- oftpd-0.3.7.orig/src/config.h.in 2002-02-04 22:45:58.000000000 +0000 >+++ oftpd-0.3.7/src/config.h.in 2010-01-05 21:50:11.110304366 +0000 >@@ -97,15 +97,15 @@ > /* Define if you have the <limits.h> header file. */ > #undef HAVE_LIMITS_H > >+/* Define if you have the <syslog.h> header file. */ >+#undef HAVE_SYSLOG_H >+ > /* Define if you have the <sys/time.h> header file. */ > #undef HAVE_SYS_TIME_H > > /* Define if you have the <sys/types.h> header file. */ > #undef HAVE_SYS_TYPES_H > >-/* Define if you have the <syslog.h> header file. */ >-#undef HAVE_SYSLOG_H >- > /* Define if you have the <unistd.h> header file. */ > #undef HAVE_UNISTD_H > >diff -Naur oftpd-0.3.7.orig/src/error.c oftpd-0.3.7/src/error.c >--- oftpd-0.3.7.orig/src/error.c 2001-04-18 21:41:04.000000000 +0000 >+++ oftpd-0.3.7/src/error.c 2010-01-05 21:50:11.110304366 +0000 >@@ -23,6 +23,7 @@ > { > va_list args; > >+ fprintf(stderr, "error_init: %d %s", error_code, desc_fmt); > daemon_assert(err != NULL); > daemon_assert(error_code >= 0); > daemon_assert(desc_fmt != NULL); >diff -Naur oftpd-0.3.7.orig/src/ftp_command.c oftpd-0.3.7/src/ftp_command.c >--- oftpd-0.3.7.orig/src/ftp_command.c 2004-03-25 20:46:57.000000000 +0000 >+++ oftpd-0.3.7/src/ftp_command.c 2010-01-05 21:50:11.133303657 +0000 >@@ -12,7 +12,6 @@ > #include <arpa/inet.h> > #include <netdb.h> > #include "ftp_command.h" >-#include "af_portability.h" > #include "daemon_assert.h" > > /* argument types */ >@@ -67,8 +66,8 @@ > static const char *parse_host_port(struct sockaddr_in *addr, const char *s); > static const char *parse_number(int *num, const char *s, int max_num); > static const char *parse_offset(off_t *ofs, const char *s); >-static const char *parse_host_port_long(sockaddr_storage_t *sa, const char *s); >-static const char *parse_host_port_ext(sockaddr_storage_t *sa, const char *s); >+static const char *parse_host_port_long(struct sockaddr *sa, const char *s); >+static const char *parse_host_port_ext(struct sockaddr *sa, const char *s); > > int ftp_command_parse(const char *input, ftp_command_t *cmd) > { >@@ -137,7 +136,7 @@ > input++; > > /* parse the host & port information (if any) */ >- input = parse_host_port(&tmp.arg[0].host_port, input); >+ input = parse_host_port((struct sockaddr_in *)&tmp.arg[0].host_port, input); > if (input == NULL) { > return 0; > } >@@ -151,7 +150,7 @@ > input++; > > /* parse the host & port information (if any) */ >- input = parse_host_port_long(&tmp.arg[0].host_port, input); >+ input = parse_host_port_long((struct sockaddr *)&tmp.arg[0].host_port, input); > if (input == NULL) { > return 0; > } >@@ -165,7 +164,7 @@ > input++; > > /* parse the host & port information (if any) */ >- input = parse_host_port_ext(&tmp.arg[0].host_port, input); >+ input = parse_host_port_ext((struct sockaddr *)&tmp.arg[0].host_port, input); > if (input == NULL) { > return 0; > } >@@ -378,7 +377,7 @@ > > /* note: returns success even for unknown address families */ > /* this is okay, as long as subsequent uses VERIFY THE FAMILY first */ >-static const char *parse_host_port_long(sockaddr_storage_t *sa, const char *s) >+static const char *parse_host_port_long(struct sockaddr *sa, const char *s) > { > int i; > int family; >@@ -441,38 +440,38 @@ > > /* okay, everything parses, load the address if possible */ > if (family == 4) { >- SAFAM(sa) = AF_INET; >+ ((struct sockaddr_in *)sa)->sin_family = AF_INET; > if (addr_len != sizeof(struct in_addr)) { > return NULL; > } > if (port_len != 2) { > return NULL; >- } >- memcpy(&SINADDR(sa), addr, addr_len); >- SINPORT(sa) = htons((port[0] << 8) + port[1]); >+ } >+ memcpy(&((struct sockaddr_in *)sa)->sin_addr, addr, addr_len); >+ ((struct sockaddr_in *)sa)->sin_port = htons((port[0] << 8) + port[1]); > } > #ifdef INET6 > else if (family == 6) { >- SAFAM(sa) = AF_INET6; >+ ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6; > if (addr_len != sizeof(struct in6_addr)) { > return NULL; > } > if (port_len != 2) { > return NULL; > } >- memcpy(&SIN6ADDR(sa), addr, addr_len); >- SINPORT(sa) = htons((port[0] << 8) + port[1]); >+ memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, addr, addr_len); >+ ((struct sockaddr_in6 *)sa)->sin6_port = htons((port[0] << 8) + port[1]); > } > #endif > else { >- SAFAM(sa) = -1; >+ sa->sa_family = -1; > } > > /* return new pointer */ > return s; > } > >-static const char *parse_host_port_ext(sockaddr_storage_t *sa, const char *s) >+static const char *parse_host_port_ext(struct sockaddr *sa, const char *s) > { > int delimeter; > int family; >@@ -545,12 +544,11 @@ > } > #endif /* HAVE_INET_ATON */ > >- SIN4ADDR(sa) = in_addr; >+ ((struct sockaddr_in *)sa)->sin_addr = in_addr; > } > #else > { >- struct addrinfo hints; >- struct *res; >+ struct addrinfo hints, *res; > > memset(&hints, 0, sizeof(hints)); > hints.ai_flags = AI_NUMERICHOST; >@@ -566,8 +564,17 @@ > } > #endif /* INET6 */ > >- SAFAM(sa) = family; >- SINPORT(sa) = htons(port); >+ sa->sa_family = family; >+ if (family == AF_INET) { >+ ((struct sockaddr_in *)sa)->sin_port = htons(port); >+#ifdef INET6 >+ } else if (family == AF_INET6) { >+ ((struct sockaddr_in6 *)sa)->sin6_port = htons(port); >+#endif /* INET6 */ >+ } else { >+ /* we have an error! */ >+ return NULL; >+ } > > /* return new pointer */ > return s; >diff -Naur oftpd-0.3.7.orig/src/ftp_command.h oftpd-0.3.7/src/ftp_command.h >--- oftpd-0.3.7.orig/src/ftp_command.h 2001-03-20 23:56:00.000000000 +0000 >+++ oftpd-0.3.7/src/ftp_command.h 2010-01-05 21:50:11.141303856 +0000 >@@ -34,7 +34,6 @@ > #include <netinet/in.h> > #include <limits.h> > #include <sys/types.h> >-#include "af_portability.h" > > /* special macro for handling EPSV ALL requests */ > #define EPSV_ALL (-1) >@@ -50,7 +49,11 @@ > int num_arg; > union { > char string[MAX_STRING_LEN+1]; >- sockaddr_storage_t host_port; >+#ifdef INET6 >+ struct sockaddr_storage host_port; >+#else >+ struct sockaddr_in host_port; >+#endif > int num; > off_t offset; > } arg[MAX_ARG]; >diff -Naur oftpd-0.3.7.orig/src/ftp_listener.c oftpd-0.3.7/src/ftp_listener.c >--- oftpd-0.3.7.orig/src/ftp_listener.c 2001-05-10 23:29:46.000000000 +0000 >+++ oftpd-0.3.7/src/ftp_listener.c 2010-01-05 21:50:11.144303870 +0000 >@@ -52,7 +52,6 @@ > #include "af_portability.h" > > >- > /* maximum number of consecutive errors in accept() > before we terminate listener */ > #define MAX_ACCEPT_ERROR 10 >@@ -73,7 +72,7 @@ > /* prototypes */ > static int invariant(const ftp_listener_t *f); > static void *connection_acceptor(ftp_listener_t *f); >-static void addr_to_string(const sockaddr_storage_t *s, char *addr); >+static void addr_to_string(const struct sockaddr *s, char *addr); > static void *connection_handler(connection_info_t *info); > static void connection_handler_cleanup(connection_info_t *info); > >@@ -85,14 +84,22 @@ > int inactivity_timeout, > error_t *err) > { >- sockaddr_storage_t sock_addr; >+#ifdef INET6 >+ struct sockaddr_storage sock_addr; >+ int gai_err; >+ struct addrinfo hints; >+ struct addrinfo *res; >+ char buf[ADDR_BUF_LEN+1]; >+ int ret; >+#else >+ struct sockaddr_in sock_addr; >+ char *addr_str; >+#endif > int fd; > int flags; > int pipefds[2]; > int reuseaddr; > char dir[PATH_MAX+1]; >- char buf[ADDR_BUF_LEN+1]; >- const char *inet_ntop_ret; > > daemon_assert(f != NULL); > daemon_assert(port >= 0); >@@ -108,64 +115,67 @@ > } > > /* set up our socket address */ >- memset(&sock_addr, 0, sizeof(sockaddr_storage_t)); >+ memset(&sock_addr, 0, sizeof(sock_addr)); > >- if (address == NULL) { > #ifdef INET6 >- SAFAM(&sock_addr) = AF_INET6; >- memcpy(&SIN6ADDR(&sock_addr), &in6addr_any, sizeof(struct in6_addr)); >+ memset(&hints, 0, sizeof(hints)); >+ >+ /* with AF_UNSPEC we can handle even hostnames */ >+ hints.ai_family = (address == NULL ? AF_INET6 : AF_UNSPEC); >+ hints.ai_flags = AI_PASSIVE; >+ hints.ai_socktype = SOCK_STREAM; >+ >+ gai_err = getaddrinfo(address, "21", &hints, &res); >+ if (gai_err != 0) { >+ if (gai_err < 0) gai_err = -gai_err; >+ error_init(err, gai_err, "error parsing server socket address; %s", >+ gai_strerror(gai_err)); >+ return 0; >+ } >+ >+ memcpy(&sock_addr, res->ai_addr, res->ai_addrlen); >+ freeaddrinfo(res); > #else >- SAFAM(&sock_addr) = AF_INET; >+ if (address == NULL) { >+ sock_addr.sin_family = AF_INET; > sock_addr.sin_addr.s_addr = INADDR_ANY; >-#endif > } else { >- int gai_err; >- struct addrinfo hints; >- struct addrinfo *res; >- >- memset(&hints, 0, sizeof(hints)); >- >-/* - This code should be able to parse both IPv4 and IPv6 internet >- * addresses and put them in the sock_addr variable. >- * - Much neater now. >- * - Bug: Can't handle hostnames, only IP addresses. Not sure >- * exactly why. But then again, I'm not sure exactly why >- * there is a man page for getipnodebyname (which getaddrinfo >- * says it uses) but no corresponding function in libc. >- * -- Matthew Danish [3/20/2001] >- */ >+ struct hostent *hp; >+ >+ hp = gethostbyname(address); >+ if(hp == NULL) { >+ error_init(err, h_errno, "error with gethostbyname"); >+ return 0; >+ } >+ >+ assert(hp->h_length <= sizeof(sock_addr)); >+ memcpy(&sock_addr, hp->h_addr, hp->h_length); >+ } >+#endif > >+ /* setup non-default port */ >+ if (port != 0) { >+ sa_family_t family = ((struct sockaddr *)&sock_addr)->sa_family; >+ switch (family) { > #ifdef INET6 >- hints.ai_family = AF_INET6; >-#else >- hints.ai_family = AF_INET; >+ case AF_INET6: >+ ((struct sockaddr_in6*)&sock_addr)->sin6_port = port; >+ break; > #endif >- >- hints.ai_flags = AI_PASSIVE; >- >- gai_err = getaddrinfo(address, NULL, &hints, &res); >- if (gai_err != 0) { >- error_init(err, gai_err, "error parsing server socket address; %s", >- gai_strerror(gai_err)); >- return 0; >- } >- >- memcpy(&sock_addr, res->ai_addr, res->ai_addrlen); >- freeaddrinfo(res); >- } >- >- if (port == 0) { >- SINPORT(&sock_addr) = htons(DEFAULT_FTP_PORT); >- } else { >- SINPORT(&sock_addr) = htons(port); >+ case AF_INET: >+ ((struct sockaddr_in*)&sock_addr)->sin_port = port; >+ break; >+ default: >+ /* handle error */ >+ error_init(err, 1, "unknown adderess family"); >+ return 0; >+ } > } >- >- >- inet_ntop_ret = inet_ntop(SAFAM(&sock_addr), >- (void *)&SINADDR(&sock_addr), >- buf, >- sizeof(buf)); >- if (inet_ntop_ret == NULL) { >+ >+#ifdef INET6 >+ ret = getnameinfo((struct sockaddr *)(&sock_addr), sizeof(sock_addr), buf, sizeof(buf), >+ NULL, 0, NI_NUMERICHOST); >+ if (ret != 0) { > error_init(err, errno, "error converting server address to ASCII; %s", > strerror(errno)); > return 0; >@@ -173,11 +183,26 @@ > > /* Put some information in syslog */ > syslog(LOG_INFO, "Binding interface '%s', port %d, max clients %d\n", buf, >- ntohs(SINPORT(&sock_addr)), max_connections); >+ sockaddr_port((struct sockaddr *)&sock_addr, sizeof(sock_addr)), max_connections); >+#else >+ /* this should be thread-safe, as glibc texinfo documentation states: >+ * >+ * In multi-threaded programs each thread has an own >+ * statically-allocated buffer (for inet_ntoa). But still >+ * subsequent calls of `inet_ntoa' in the same thread will >+ * overwrite the result of the last call. >+ */ >+ addr_str = inet_ntoa(sock_addr.sin_addr); >+ >+ /* Put some information in syslog */ >+ syslog(LOG_INFO, "Binding interface '%s', port %d, max clients %d\n", >+ addr_str,sockaddr_port((struct sockaddr*)&sock_addr,sizeof(sock_addr)), >+ max_connections); >+#endif > > > /* okay, finally do some socket manipulation */ >- fd = socket(AF_INET, SOCK_STREAM, 0); >+ fd = socket(((struct sockaddr *)&sock_addr)->sa_family, SOCK_STREAM, 0); > if (fd == -1) { > error_init(err, errno, "error creating socket; %s", strerror(errno)); > return 0; >@@ -193,8 +218,7 @@ > return 0; > } > >- if (bind(fd, (struct sockaddr *)&sock_addr, >- sizeof(struct sockaddr_in)) != 0) >+ if (bind(fd, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) > { > close(fd); > error_init(err, errno, "error binding address; %s", strerror(errno)); >@@ -261,6 +285,8 @@ > daemon_assert(invariant(f)); > daemon_assert(err != NULL); > >+ syslog(LOG_WARNING, "in ftp_listener_start\n"); >+ > error_code = pthread_create(&thread_id, > NULL, > (void *(*)())connection_acceptor, >@@ -320,8 +346,13 @@ > > int fd; > int tcp_nodelay; >- sockaddr_storage_t client_addr; >- sockaddr_storage_t server_addr; >+#ifdef INET6 >+ struct sockaddr_storage client_addr; >+ struct sockaddr_storage server_addr; >+#else >+ struct sockaddr_in client_addr; >+ struct sockaddr_in server_addr; >+#endif > unsigned addr_len; > > connection_info_t *info; >@@ -332,6 +363,8 @@ > > daemon_assert(invariant(f)); > >+ syslog(LOG_WARNING, "in connection_acceptor\n"); >+ > if (!watchdog_init(&f->watchdog, f->inactivity_timeout, &err)) { > syslog(LOG_ERR, "Error initializing watchdog thread; %s", > error_get_desc(&err)); >@@ -355,10 +388,12 @@ > } > > /* otherwise accept our pending connection (if any) */ >- addr_len = sizeof(sockaddr_storage_t); >+ addr_len = sizeof(client_addr); > fd = accept(f->fd, (struct sockaddr *)&client_addr, &addr_len); > if (fd >= 0) { > >+ syslog(LOG_WARNING, "in connection_acceptor loop\n"); >+ > tcp_nodelay = 1; > if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcp_nodelay, > sizeof(int)) != 0) >@@ -370,7 +405,7 @@ > continue; > } > >- addr_len = sizeof(sockaddr_storage_t); >+ addr_len = sizeof(server_addr); > if (getsockname(fd, (struct sockaddr *)&server_addr, > &addr_len) == -1) > { >@@ -392,9 +427,11 @@ > > telnet_session_init(&info->telnet_session, fd, fd); > >+ syslog(LOG_WARNING, "about to call ftp_session_init\n"); >+ > if (!ftp_session_init(&info->ftp_session, >- &client_addr, >- &server_addr, >+ (struct sockaddr *)&client_addr, >+ (struct sockaddr *)&server_addr, > &info->telnet_session, > f->dir, > &err)) >@@ -444,7 +481,7 @@ > > /* convert an address to a printable string */ > /* NOT THREADSAFE - wrap with a mutex before calling! */ >-static char *addr2string(const sockaddr_storage_t *s) >+static char *addr2string(const struct sockaddr *s) > { > static char addr[IP_ADDRSTRLEN+1]; > int error; >@@ -454,14 +491,14 @@ > > #ifdef INET6 > error = getnameinfo((struct sockaddr *)s, >- sizeof(sockaddr_storage_t), >+ sizeof(struct sockaddr_storage), > addr, > sizeof(addr), > NULL, > 0, > NI_NUMERICHOST); > if (error != 0) { >- syslog(LOG_WARN, "getnameinfo error; %s", gai_strerror(error)); >+ syslog(LOG_WARNING, "getnameinfo error; %s", gai_strerror(error)); > ret_val = "Unknown IP"; > } else { > ret_val = addr; >@@ -480,6 +517,7 @@ > int num_connections; > char drop_reason[80]; > >+ syslog(LOG_WARNING, "in connection_handler\n"); > /* for ease of use only */ > f = info->ftp_listener; > >@@ -497,13 +535,15 @@ > pthread_mutex_lock(&f->mutex); > num_connections = ++f->num_connections; > syslog(LOG_INFO, "%s port %d connection", >- addr2string(&info->ftp_session.client_addr), >- ntohs(SINPORT(&info->ftp_session.client_addr))); >+ addr2string((struct sockaddr *)&info->ftp_session.client_addr), >+ sockaddr_port((struct sockaddr *)&info->ftp_session.client_addr, >+ sizeof(info->ftp_session.client_addr))); > pthread_mutex_unlock(&f->mutex); > > /* handle the session */ > if (num_connections <= f->max_connections) { > >+ syslog(LOG_WARNING, "about to call ftp_session_run\n"); > ftp_session_run(&info->ftp_session, &info->watched); > > } else { >@@ -518,8 +558,9 @@ > pthread_mutex_lock(&f->mutex); > syslog(LOG_WARNING, > "%s port %d exceeds max users (%d), dropping connection", >- addr2string(&info->ftp_session.client_addr), >- ntohs(SINPORT(&info->ftp_session.client_addr)), >+ addr2string((struct sockaddr *)&info->ftp_session.client_addr), >+ sockaddr_port((struct sockaddr *)&info->ftp_session.client_addr, >+ sizeof(info->ftp_session.client_addr)), > num_connections); > pthread_mutex_unlock(&f->mutex); > >@@ -548,8 +589,9 @@ > > syslog(LOG_INFO, > "%s port %d disconnected", >- addr2string(&info->ftp_session.client_addr), >- ntohs(SINPORT(&info->ftp_session.client_addr))); >+ addr2string((struct sockaddr *)&info->ftp_session.client_addr), >+ sockaddr_port((struct sockaddr *)&info->ftp_session.client_addr, >+ sizeof(info->ftp_session.client_addr))); > > pthread_mutex_unlock(&f->mutex); > >diff -Naur oftpd-0.3.7.orig/src/ftp_session.c oftpd-0.3.7/src/ftp_session.c >--- oftpd-0.3.7.orig/src/ftp_session.c 2004-03-25 20:46:40.000000000 +0000 >+++ oftpd-0.3.7/src/ftp_session.c 2010-01-05 21:50:11.159303450 +0000 >@@ -52,12 +52,12 @@ > static void init_passive_port(); > static int get_passive_port(); > static int convert_newlines(char *dst, const char *src, int srclen); >-static void get_addr_str(const sockaddr_storage_t *s, char *buf, int bufsiz); >+static void get_addr_str(const struct sockaddr *s, char *buf, int bufsiz); > static void send_readme(const ftp_session_t *f, int code); > static void netscape_hack(int fd); >-static void set_port(ftp_session_t *f, const sockaddr_storage_t *host_port); >-static int set_pasv(ftp_session_t *f, sockaddr_storage_t *host_port); >-static int ip_equal(const sockaddr_storage_t *a, const sockaddr_storage_t *b); >+static void set_port(ftp_session_t *f, const struct sockaddr *host_port); >+static int set_pasv(ftp_session_t *f, struct sockaddr *host_port); >+static int ip_equal(const struct sockaddr *a, const struct sockaddr *b); > static void get_absolute_fname(char *fname, > int fname_len, > const char *dir, >@@ -123,8 +123,8 @@ > > > int ftp_session_init(ftp_session_t *f, >- const sockaddr_storage_t *client_addr, >- const sockaddr_storage_t *server_addr, >+ const struct sockaddr *client_addr, >+ const struct sockaddr *server_addr, > telnet_session_t *t, > const char *dir, > error_t *err) >@@ -138,9 +138,9 @@ > daemon_assert(err != NULL); > > #ifdef INET6 >- /* if the control connection is on IPv6, we need to get an IPv4 address */ >- /* to bind the socket to */ >- if (SSFAM(server_addr) == AF_INET6) { >+ /* if the control connection is on IPv6, we need to get an IPv4 address >+ * to bind the socket to */ >+ if (server_addr->sa_family == AF_INET6) { > struct addrinfo hints; > struct addrinfo *res; > int errcode; >@@ -149,8 +149,10 @@ > memset(&hints, 0, sizeof(struct addrinfo)); > hints.ai_family = AF_INET; > hints.ai_flags = AI_PASSIVE; >- if (getaddrinfo(NULL, "ftp", &hints, &res) != 0) { >- error_init(err, 0, "unable to determing IPv4 address; %s", >+ hints.ai_socktype = SOCK_STREAM; >+ >+ if ((errcode = getaddrinfo(NULL, "21", &hints, &res)) != 0) { >+ error_init(err, 0, "unable to determine IPv4 address; %s", > gai_strerror(errcode)); > return 0; > } >@@ -158,17 +160,14 @@ > /* let's sanity check */ > daemon_assert(res != NULL); > daemon_assert(sizeof(f->server_ipv4_addr) >= res->ai_addrlen); >- daemon_assert(SSFAM(host_port) == AF_INET); >+ daemon_assert(res->ai_addr->sa_family == AF_INET); > > /* copy the result and free memory as necessary */ > memcpy(&f->server_ipv4_addr, res->ai_addr, res->ai_addrlen); > freeaddrinfo(res); > } else { >- daemon_assert(SSFAM(host_port) == AF_INET); >- f->server_ipv4_addr = *server_addr; >+ f->server_ipv4_addr = *((struct sockaddr_in *)server_addr); > } >-#else >- f->server_ipv4_addr = *server_addr; > #endif > > f->session_active = 1; >@@ -182,17 +181,22 @@ > > f->epsv_all_set = 0; > >- f->client_addr = *client_addr; >+#ifdef INET6 >+ memcpy(&f->client_addr, client_addr, sizeof(struct sockaddr_in6)); >+ memcpy(&f->server_addr, server_addr, sizeof(struct sockaddr_in6)); >+ memcpy(&f->data_port, client_addr, sizeof(struct sockaddr_in6)); >+#else >+ memcpy(&f->client_addr, client_addr, sizeof(struct sockaddr_in)); >+ memcpy(&f->server_addr, server_addr, sizeof(struct sockaddr_in)); >+ memcpy(&f->data_port, client_addr, sizeof(struct sockaddr_in)); >+#endif > get_addr_str(client_addr, f->client_addr_str, sizeof(f->client_addr_str)); > >- f->server_addr = *server_addr; >- > f->telnet_session = t; > daemon_assert(strlen(dir) < sizeof(f->dir)); > strcpy(f->dir, dir); > > f->data_channel = DATA_PORT; >- f->data_port = *client_addr; > f->server_fd = -1; > > daemon_assert(invariant(f)); >@@ -326,7 +330,8 @@ > /* If the client specifies a port, verify that it is from the */ > /* host the client connected from. This prevents a client from */ > /* using the server to open connections to arbritrary hosts. */ >- if (!ip_equal(&f->client_addr, &f->data_port)) { >+ if (!ip_equal((struct sockaddr *)&f->client_addr, >+ (struct sockaddr *)&f->data_port)) { > return 0; > } > if (f->server_fd != -1) { >@@ -412,7 +417,7 @@ > } > > #ifdef INET6 >-static void get_addr_str(const sockaddr_storage_t *s, char *buf, int bufsiz) >+static void get_addr_str(const struct sockaddr *s, char *buf, int bufsiz) > { > int port; > int error; >@@ -426,17 +431,17 @@ > * number (which is 5 chars max), plus the '\0' character. */ > daemon_assert(bufsiz >= (INET_ADDRSTRLEN + 12)); > >- error = getnameinfo(client_addr, sizeof(sockaddr_storage_t), buf, >+ error = getnameinfo(s, sizeof(struct sockaddr_storage), buf, > bufsiz, NULL, 0, NI_NUMERICHOST); > /* getnameinfo() should never fail when called with NI_NUMERICHOST */ > daemon_assert(error == 0); > > len = strlen(buf); > daemon_assert(bufsiz >= len+12); >- snprintf(buf+len, bufsiz-len, " port %d", ntohs(SINPORT(&f->client_addr))); >+ snprintf(buf+len, bufsiz-len, " port %d", sockaddr_port((struct sockaddr *)s, sizeof(s))); > } > #else >-static void get_addr_str(const sockaddr_storage_t *s, char *buf, int bufsiz) >+static void get_addr_str(const struct sockaddr *s, char *buf, int bufsiz) > { > unsigned int addr; > int port; >@@ -449,8 +454,8 @@ > * number (which is 5 chars max), plus the '\0' character. */ > daemon_assert(bufsiz >= (INET_ADDRSTRLEN + 12)); > >- addr = ntohl(s->sin_addr.s_addr); >- port = ntohs(s->sin_port); >+ addr = ntohl(((struct sockaddr_in *)s)->sin_addr.s_addr); >+ port = ntohs(((struct sockaddr_in *)s)->sin_port); > snprintf(buf, bufsiz, "%d.%d.%d.%d port %d", > (addr >> 24) & 0xff, > (addr >> 16) & 0xff, >@@ -626,16 +631,22 @@ > } > > /* support for the various port setting functions */ >-static void set_port(ftp_session_t *f, const sockaddr_storage_t *host_port) >-{ >+static void set_port(ftp_session_t *f, const struct sockaddr *host_port) >+{ > daemon_assert(invariant(f)); > daemon_assert(host_port != NULL); > > if (f->epsv_all_set) { > reply(f, 500, "After EPSV ALL, only EPSV allowed."); >- } else if (!ip_equal(&f->client_addr, host_port)) { >+ } else if (!ip_equal((struct sockaddr *)&f->client_addr, host_port)) { > reply(f, 500, "Port must be on command channel IP."); >- } else if (ntohs(SINPORT(host_port)) < IPPORT_RESERVED) { >+#ifdef INET6 >+ } else if (sockaddr_port(host_port, sizeof(struct sockaddr_storage)) >+ < IPPORT_RESERVED) { >+#else >+ } else if (sockaddr_port(host_port, sizeof(struct sockaddr_in)) >+ < IPPORT_RESERVED) { >+#endif > reply(f, 500, "Port may not be less than 1024, which is reserved."); > } else { > /* close any outstanding PASSIVE port */ >@@ -645,7 +656,11 @@ > } > > f->data_channel = DATA_PORT; >- f->data_port = *host_port; >+#ifdef INET6 >+ memcpy(&f->data_port, host_port, sizeof(struct sockaddr_in6)); >+#else >+ memcpy(&f->data_port, host_port, sizeof(struct sockaddr_in)); >+#endif > reply(f, 200, "Command okay."); > } > >@@ -655,16 +670,20 @@ > /* set IP and port for client to receive data on */ > static void do_port(ftp_session_t *f, const ftp_command_t *cmd) > { >- const sockaddr_storage_t *host_port; >+#ifdef INET6 >+ const struct sockaddr_storage *host_port; >+#else >+ const struct sockaddr_in *host_port; >+#endif > > daemon_assert(invariant(f)); > daemon_assert(cmd != NULL); > daemon_assert(cmd->num_arg == 1); > > host_port = &cmd->arg[0].host_port; >- daemon_assert(SSFAM(host_port) == AF_INET); >+ daemon_assert(((struct sockaddr *)host_port)->sa_family == AF_INET); > >- set_port(f, host_port); >+ set_port(f, (struct sockaddr *)host_port); > > daemon_assert(invariant(f)); > } >@@ -672,7 +691,12 @@ > /* set IP and port for client to receive data on, transport independent */ > static void do_lprt(ftp_session_t *f, const ftp_command_t *cmd) > { >- const sockaddr_storage_t *host_port; >+#ifdef INET6 >+ const struct sockaddr_storage *host_port; >+#else >+ const struct sockaddr_in *host_port; >+#endif >+ struct sockaddr_in6 *tmp = (struct sockaddr_in6 *)host_port; > > daemon_assert(invariant(f)); > daemon_assert(cmd != NULL); >@@ -681,16 +705,30 @@ > host_port = &cmd->arg[0].host_port; > > #ifdef INET6 >- if ((SSFAM(host_port) != AF_INET) && (SSFAM(host_port) != AF_INET6)) { >+ if ((((struct sockaddr *)host_port)->sa_family != AF_INET) && >+ (((struct sockaddr *)host_port)->sa_family != AF_INET6)) { > reply(f, 521, "Only IPv4 and IPv6 supported, address families (4,6)"); > } > #else >- if (SSFAM(host_port) != AF_INET) { >+ if (((struct sockaddr *)host_port)->sa_family != AF_INET) { > reply(f, 521, "Only IPv4 supported, address family (4)"); > } > #endif > >- set_port(f, host_port); >+ /* >+ syslog(LOG_WARNING, "host is %d:%d:%d:%d:%d:%d:%d:%d %d", >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[0]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[1]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[2]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[3]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[4]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[5]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[6]), >+ ntohs(((struct sockaddr_in6 *)host_port)->sin6_addr.s6_addr16[7]), >+ sockaddr_port(host_port, sizeof(struct sockaddr_storage))); >+ */ >+ >+ set_port(f, (struct sockaddr *)host_port); > > daemon_assert(invariant(f)); > } >@@ -703,7 +741,11 @@ > /* requests. */ > static void do_eprt(ftp_session_t *f, const ftp_command_t *cmd) > { >- const sockaddr_storage_t *host_port; >+#ifdef INET6 >+ const struct sockaddr_storage *host_port; >+#else >+ const struct sockaddr_in *host_port; >+#endif > > daemon_assert(invariant(f)); > daemon_assert(cmd != NULL); >@@ -717,15 +759,17 @@ > /* support for the various pasv setting functions */ > /* returns the file descriptor of the bound port, or -1 on error */ > /* note: the "host_port" parameter will be modified, having its port set */ >-static int set_pasv(ftp_session_t *f, sockaddr_storage_t *bind_addr) >+static int set_pasv(ftp_session_t *f, struct sockaddr *bind_addr) > { > int socket_fd; > int port; >+ sa_family_t family; > > daemon_assert(invariant(f)); > daemon_assert(bind_addr != NULL); > >- socket_fd = socket(SSFAM(bind_addr), SOCK_STREAM, 0); >+ family = ((struct sockaddr *)bind_addr)->sa_family; >+ socket_fd = socket(family, SOCK_STREAM, 0); > if (socket_fd == -1) { > reply(f, 500, "Error creating server socket; %s.", strerror(errno)); > return -1; >@@ -733,9 +777,19 @@ > > for (;;) { > port = get_passive_port(); >- SINPORT(bind_addr) = htons(port); >+#ifdef INET6 >+ if (((struct sockaddr *)bind_addr)->sa_family == AF_INET6) { >+ ((struct sockaddr_in6 *)bind_addr)->sin6_port = htons(port); >+ } else >+#endif >+ ((struct sockaddr_in *)bind_addr)->sin_port = htons(port); >+ > if (bind(socket_fd, (struct sockaddr *)bind_addr, >- sizeof(struct sockaddr)) == 0) >+#ifdef INET6 >+ sizeof(struct sockaddr_storage)) == 0) >+#else >+ sizeof(struct sockaddr_in)) == 0) >+#endif > { > break; > } >@@ -771,14 +825,23 @@ > goto exit_pasv; > } > >- socket_fd = set_pasv(f, &f->server_ipv4_addr); >+#ifdef INET6 >+ socket_fd = set_pasv(f, (struct sockaddr *)&f->server_ipv4_addr); >+#else >+ socket_fd = set_pasv(f, (struct sockaddr *)&f->server_addr); >+#endif > if (socket_fd == -1) { > goto exit_pasv; > } > > /* report port to client */ >+#ifdef INET6 > addr = ntohl(f->server_ipv4_addr.sin_addr.s_addr); > port = ntohs(f->server_ipv4_addr.sin_port); >+#else >+ addr = ntohl(f->server_addr.sin_addr.s_addr); >+ port = ntohs(f->server_addr.sin_port); >+#endif > reply(f, 227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d).", > addr >> 24, > (addr >> 16) & 0xff, >@@ -815,16 +878,16 @@ > goto exit_lpsv; > } > >- socket_fd = set_pasv(f, &f->server_addr); >+ socket_fd = set_pasv(f, (struct sockaddr *)&f->server_addr); > if (socket_fd == -1) { > goto exit_lpsv; > } > >- /* report address and port to client */ >+ /* report address and port to server */ > #ifdef INET6 >- if (SSFAM(&f->server_addr) == AF_INET6) { >- a = (uint8_t *)&SIN6ADDR(&f->server_addr); >- p = (uint8_t *)&SIN6PORT(&f->server_addr); >+ if (((struct sockaddr *)&f->server_addr)->sa_family == AF_INET6) { >+ a = (uint8_t *)&(((struct sockaddr_in6 *)&f->server_addr)->sin6_addr); >+ p = (uint8_t *)&(((struct sockaddr_in6 *)&f->server_addr)->sin6_port); > snprintf(addr, sizeof(addr), > "(6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d)", > a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], >@@ -832,8 +895,8 @@ > } else > #endif > { >- a = (uint8_t *)&SIN4ADDR(&f->server_addr); >- p = (uint8_t *)&SIN4PORT(&f->server_addr); >+ a = (uint8_t *)&(((struct sockaddr_in *)&f->server_addr)->sin_addr); >+ p = (uint8_t *)&(((struct sockaddr_in *)&f->server_addr)->sin_port); > snprintf(addr, sizeof(addr), "(4,4,%d,%d,%d,%d,2,%d,%d)", > a[0], a[1], a[2], a[3], p[0], p[1]); > } >@@ -855,7 +918,7 @@ > static void do_epsv(ftp_session_t *f, const ftp_command_t *cmd) > { > int socket_fd; >- sockaddr_storage_t *addr; >+ struct sockaddr *addr; > > daemon_assert(invariant(f)); > daemon_assert(cmd != NULL); >@@ -863,10 +926,10 @@ > > /* check our argument, if any, and use the appropriate address */ > if (cmd->num_arg == 0) { >- addr = &f->server_addr; >+ addr = (struct sockaddr *)&f->server_addr; > } else { > switch (cmd->arg[0].num) { >- /* EPSV_ALL is a special number indicating the client sent */ >+ /* EPSV_ALL is a special number indicating the server sent */ > /* the command "EPSV ALL" - this is not a request to assign */ > /* a new passive port, but rather to deny all future port */ > /* assignment requests other than EPSV */ >@@ -874,17 +937,20 @@ > f->epsv_all_set = 1; > reply(f, 200, "EPSV ALL command successful."); > goto exit_epsv; >+#ifdef INET6 > case 1: >- addr = (sockaddr_storage_t *)&f->server_ipv4_addr; >+ addr = (struct sockaddr *)&f->server_ipv4_addr; > break; >-#ifdef INET6 > case 2: >- addr = &f->server_addr; >+ addr = (struct sockaddr *)&f->server_addr; > break; > default: > reply(f, 522, "Only IPv4 and IPv6 supported, use (1,2)"); > goto exit_epsv; > #else >+ case 1: >+ addr = (struct sockaddr *)&f->server_addr; >+ break; > default: > reply(f, 522, "Only IPv4 supported, use (1)"); > goto exit_epsv; >@@ -900,7 +966,8 @@ > > /* report port to client */ > reply(f, 229, "Entering Extended Passive Mode (|||%d|)", >- ntohs(SINPORT(&f->server_addr))); >+ sockaddr_port((struct sockaddr *)&f->server_addr, >+ sizeof(f->server_addr))); > > /* close any outstanding PASSIVE port */ > if (f->data_channel == DATA_PASSIVE) { >@@ -1278,29 +1345,36 @@ > static int open_connection(ftp_session_t *f) > { > int socket_fd; >+#ifdef INET6 >+ struct sockaddr_storage addr; >+#else > struct sockaddr_in addr; >+#endif > unsigned addr_len; >+ sa_family_t family; > > daemon_assert((f->data_channel == DATA_PORT) || > (f->data_channel == DATA_PASSIVE)); > > if (f->data_channel == DATA_PORT) { >- socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0); >+ family = ((struct sockaddr *)&f->data_port)->sa_family; >+ socket_fd = socket(family, SOCK_STREAM, 0); > if (socket_fd == -1) { > reply(f, 425, "Error creating socket; %s.", strerror(errno)); > return -1; > } > if (connect(socket_fd, (struct sockaddr *)&f->data_port, >- sizeof(sockaddr_storage_t)) != 0) >+ sizeof(f->data_port)) != 0) > { > reply(f, 425, "Error connecting; %s.", strerror(errno)); > close(socket_fd); > return -1; > } > } else { >+ sa_family_t a, b; > daemon_assert(f->data_channel == DATA_PASSIVE); > >- addr_len = sizeof(struct sockaddr_in); >+ addr_len = sizeof(addr); > socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len); > if (socket_fd == -1) { > reply(f, 425, "Error accepting connection; %s.", strerror(errno)); >@@ -1310,15 +1384,31 @@ > /* in IPv6, the client can connect to a channel using a different */ > /* protocol - in that case, we'll just blindly let the connection */ > /* through, otherwise verify addresses match */ >- if (SAFAM(addr) == SSFAM(&f->client_addr)) { >- if (memcmp(&SINADDR(&f->client_addr), &SINADDR(&addr), >- sizeof(SINADDR(&addr)))) >- { >- reply(f, 425, >- "Error accepting connection; connection from invalid IP."); >- close(socket_fd); >- return -1; >- } >+ a = ((struct sockaddr *)&addr)->sa_family; >+ b = ((struct sockaddr *)&f->client_addr)->sa_family; >+ >+ if (a == b) { >+ if (a == AF_INET6) { >+ if (memcmp(&(((struct sockaddr_in6 *)&addr)->sin6_addr), >+ &(((struct sockaddr_in6 *)&f->client_addr)->sin6_addr), >+ sizeof(struct in6_addr))) >+ { >+ reply(f, 425, >+ "Error accepting connection; connection from invalid IP."); >+ close(socket_fd); >+ return -1; >+ } >+ } else { >+ if (memcmp(&(((struct sockaddr_in *)&addr)->sin_addr), >+ &(((struct sockaddr_in *)&f->client_addr)->sin_addr), >+ sizeof(struct in_addr))) >+ { >+ reply(f, 425, >+ "Error accepting connection; connection from invalid IP."); >+ close(socket_fd); >+ return -1; >+ } >+ } > } > #else > if (memcmp(&f->client_addr.sin_addr, >@@ -1811,20 +1901,69 @@ > } > } > >+#ifdef INET6 >+ > /* compare two addresses to see if they contain the same IP address */ >-static int ip_equal(const sockaddr_storage_t *a, const sockaddr_storage_t *b) >+static int ip_equal(const struct sockaddr *a, const struct sockaddr *b) > { >+ struct sockaddr *aa, *bb; >+ > daemon_assert(a != NULL); > daemon_assert(b != NULL); >- daemon_assert((SSFAM(a) == AF_INET) || (SSFAM(a) == AF_INET6)); >- daemon_assert((SSFAM(b) == AF_INET) || (SSFAM(b) == AF_INET6)); >- >- if (SSFAM(a) != SSFAM(b)) { >- return 0; >+ daemon_assert((a->sa_family == AF_INET) || (a->sa_family == AF_INET6)); >+ daemon_assert((b->sa_family == AF_INET) || (b->sa_family == AF_INET6)); >+ >+ aa = (struct sockaddr *)a; >+ bb = (struct sockaddr *)b; >+ >+ /* we have to handle those --damned-- IPV4MAPPED addresses */ >+ if (aa->sa_family != bb->sa_family) { >+ if (a->sa_family == AF_INET6 && >+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)a)->sin6_addr)) { >+ aa = (struct sockaddr *)alloca(sizeof(struct sockaddr_in)); >+ memset(aa, 0, sizeof(struct sockaddr_in)); >+ ((struct sockaddr_in *)aa)->sin_addr.s_addr = >+ ((struct sockaddr_in6 *)a)->sin6_addr.s6_addr32[3]; >+ ((struct sockaddr_in *)aa)->sin_port = >+ ((struct sockaddr_in6 *)a)->sin6_port; >+ } else if (b->sa_family == AF_INET6 && >+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)b)->sin6_addr)) { >+ bb = (struct sockaddr *)alloca(sizeof(struct sockaddr_in)); >+ memset(bb, 0, sizeof(struct sockaddr_in)); >+ ((struct sockaddr_in *)bb)->sin_addr.s_addr = >+ ((struct sockaddr_in6 *)b)->sin6_addr.s6_addr32[3]; >+ ((struct sockaddr_in *)bb)->sin_port = >+ ((struct sockaddr_in6 *)b)->sin6_port; >+ } else { >+ return 0; >+ } > } >- if (memcmp(&SINADDR(a), &SINADDR(b), sizeof(SINADDR(a))) != 0) { >- return 0; >+ >+ if (aa->sa_family == AF_INET6) { >+ if (memcmp(&((struct sockaddr_in6 *)aa)->sin6_addr, >+ &((struct sockaddr_in6 *)bb)->sin6_addr, >+ sizeof(struct sockaddr_in6)) != 0) return 0; >+ } else { >+ if (((struct sockaddr_in *)aa)->sin_addr.s_addr != >+ ((struct sockaddr_in *)bb)->sin_addr.s_addr) return 0; > } >+ > return 1; > } > >+#else >+ >+static int ip_equal(const struct sockaddr *a, const struct sockaddr *b) >+{ >+ daemon_assert(a != NULL); >+ daemon_assert(b != NULL); >+ daemon_assert(a->sa_family == AF_INET); >+ daemon_assert(b->sa_family == AF_INET); >+ >+ if (((struct sockaddr_in *)aa)->sin_addr.s_addr != >+ ((struct sockaddr_in *)bb)->sin_addr.s_addr) return 0; >+ >+ return 1; >+} >+ >+#endif >diff -Naur oftpd-0.3.7.orig/src/ftp_session.h oftpd-0.3.7/src/ftp_session.h >--- oftpd-0.3.7.orig/src/ftp_session.h 2001-05-10 23:29:12.000000000 +0000 >+++ oftpd-0.3.7/src/ftp_session.h 2010-01-05 21:50:11.160303781 +0000 >@@ -12,7 +12,6 @@ > #include <netinet/in.h> > #include <sys/types.h> > #include <limits.h> >-#include "af_portability.h" > #include "watchdog.h" > #include "error.h" > >@@ -54,12 +53,20 @@ > int epsv_all_set; > > /* address of client */ >- sockaddr_storage_t client_addr; >+#ifdef INET6 >+ struct sockaddr_storage client_addr; >+#else >+ struct sockaddr_in client_addr; >+#endif > char client_addr_str[ADDRPORT_STRLEN]; > > /* address of server (including IPv4 version) */ >- sockaddr_storage_t server_addr; >+#ifdef INET6 >+ struct sockaddr_storage server_addr; > struct sockaddr_in server_ipv4_addr; >+#else >+ struct sockaddr_in server_addr; >+#endif > > /* telnet session to encapsulate control channel logic */ > telnet_session_t *telnet_session; >@@ -70,7 +77,11 @@ > /* data channel information, including type, > and client address or server port depending on type */ > int data_channel; >- sockaddr_storage_t data_port; >+#ifdef INET6 >+ struct sockaddr_storage data_port; >+#else >+ struct sockaddr_in data_port; >+#endif > int server_fd; > > /* watchdog to handle timeout */ >@@ -78,8 +89,8 @@ > } ftp_session_t; > > int ftp_session_init(ftp_session_t *f, >- const sockaddr_storage_t *client_addr, >- const sockaddr_storage_t *server_addr, >+ const struct sockaddr *client_addr, >+ const struct sockaddr *server_addr, > telnet_session_t *t, > const char *dir, > error_t *err); >diff -Naur oftpd-0.3.7.orig/src/oftpd.c oftpd-0.3.7/src/oftpd.c >--- oftpd-0.3.7.orig/src/oftpd.c 2001-05-27 22:40:27.000000000 +0000 >+++ oftpd-0.3.7/src/oftpd.c 2010-01-05 21:50:11.160303781 +0000 >@@ -300,7 +300,7 @@ > > > fork_ret = fork(); >- if (fork_ret == -1) { >+ if (fork_ret < 0) { > fprintf(stderr, "%s: error forking; %s\n", exe_name, strerror(errno)); > exit(1); > } >@@ -313,7 +313,7 @@ > exit(1); > } > fork_ret = fork(); >- if (fork_ret == -1) { >+ if (fork_ret < 0) { > fprintf(stderr, "%s: error forking; %s\n", exe_name, strerror(errno)); > exit(1); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 157005
:
103284
|
211361
| 220543 |
220545
|
220547