Bug 79573

Summary: fish file transfer stops after 2 GB
Product: [Unmaintained] kio Reporter: Martin Horstmann <m.horstmann>
Component: fishAssignee: Jörg Walter <trouble>
Status: VERIFIED FIXED    
Severity: crash CC: dev, ismail, jtscsousa, nicolasg, spacial
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Martin Horstmann 2004-04-13 18:30:20 UTC
Version:           3.2.2 (using KDE KDE 3.2.2)
Installed from:    Debian testing/unstable Packages
OS:          Linux

With the transfer of one approx. 3,5 GB file over one fish://-Connection crashs the transmission after 2.0 GB.  The file transfer of the file by means of scp is successful.
Comment 1 Richard Bos 2004-04-13 21:32:47 UTC
You may seem the same problem using for example ftp, http, rsync, etc.
I run into these huge file problems recently and the only way to get
the file transferred was to split it in 2GB files and to concatenate the parts
on the destination system.  I did not try scp, might have worked.
I assume that fish:// uses one of the ftp, http, rsync, etc. protocols.
Comment 2 Anders Flyndersøe 2005-02-14 12:34:46 UTC
Version: KDE 3.3.2  
Installed from: Gentoo Packages

Able to reproduce the bug, but transfer failes to start instead of crash
sftp works fine with files > 2Gb
Comment 3 Gustavo Michels 2005-05-05 19:33:03 UTC
Same here as comment #2, transfers fails to start with the following error:

"Could not read file fish://<hostname>/<path>/<big.file>"

Using Gentoo Packages, KDE 3.4, compiled from sources.
Comment 4 Thiago Macieira 2005-06-22 13:16:15 UTC
*** Bug 103949 has been marked as a duplicate of this bug. ***
Comment 5 Nicolas Goutte 2005-09-17 15:29:11 UTC
*** Bug 109978 has been marked as a duplicate of this bug. ***
Comment 6 Nicolas Goutte 2005-09-17 15:45:31 UTC
SVN commit 461382 by goutte:

Be sure to use KIO:filesize_t for declaring variable having the file length
(Not tested; creates many warnings "unsigned < 0 always true")
CCBUG:79573


 M  +3 -3      fish.cpp  


--- branches/KDE/3.5/kdebase/kioslave/fish/fish.cpp #461381:461382
@@ -805,7 +805,7 @@
     int rc = handleResponse(line);
     UDSAtom atom;
     QDateTime dt;
-    int pos, pos2, pos3;
+    KIO::filesize_t pos, pos2, pos3;
     bool isOk = false;
     if (!rc) {
         switch (fishCommand) {
@@ -838,7 +838,7 @@
                 case '7':
                 case '8':
                 case '9':
-                    pos = line.toInt(&isOk);
+                    pos = line.toULongLong(&isOk);
                     if (pos > 0 && isOk) errorCount--;
                     if ((fishCommand == FISH_LIST) && (listReason == LIST))
                         totalSize(pos);
@@ -932,7 +932,7 @@
 
                 case 'S':
                     atom.m_uds = UDS_SIZE;
-                    atom.m_long = line.mid(1).toLongLong(&isOk);
+                    atom.m_long = line.mid(1).toULongLong(&isOk);
                     if (!isOk) break;
                     errorCount--;
                     udsEntry.append(atom);
Comment 7 Nicolas Goutte 2005-09-17 15:46:33 UTC
SVN commit 461383 by goutte:

Be sure to use KIO:filesize_t for declaring variable having the file length
(Forward port of revision 461382; not tested)
CCBUG:79573
(Not closing the bug, as Ihave no idea if it is enough to close the bug.)


 M  +3 -3      fish.cpp  


--- trunk/KDE/kdebase/kioslave/fish/fish.cpp #461382:461383
@@ -790,7 +790,7 @@
     int rc = handleResponse(line);
     UDSAtom atom;
     QDateTime dt;
-    int pos, pos2, pos3;
+    KIO::filesize_t pos, pos2, pos3;
     bool isOk = false;
     if (!rc) {
         switch (fishCommand) {
@@ -823,7 +823,7 @@
                 case '7':
                 case '8':
                 case '9':
-                    pos = line.toInt(&isOk);
+                    pos = line.toULongLong(&isOk);
                     if (pos > 0 && isOk) errorCount--;
                     if ((fishCommand == FISH_LIST) && (listReason == LIST))
                         totalSize(pos);
@@ -917,7 +917,7 @@
 
                 case 'S':
                     atom.m_uds = UDS_SIZE;
-                    atom.m_long = line.mid(1).toLongLong(&isOk);
+                    atom.m_long = line.mid(1).toULongLong(&isOk);
                     if (!isOk) break;
                     errorCount--;
                     udsEntry.append(atom);
Comment 8 Nicolas Goutte 2005-09-18 02:15:01 UTC
Unfortunately there are more variables that are only declared as int instead of being KIO:filesize_t. So the problem remains.
Comment 9 Tamás Hornos 2005-12-09 13:24:12 UTC
I got the same effect with KDE 3.5, scp is still working.
Version: KDE 3.5 Level "a" (OpenSUSE 10.0)
Comment 10 James Martinez 2006-03-27 00:07:05 UTC
I have the same bug in Konqueror 3.5.0 under ubuntu, not only do file transfers under fish stall at 2.0 GB, but the transfers are REALLY slow.  Before it stalled, it was getting ~800kB/s on a 10/100 LAN direct connection between the two computers involved.  scp works, and at about 4MB/s. Please fix!
Comment 11 James Martinez 2006-03-27 00:08:41 UTC
the error is reproducible, and has happened to me at least three times.
Comment 12 Martin Koller 2006-11-03 23:28:33 UTC
*** Bug 125497 has been marked as a duplicate of this bug. ***
Comment 13 Martin Koller 2006-11-04 13:36:46 UTC
SVN commit 601776 by mkoller:

BUG: 79573

use KIO::fileoffset_t instead of int to be able to handle
files > 2GB


 M  +5 -5      fish.cpp  
 M  +11 -12    fish.h  


--- branches/KDE/3.5/kdebase/kioslave/fish/fish.cpp #601775:601776
@@ -530,7 +530,7 @@
 /**
 writes one chunk of data to stdin of child process
 */
-void fishProtocol::writeChild(const char *buf, int len) {
+void fishProtocol::writeChild(const char *buf, KIO::fileoffset_t len) {
     if (outBufPos >= 0 && outBuf) {
 #if 0
         QString debug;
@@ -547,7 +547,7 @@
 /**
 manages initial communication setup including password queries
 */
-int fishProtocol::establishConnection(char *buffer, int len) {
+int fishProtocol::establishConnection(char *buffer, KIO::fileoffset_t len) {
     QString buf;
     buf.setLatin1(buffer,len);
     int pos;
@@ -1018,7 +1018,7 @@
                 recvLen = 0;
                 break;
             }
-            recvLen = line.toInt(&isOk);
+            recvLen = line.toLongLong(&isOk);
             if (!isOk) {
                 error(ERR_COULD_NOT_READ,url.prettyURL());
                 shutdownConnection();
@@ -1193,7 +1193,7 @@
 {
     if (rawWrite > 0) {
         myDebug( << "writing raw: " << rawData.size() << "/" << rawWrite << endl);
-        writeChild(rawData.data(),((unsigned int)rawWrite > rawData.size()?rawData.size():rawWrite));
+        writeChild(rawData.data(),(rawWrite > rawData.size()?rawData.size():rawWrite));
         rawWrite -= rawData.size();
         if (rawWrite > 0) {
             dataReq();
@@ -1221,7 +1221,7 @@
     }
 }
 
-int fishProtocol::received(const char *buffer, int buflen)
+int fishProtocol::received(const char *buffer, KIO::fileoffset_t buflen)
 {
     int pos = 0;
     do {
--- branches/KDE/3.5/kdebase/kioslave/fish/fish.h #601775:601776
@@ -90,9 +90,9 @@
   /** buffer for data to be written */
   const char *outBuf;
   /** current write position in buffer */
-  int outBufPos;
+  KIO::fileoffset_t outBufPos;
   /** length of buffer */
-  int outBufLen;
+  KIO::fileoffset_t outBufLen;
   /** use su if true else use ssh */
   bool local;
   /**  // FIXME: just a workaround for konq deficiencies */
@@ -137,13 +137,13 @@
   /** queue for commands to be sent */
   QValueList<int> commandCodes;
   /** bytes still to be read in raw mode */
-  int rawRead;
+  KIO::fileoffset_t rawRead;
   /** bytes still to be written in raw mode */
-  int rawWrite;
+  KIO::fileoffset_t rawWrite;
   /** data bytes to read in next read command */
-  int recvLen;
+  KIO::fileoffset_t recvLen;
   /** data bytes to write in next write command */
-  int sendLen;
+  KIO::fileoffset_t sendLen;
   /** true if the last write operation was finished */
   bool writeReady;
   /** true if a command stack is currently executing */
@@ -157,7 +157,7 @@
   /** true if file may be overwritten */
   bool checkOverwrite;
   /** current position of write */
-  int putPos;
+  KIO::fileoffset_t putPos;
   /** true if file already existed */
   bool checkExist;
   /** true if this is the first login attempt (== use cached password) */
@@ -169,7 +169,7 @@
   /** whther the mimetype has been sent already */
   bool mimeTypeSent;
   /** number of bytes read so far */
-  int dataRead;
+  KIO::fileoffset_t dataRead;
   /** details about each fishCommand */
   static const struct fish_info {
       const char *command;
@@ -186,9 +186,8 @@
   int fishCodeLen;
 protected: // Protected methods
   /** manages initial communication setup including password queries */
-  int establishConnection(char *buffer, int buflen);
-  void debugConnection(char *buffer, int buflen);
-  int received(const char *buffer, int buflen);
+  int establishConnection(char *buffer, KIO::fileoffset_t buflen);
+  int received(const char *buffer, KIO::fileoffset_t buflen);
   void sent();
   /** builds each FISH request and sets the error counter */
   bool sendCommand(fish_command_type cmd, ...);
@@ -201,7 +200,7 @@
   /** creates the subprocess */
   bool connectionStart();
   /** writes one chunk of data to stdin of child process */
-  void writeChild(const char *buf, int len);
+  void writeChild(const char *buf, KIO::fileoffset_t len);
   /** parses response from server and acts accordingly */
   void manageConnection(const QString &line);
   /** writes to process */
Comment 14 Thorsten Staerk 2006-11-05 07:26:30 UTC
Congrats, I am really excited about this solution!!!
We need to forward-port it to trunk however.
Comment 15 Ismail Donmez 2006-11-05 10:11:19 UTC
SVN commit 601779 by mkoller:

forwardport of fix for bug 79573; handle files > 2GB


 M  +6 -6      fish.cpp  
 M  +11 -12    fish.h  
Comment 16 Thorsten Staerk 2006-11-23 15:35:52 UTC
wohooo!
thanks a LOT, it works!