Subject: off_t bug in ftpd
To: None <netbsd-bugs@sun-lamp.cs.berkeley.edu>
From: None <carrel@cisco.com>
List: netbsd-bugs
Date: 06/28/1994 00:13:37
>Submitter-Id: net
>Originator: David Carrel
>Organization:
Just a regular guy!
>Confidential: no
>Synopsis: ftpd always claims 0 byte files being transfered
>Severity: non-critical
>Priority: medium
>Category: bin
>Class: sw-bug
>Release: 0.9C (sources from 26 June 94)
>Environment:
This problem probably only manifests itself on big endian machines
but I can't say for sure since I don't have a little endian machine. The
fix below is universal.
Tested on hp300
>Description:
When ftp-ing a file from a big endian NetBSD machine, the server
end always reports that the file size is zero.
The ftpd code is passing off_t's to printf and then printing them
as longs. On big endian machines, this means that only the most
significant word is used and this is always zero (or at least it is for any
files that I am able to create ;-). No further troubles occur since the
off_t in question is the last value passed to printf and so there is
nothing after it to get messed up.
This is only a problem in the presentation. Files do transfer
correctly.
>How-To-Repeat:
ftp to a big endian NetBSD machine (ie hp300) from ANY host
ftp> get .bashrc foot
227 Entering Passive Mode (155,53,128,106,4,5)
150 Opening BINARY mode data connection for .bashrc (0 bytes).
226 Transfer complete.
8891 bytes received in 15.6 secs (568 bytes/sec)
ftp>
Notice that the size on the second line is zero bytes, but the local ftp
reports 8891 bytes were transfered. (8891 is correct)
>Fix:
The fix is to cast the off_t's to ulongs since that is what the
format strings are telling printf that it is receiving.
*** ftpcmd.y.orig Mon Jun 27 23:49:42 1994
--- ftpcmd.y Mon Jun 27 23:50:27 1994
***************
*** 1171,1177 ****
(stbuf.st_mode&S_IFMT) != S_IFREG)
reply(550, "%s: not a plain file.", filename);
else
! reply(213, "%lu", stbuf.st_size);
break;}
case TYPE_A: {
FILE *fin;
--- 1171,1177 ----
(stbuf.st_mode&S_IFMT) != S_IFREG)
reply(550, "%s: not a plain file.", filename);
else
! reply(213, "%lu", (unsigned long)stbuf.st_size);
break;}
case TYPE_A: {
FILE *fin;
*** ftpd.c.orig Mon Jun 27 23:49:42 1994
--- ftpd.c Mon Jun 27 23:50:28 1994
***************
*** 738,744 ****
file_size = size;
byte_count = 0;
if (size != (off_t) -1)
! (void) sprintf (sizebuf, " (%ld bytes)", size);
else
(void) strcpy(sizebuf, "");
if (pdata >= 0) {
--- 738,744 ----
file_size = size;
byte_count = 0;
if (size != (off_t) -1)
! (void) sprintf (sizebuf, " (%ld bytes)", (unsigned long)size);
else
(void) strcpy(sizebuf, "");
if (pdata >= 0) {
------------------------------------------------------------------------------