inets ftp bug

Serge Aleynikov serge@REDACTED
Tue Aug 23 23:19:12 CEST 2005


Actually, there seems to be one more (at least :-( ) issue with the 
ftp.erl.  With the applied patch there is no more exception raised, but 
the second transfer of a file doesn't happen if you run the code outside 
of the debugger.

When running with a debugger, I get:

~/tmp/dirtest>erl
Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0]

Eshell V5.4.8  (abort with ^G)
1> i:ii(ftp).
{module,ftp}
2> i:ib(ftp, activate_data_connection, 1).
ok
3> debugger:start().
{ok,<0.36.0>}
4> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", 
"cust_group.txt").
"220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]"
"331 Password required for serge."
"230 User serge logged in."
"250 CWD command successful."
"500 EPSV not understood."
"200 PORT command successful"
"150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)"
"226 Transfer complete."
"150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)"
ok

This is good and expected. We can see that the file is transfered twice.
Now the same call without debugger:

~/tmp/dirtest>erl
Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0]

Eshell V5.4.8  (abort with ^G)
1> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", 
"cust_group.txt").
"220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]"
"331 Password required for serge."
"230 User serge logged in."
"250 CWD command successful."
"500 EPSV not understood."
"200 PORT command successful"
"150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)"
"226 Transfer complete."
"200 PORT command successful"
ok

No transfer is happening after the successful PORT command...

Serge


Serge Aleynikov wrote:
> OTP team:
> 
> I found a bug in the inets' ftp.erl client that can be patched by 
> applying the ftp.erl.patch file to the source.
> 
> The bug is seen when you try to download more than one file in a row 
> using ftp:recv/2 function.  For some reason this bug doesn't occur when 
> tracing is enabled (and/or debugger application is running).
> 
> Use the following to reproduce the bug:
> 
> ftp_test:test(Host, User, Password, RemoteDir, RemoteFile).
> 
> ~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin
> Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0]
> 
> Eshell V5.4.8  (abort with ^G)
> 1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt").
> "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]"
> "331 Password required for serge."
> "230 User serge logged in."
> "250 CWD command successful."
> "500 EPSV not understood."
> "200 PORT command successful"
> "150 Opening ASCII mode data connection for tt.txt (7487 bytes)"
> "226 Transfer complete."
> "200 PORT command successful"
> ** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]},
>                               {ftp,do_termiante,2},
>                               {gen_server,terminate,6},
>                               {proc_lib,init_p,5}]},
>             {gen_server,call,
>                         [<0.42.0>,
>                          {recv,"tt.txt","tt.txt"},
>                          infinity]}} **
> 
> Hope that it can make it in the next OTP release.
> 
> Regards,
> 
> Serge
> 
> 
> ------------------------------------------------------------------------
> 
> -module(ftp_test).
> 
> -export([test/5]).
> 
> test(Host, User, Password, Dir, File) ->
>     application:start(inets),
>     {ok, Pid} = ftp:open(Host, [verbose]),
>     ok = ftp:user(Pid, User, Password),
>     ok = ftp:cd(Pid, Dir),
>     ok = ftp:recv(Pid, File),
>     ok = ftp:recv(Pid, File),
>     ftp:close(Pid).
> 
> 
> ------------------------------------------------------------------------
> 
> --- /usr/local/lib/erlang/lib/inets-4.5/src/ftp.erl	Tue Aug 23 13:28:08 2005
> +++ ftp.erl	Tue Aug 23 16:39:43 2005
> @@ -790,11 +790,11 @@
>  %% terminate/2 and code_change/3
>  %%--------------------------------------------------------------------------
>  terminate(normal, State) ->
> -    do_termiante({error, econn}, State);
> +    do_terminate({error, econn}, State);
>  terminate(Reason, State) ->
> -    do_termiante({error, Reason}, State).
> +    do_terminate({error, Reason}, State).
>  
> -do_termiante(ErrorMsg, State) ->
> +do_terminate(ErrorMsg, State) ->
>      close_data_connection(State),
>      close_ctrl_connection(State),
>      case State#state.client of
> @@ -1313,6 +1313,8 @@
>  
>  close_data_connection(#state{dsock = undefined}) ->
>      ok;
> +close_data_connection(#state{dsock = {lsock, Socket}}) ->
> +    close_connection(Socket);
>  close_data_connection(#state{dsock = Socket}) ->
>      close_connection(Socket).



More information about the erlang-questions mailing list