Tk Library Source Code

View Ticket
Login
Ticket UUID: 548540
Title: ftp::Put success on control timeout
Type: Bug Version: None
Submitter: drcampbell Created on: 2002-04-25 11:07:51
Subsystem: ftp Assigned To: gwlester
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2013-07-04 17:25:11
Resolution: Not Applicable Here Closed By:
    Closed on:
Description:
On numerous Tcl versions (up to 8.3) and ftp
library versions (1.2, 2.2, 2.3) we have
experienced false successes for ftp::Put.
Recently, we have noticed that these occur when
ftp::Put encounters the error:
"Timeout of control connection"

If a sequence of files are being sent by ftp::Put,
then subsequent files after the erroneous success
will have their data written to the wrong file name.

E.g.

ftp::Put A is OK

ftp::Put B times out

ftp::Put C sends C's contents to the file B!

As a work-around I set a flag in the
ftp::DisplayMsg procedure within the error
branch.  If this flag is set despite ftp::Put
indicating success, then I treat this as a 
failed ftp::Put.  I then quit the connection
to try again.

Additionally, a couple of times after experiencing
these false-positive results when we have attempted
to quit the connection, we have encountered an
inifinite loop:

bgerror failed to handle background error.
    Original error: Unknown state "quit_sent"
    Error in bgerror: invalid command name "bgerror"
bgerror failed to handle background error.
    Original error: too many nested calls to 
Tcl_EvalObj (infinite loop?)
    Error in bgerror: too many nested calls to 
Tcl_EvalObj (infinite loop?)

(This is using ftp_lib.tcl 2.3 with Tcl 8.3 on
Solaris)
User Comments: hofkensg added on 2007-03-19 01:54:20:
Logged In: YES 
user_id=1625850
Originator: NO

I sometimes see the following crash during a ftp::Get :

can't read "ftp(Start_Time)": no such element in array
    while executing
"expr {$stop_time - $ftp(Start_Time)}"
    (procedure "ElapsedTime" line 5)
    invoked from within
"ElapsedTime $s [clock seconds]"
    (procedure "ftp::Get" line 87)


I think this happens because the proc ftp::WaitOrTimeout (used at the end of ftp::Get) returns 1 on timeout i.s.o. 0. And so ftp::Get tries to calculate the elapsed time in ftp::ElapsedTime, while ftp(Start_Time) is not yet existing, resulting in a crash.
I have looked at all usage of ftp::WaitOrTimeout, and the return code should be 1 on success, 0 on error. Therefore I suggest to change ftp::Timeout to put ftp(state.control) to 0.

It solves the crash for me and I think it will solve the related bugs of this thread as well.

As I am not able to add a patchfile to this comment, I will paste the diff (only a 1 needs to be changed to a 0) :
--- ftp1.45.tcl2007-03-16 21:25:07.954228800 +0100
+++ ftp.tcl2007-03-18 19:45:10.498745600 +0100
@@ -121,7 +121,7 @@
     upvar ::ftp::ftp$s ftp
 
     after cancel $ftp(Wait)
-    set ftp(state.control) 1
+    set ftp(state.control) 0
 
     DisplayMsg "" "Timeout of control connection after $ftp(Timeout) sec.!" error
     Command $ftp(Command) timeout

drcampbell added on 2002-11-23 00:12:57:
Logged In: YES 
user_id=526050

I have an undesirable result from "set ftp(stat.control) 0" 
in "ftp::Timeout".

This time we had an unreliable connection that was timing-out 
on the ftp::Get.  When trying to close the connection with 
ftp::Close the call to ftp::Timeout from ftp::WaitOrTimeout 
would not return.  Instead, it just hung.  If I ignored trying to 
close the connection, the connection hung when trying to 
connect next.

The only reliable solution was to return to "set ftp
(state.control) 1" in ftp::Timeout, then to close the connection 
with ftp::Close as soon as an error was discovered when 
having run ftp::Get.

drcampbell added on 2002-11-08 17:35:14:
Logged In: YES 
user_id=526050

I've modified 'ftp::Timeout' to set ftp(state.control) to "0" and 
I'm in the process of testing.  I've not yet managed to recreate 
the exact scenario to judge the behaviour with this 
modification, but it does appear to be behaving as one would 
hope.

andreas_kupries added on 2002-10-18 05:07:21:
Logged In: YES 
user_id=75003

With the error message in your patch I find 'ftp::Timeout'. The 
interesting thing about this procedure is that it sets ftp
(state.control) to "1". This value seems to become the result 
of the command in execution, and means 'Ok'. Which IMHO 
is not ok. The error value is '0'.

drcampbell added on 2002-05-15 17:38:32:

File Added - 23117: FTP-patch.tclsh

andreas_kupries added on 2002-05-15 02:22:50:
Logged In: YES 
user_id=75003

Can you attach a small script/patch which show how you 
modfied DisplayMsg ? I would basically like to know if you 
check for a specific error message, or just that there was 
an error message. If you know which error message you get, 
well, that would be helpful as well. The ftp sources are a 
bit convoluted and any piece of information you can give me 
will make it easier to find the place where it should error 
out instead of returning a false-positive. Especially as I 
am not the original author of this code.

Attachments: