linamh/net-ftp/oftpd/files/oftpd-0.3.7-ipv6rel2-1.patch

1309 lines
44 KiB
Diff
Raw Normal View History

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);
}