diff -urN proftpd-1.2.10/include/data.h proftpd-1.2.10-sendfile64/include/data.h --- proftpd-1.2.10/include/data.h 2004-05-21 19:19:02.000000000 +0200 +++ proftpd-1.2.10-sendfile64/include/data.h 2005-02-03 17:18:39.676660624 +0100 @@ -36,25 +36,12 @@ int pr_data_open(char *, char *, int, off_t); void pr_data_close(int); void pr_data_abort(int, int); -int pr_data_xfer(char *, int); +off_t pr_data_xfer(char *, int); void pr_data_reset(void); void pr_data_set_linger(long); #ifdef HAVE_SENDFILE -typedef - -#if defined(HAVE_AIX_SENDFILE) || defined(HAVE_HPUX_SENDFILE) || \ - defined(HAVE_LINUX_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE) -ssize_t -#elif defined(HAVE_BSD_SENDFILE) -off_t -#else -#error "You have an unknown sendfile implementation." -#endif - -pr_sendfile_t; - -pr_sendfile_t pr_data_sendfile(int retr_fd, off_t *offset, size_t count); +off_t pr_data_sendfile(int retr_fd, off_t *offset, off_t count); #endif /* HAVE_SENDFILE */ #endif /* PR_DATACONN_H */ diff -urN proftpd-1.2.10/modules/mod_xfer.c proftpd-1.2.10-sendfile64/modules/mod_xfer.c --- proftpd-1.2.10/modules/mod_xfer.c 2004-08-25 00:24:18.000000000 +0200 +++ proftpd-1.2.10-sendfile64/modules/mod_xfer.c 2005-02-03 17:18:26.109723112 +0100 @@ -603,7 +603,7 @@ return; } -static int _transmit_normal(char *buf, long bufsize) { +static off_t _transmit_normal(char *buf, long bufsize) { long count; if ((count = pr_fsio_read(retr_fh, buf, bufsize)) <= 0) @@ -614,7 +614,7 @@ #ifdef HAVE_SENDFILE static int _transmit_sendfile(off_t count, off_t *offset, - pr_sendfile_t *retval) { + off_t *retval) { /* We don't use sendfile() if: * - We're using bandwidth throttling. @@ -670,8 +670,8 @@ } #endif /* HAVE_SENDFILE */ -static long _transmit_data(off_t count, off_t offset, char *buf, long bufsize) { - long res; +static off_t _transmit_data(off_t count, off_t offset, char *buf, long bufsize) { + off_t res; #ifdef TCP_CORK int on = 1; @@ -679,7 +679,7 @@ #endif /* TCP_CORK */ #ifdef HAVE_SENDFILE - pr_sendfile_t retval; + off_t retval; #endif /* HAVE_SENDFILE */ #ifdef TCP_CORK @@ -695,7 +695,7 @@ if (!_transmit_sendfile(count, &offset, &retval)) res = _transmit_normal(buf, bufsize); else - res = (long) retval; + res = retval; #else res = _transmit_normal(buf, bufsize); #endif /* HAVE_SENDFILE */ @@ -1526,8 +1526,8 @@ off_t nbytes_max_retrieve = 0; unsigned char have_limit = FALSE; privdata_t *p; - long bufsize, len = 0; - off_t respos = 0, nbytes_sent = 0, cnt_steps = 0, cnt_next = 0; + long bufsize; + off_t respos = 0, nbytes_sent = 0, cnt_steps = 0, cnt_next = 0, len = 0; /* This function sets static module variables for later potential * throttling of the transfer. diff -urN proftpd-1.2.10/src/data.c proftpd-1.2.10-sendfile64/src/data.c --- proftpd-1.2.10/src/data.c 2004-08-25 20:08:46.000000000 +0200 +++ proftpd-1.2.10-sendfile64/src/data.c 2005-02-03 17:20:56.858805768 +0100 @@ -772,9 +772,9 @@ * closes, or -1 if error */ -int pr_data_xfer(char *cl_buf, int cl_size) { - int len = 0; - int total = 0; +off_t pr_data_xfer(char *cl_buf, int cl_size) { + off_t len = 0; + off_t total = 0; if (session.xfer.direction == PR_NETIO_IO_RD) { char *buf = session.xfer.buf; @@ -910,9 +910,9 @@ * ASCII translation is not performed. * return 0 if reading and data connection closes, or -1 if error */ -pr_sendfile_t pr_data_sendfile(int retr_fd, off_t *offset, size_t count) { +off_t pr_data_sendfile(int retr_fd, off_t *offset, off_t count) { int flags, error; - pr_sendfile_t len = 0, total = 0; + off_t len = 0, total = 0; #if defined(HAVE_AIX_SENDFILE) struct sf_parms parms; int rc; @@ -932,14 +932,19 @@ for (;;) { #if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE) off_t orig_offset = *offset; + off_t translen = 0; + if (count > 1024*1024*1024) + translen = 1024*1024*1024; + else + translen = count; /* Linux semantics are fairly straightforward in a glibc 2.x world: * * #include * * ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) */ - len = sendfile(PR_NETIO_FD(session.d->outstrm), retr_fd, offset, count); + len = sendfile(PR_NETIO_FD(session.d->outstrm), retr_fd, offset, (size_t)translen); if (len != -1 && len < count) { /* under linux semantics, this occurs when a signal has interrupted