[Bug 1173] scp reports lost connection for very large files
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Fri Mar 17 17:12:25 EST 2006
http://bugzilla.mindrot.org/show_bug.cgi?id=1173
Summary: scp reports lost connection for very large files
Product: Portable OpenSSH
Version: 4.3p2
Platform: HPPA
OS/Version: HP-UX
Status: NEW
Severity: normal
Priority: P2
Component: scp
AssignedTo: bitbucket at mindrot.org
ReportedBy: e.borovac at bom.gov.au
As the summary says scp (4.3p2) reports 'lost connection' for very large files
(e.g. 10GB) and terminates transfer around 1.8G mark.
We have verified that file transfer works fine with 4.2p1.
I'll attempt to describe where I think the problem is.
The size of the file being transferred is around 10G (10435459928), however
with 'scp -v' it is reported (see line below) as merely 1.8G or so
(1845525336).
Sending file modes: C0644 1845525336 onedrain_opsncc_pg_dump.out
Further investigation points to scp.c line 607
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
(u_int) (stb.st_mode & FILEMODEMASK),
(long long)stb.st_size, last);
if (verbose_mode) {
fprintf(stderr, "Sending file modes: %s", buf);
}
Value in stb.st_size is correct (10435459928), however after snprintf()
variable buf holds incorrect value (1845525336).
Now, snprintf() that gets used is the one in openbsd-compat/bsd-snprintf.c not
the native HP-UX one. Output from 'configure' shows the following
checking whether vsnprintf returns correct values on overflow... no
configure: WARNING: ****** Your vsnprintf() function is broken, complain to
your vendor
Consequently BROKEN_SNPRINTF gets defined in config.h and snprintf() definition
comes from openbsd-compat/bsd-snprintf.c.
Here are relevant lines from bsd-snprintf.c line 470
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
It seems that type for 'value' should be 'LLONG' instead of 'long' and
similarly type for 'uvalue' should be 'unsigned LLONG' instead of 'unsigned
long'.
In dopr() 'value' is defined as 'LLONG' (long long) but when it's passed to
fmtint() it's cast from 'LLONG' (long long) to 'long'. This seems to be root
cause for snprintf() anomaly.
After making these changes to fmtint, scp reports correct size for the file and
transfers it completely.
--- bsd-snprintf.c.orig 2005-12-17 22:32:04.000000000 +1100
+++ bsd-snprintf.c 2006-03-17 17:08:29.000000000 +1100
@@ -161,7 +161,7 @@
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags);
+ LLONG value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
@@ -468,10 +468,10 @@
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags)
+ LLONG value, int base, int min, int max, int flags)
{
int signvalue = 0;
- unsigned long uvalue;
+ unsigned LLONG uvalue;
char convert[20];
int place = 0;
int spadlen = 0; /* amount to space pad */
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
More information about the openssh-bugs
mailing list