From b6951505043a89fc13d694f1ed81f5329ce736b1 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 27 Sep 2013 16:04:45 +0200 Subject: ftp: Implement ftps (upgrade to TLS) --- lib/inets/src/ftp/ftp.erl | 338 +++++++++++++--------- lib/inets/src/ftp/ftp_response.erl | 1 + lib/inets/test/Makefile | 1 + lib/inets/test/ftp_SUITE.erl | 146 ++++------ lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel | 18 -- lib/inets/test/old_ftp_SUITE.erl | 127 ++++++++ lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel | 18 ++ 7 files changed, 408 insertions(+), 241 deletions(-) delete mode 100644 lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel create mode 100644 lib/inets/test/old_ftp_SUITE.erl create mode 100644 lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 5d9887a9a4..f937402477 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -67,7 +67,8 @@ %% Internal state -record(state, { csock = undefined, % socket() - Control connection socket - dsock = undefined, % socket() - Data connection socket + dsock = undefined, % socket() - Data connection socket + tls_options = undefined, % list() verbose = false, % boolean() ldir = undefined, % string() - Current local directory type = ftp_server_default, % atom() - binary | ascii @@ -90,7 +91,8 @@ caller = undefined, % term() ipfamily, % inet | inet6 | inet6fb4 progress = ignore, % ignore | pid() - dtimeout = ?DATA_ACCEPT_TIMEOUT % non_neg_integer() | infinity + dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity + tls_upgrading_data_connection }). @@ -154,8 +156,7 @@ open(Host, Opts) when is_list(Opts) -> ?fcrt("open", [{open_options, OpenOptions}]), case start_link(StartOptions, []) of {ok, Pid} -> - ?fcrt("open - ok", [{pid, Pid}]), - call(Pid, {open, ip_comm, OpenOptions}, plain); + do_open(Pid, OpenOptions, tls_options(Opts)); Error1 -> ?fcrt("open - error", [{error1, Error1}]), Error1 @@ -166,7 +167,13 @@ open(Host, Opts) when is_list(Opts) -> Error2 end. - +do_open(Pid, OpenOptions, TLSOpts) -> + case call(Pid, {open, ip_comm, OpenOptions}, plain) of + {ok, Pid} -> + maybe_tls_upgrade(Pid, TLSOpts); + Error -> + Error + end. %%-------------------------------------------------------------------------- %% user(Pid, User, Pass, ) -> ok | {error, euser} | {error, econn} %% | {error, eacct} @@ -905,6 +912,10 @@ open_options(Options) -> {progress, ValidateProgress, false, ?PROGRESS_DEFAULT}], validate_options(Options, ValidOptions, []). +tls_options(Options) -> + %% Options will be validated by ssl application + proplists:get_value(tls, Options, undefined). + validate_options([], [], Acc) -> ?fcrt("validate_options -> done", [{acc, Acc}]), {ok, lists:reverse(Acc)}; @@ -1021,8 +1032,8 @@ handle_call({_, info}, _, #state{verbose = Verbose, ipfamily = IpFamily, csock = Socket, progress = Progress} = State) -> - {ok, {_, LocalPort}} = inet:sockname(Socket), - {ok, {Address, Port}} = inet:peername(Socket), + {ok, {_, LocalPort}} = sockname(Socket), + {ok, {Address, Port}} = peername(Socket), Options = [{verbose, Verbose}, {ipfamily, IpFamily}, {mode, Mode}, @@ -1091,6 +1102,10 @@ handle_call({_, {open, ip_comm, Host, Opts}}, From, State) -> {stop, normal, State2#state{client = undefined}} end; +handle_call({_, {open, tls_upgrade, TLSOptions}}, From, State) -> + send_ctrl_message(State, mk_cmd("AUTH TLS", [])), + {noreply, State#state{client = From, caller = open, tls_options = TLSOptions}}; + handle_call({_, {user, User, Password}}, From, #state{csock = CSock} = State) when (CSock =/= undefined) -> handle_user(User, Password, "", State#state{client = From}); @@ -1196,8 +1211,8 @@ handle_call({_,{recv_chunk_start, RemoteFile}}, From, #state{chunk = false} handle_call({_, recv_chunk}, _, #state{chunk = false} = State) -> {reply, {error, "ftp:recv_chunk_start/2 not called"}, State}; -handle_call({_, recv_chunk}, From, #state{chunk = true} = State) -> - activate_data_connection(State), +handle_call({_, recv_chunk}, From, #state{chunk = true} = State0) -> + State = activate_data_connection(State0), {noreply, State#state{client = From, caller = recv_chunk}}; handle_call({_, {send, LocalFile, RemoteFile}}, From, @@ -1301,10 +1316,10 @@ handle_info(timeout, State) -> %%% Data socket messages %%% handle_info({tcp, Socket, Data}, #state{dsock = Socket, - caller = {recv_file, Fd}} = State) -> + caller = {recv_file, Fd}} = State0) -> file_write(binary_to_list(Data), Fd), - progress_report({binary, Data}, State), - activate_data_connection(State), + progress_report({binary, Data}, State0), + State = activate_data_connection(State0), {noreply, State}; handle_info({tcp, Socket, Data}, #state{dsock = Socket, client = From, @@ -1313,8 +1328,8 @@ handle_info({tcp, Socket, Data}, #state{dsock = Socket, client = From, gen_server:reply(From, {ok, Data}), {noreply, State#state{client = undefined, data = <<>>}}; -handle_info({tcp, Socket, Data}, #state{dsock = Socket} = State) -> - activate_data_connection(State), +handle_info({tcp, Socket, Data}, #state{dsock = Socket} = State0) -> + State = activate_data_connection(State0), {noreply, State#state{data = <<(State#state.data)/binary, Data/binary>>}}; @@ -1357,12 +1372,12 @@ handle_info({tcp_error, Socket, Reason}, #state{dsock = Socket, data = <<>>, caller = undefined, chunk = false}}; %%% Ctrl socket messages %%% -handle_info({tcp, Socket, Data}, #state{csock = Socket, - verbose = Verbose, - caller = Caller, - client = From, - ctrl_data = {CtrlData, AccLines, - LineStatus}} +handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, + verbose = Verbose, + caller = Caller, + client = From, + ctrl_data = {CtrlData, AccLines, + LineStatus}} = State) -> case ftp_response:parse_lines(<>, AccLines, LineStatus) of @@ -1386,10 +1401,12 @@ handle_info({tcp, Socket, Data}, #state{csock = Socket, {noreply, State#state{ctrl_data = NewCtrlData}} end; -handle_info({tcp_closed, Socket}, #state{csock = Socket}) -> - %% If the server closes the control channel it is - %% the expected behavior that connection process terminates. +%% If the server closes the control channel it is +%% the expected behavior that connection process terminates. +handle_info({tcp_closed, Socket}, #state{csock = {tcp, Socket}}) -> exit(normal); %% User will get error message from terminate/2 +handle_info({ssl_closed, Socket}, #state{csock = {ssl, Socket}}) -> + exit(normal); handle_info({tcp_error, Socket, Reason}, _) -> Report = @@ -1399,6 +1416,8 @@ handle_info({tcp_error, Socket, Reason}, _) -> %% If tcp does not work the only option is to terminate, %% this is the expected behavior under these circumstances. exit(normal); %% User will get error message from terminate/2 +handle_info({ssl_error, _Socket, _Reason}, _) -> + exit(normal); %% TODO?? %% Monitor messages - if the process owning the ftp connection goes %% down there is no point in continuing. @@ -1568,6 +1587,40 @@ handle_user_account(Acc, State) -> %%-------------------------------------------------------------------------- %%-------------------------------------------------------------------------- %% Handling of control connection setup +handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz, _}} = State) -> + send_ctrl_message(State, mk_cmd("PROT P", [])), + activate_ctrl_connection(State), + {noreply, State#state{tls_upgrading_data_connection = {true, prot}}}; + +handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot, NextAction}, + dsock = {tcp, Socket}, client = From, + tls_options = TLSOptions} = State0) -> + case ssl:connect(Socket, TLSOptions) of + {ok, TLSSocket} -> + State = State0#state{dsock = {ssl, TLSSocket}, + tls_upgrading_data_connection = {false, undefined}}, + next_action_after_tls_upgrade(NextAction, State); + {error, _} = Error -> + gen_server:reply(From, {Error, self()}), + {stop, normal, State0#state{client = undefined, + caller = undefined}} + end; + +handle_ctrl_result({tls_upgrade, _}, #state{csock = {tcp, Socket}, + tls_options = TLSOptions, + caller = open, client = From} + = State) -> + case ssl:connect(Socket, TLSOptions) of + {ok, TLSSocket} -> + gen_server:reply(From, {ok, self()}), + {noreply, State#state{csock = {ssl, TLSSocket}, + client = undefined, + caller = undefined }}; + {error, _} = Error -> + gen_server:reply(From, {Error, self()}), + {stop, normal, State#state{client = undefined, + caller = undefined}} + end; handle_ctrl_result({pos_compl, _}, #state{caller = open, client = From} = State) -> gen_server:reply(From, {ok, self()}), @@ -1601,10 +1654,10 @@ handle_ctrl_result({pos_compl, Lines}, timeout = Timeout} = State) -> [_, PortStr | _] = lists:reverse(string:tokens(Lines, "|")), - {ok, {IP, _}} = inet:peername(CSock), + {ok, {IP, _}} = peername(CSock), case connect(IP, list_to_integer(PortStr), Timeout, State) of {ok, _, Socket} -> - handle_caller(State#state{caller = Caller, dsock = Socket}); + handle_caller(State#state{caller = Caller, dsock = {tcp, Socket}}); {error, _Reason} = Error -> gen_server:reply(From, Error), {noreply, State#state{client = undefined, caller = undefined}} @@ -1669,18 +1722,18 @@ handle_ctrl_result({pos_compl, Lines}, %%-------------------------------------------------------------------------- %% Directory listing -handle_ctrl_result({pos_prel, _}, #state{caller = {dir, Dir}} = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - activate_data_connection(NewState), - {noreply, NewState#state{caller = {handle_dir_result, Dir}}}; +handle_ctrl_result({pos_prel, _}, #state{caller = {dir, Dir}} = State0) -> + case accept_data_connection(State0) of + {ok, State1} -> + State = activate_data_connection(State1), + {noreply, State#state{caller = {handle_dir_result, Dir}}}; {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; @@ -1778,18 +1831,18 @@ handle_ctrl_result({Status, _}, %%-------------------------------------------------------------------------- %% File handling - recv_bin -handle_ctrl_result({pos_prel, _}, #state{caller = recv_bin} = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - activate_data_connection(NewState), - {noreply, NewState}; +handle_ctrl_result({pos_prel, _}, #state{caller = recv_bin} = State0) -> + case accept_data_connection(State0) of + {ok, State1} -> + State = activate_data_connection(State1), + {noreply, State}; {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; @@ -1812,36 +1865,35 @@ handle_ctrl_result({Status, _}, #state{caller = {recv_bin, _}} = State) -> %% File handling - start_chunk_transfer handle_ctrl_result({pos_prel, _}, #state{client = From, caller = start_chunk_transfer} - = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - gen_server:reply(From, ok), - {noreply, NewState#state{chunk = true, client = undefined, - caller = undefined}}; + = State0) -> + case accept_data_connection(State0) of + {ok, State1} -> + State = start_chunk(State1), + {noreply, State}; {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; %%-------------------------------------------------------------------------- %% File handling - recv_file -handle_ctrl_result({pos_prel, _}, #state{caller = {recv_file, _}} = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - activate_data_connection(NewState), - {noreply, NewState}; +handle_ctrl_result({pos_prel, _}, #state{caller = {recv_file, _}} = State0) -> + case accept_data_connection(State0) of + {ok, State1} -> + State = activate_data_connection(State1), + {noreply, State}; {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; @@ -1853,36 +1905,32 @@ handle_ctrl_result({Status, _}, #state{caller = {recv_file, Fd}} = State) -> %%-------------------------------------------------------------------------- %% File handling - transfer_* handle_ctrl_result({pos_prel, _}, #state{caller = {transfer_file, Fd}} - = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - send_file(Fd, NewState); + = State0) -> + case accept_data_connection(State0) of + {ok, State1} -> + send_file(State1, Fd); {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; handle_ctrl_result({pos_prel, _}, #state{caller = {transfer_data, Bin}} - = State) -> - case accept_data_connection(State) of - {ok, NewState} -> - send_data_message(NewState, Bin), - close_data_connection(NewState), - activate_ctrl_connection(NewState), - {noreply, NewState#state{caller = transfer_data_second_phase, - dsock = undefined}}; + = State0) -> + case accept_data_connection(State0) of + {ok, State} -> + send_bin(State, Bin); {error, _Reason} = ERROR -> - case State#state.client of + case State0#state.client of undefined -> - {stop, ERROR, State}; + {stop, ERROR, State0}; From -> gen_server:reply(From, ERROR), - {stop, normal, State#state{client = undefined}} + {stop, normal, State0#state{client = undefined}} end end; @@ -1975,7 +2023,7 @@ setup_ctrl_connection(Host, Port, Timeout, State) -> MsTime = millisec_time(), case connect(Host, Port, Timeout, State) of {ok, IpFam, CSock} -> - NewState = State#state{csock = CSock, ipfamily = IpFam}, + NewState = State#state{csock = {tcp, CSock}, ipfamily = IpFam}, activate_ctrl_connection(NewState), case Timeout - (millisec_time() - MsTime) of Timeout2 when (Timeout2 >= 0) -> @@ -1991,12 +2039,12 @@ setup_ctrl_connection(Host, Port, Timeout, State) -> setup_data_connection(#state{mode = active, caller = Caller, csock = CSock} = State) -> - case (catch inet:sockname(CSock)) of + case (catch sockname(CSock)) of {ok, {{_, _, _, _, _, _, _, _} = IP, _}} -> {ok, LSock} = gen_tcp:listen(0, [{ip, IP}, {active, false}, inet6, binary, {packet, 0}]), - {ok, Port} = inet:port(LSock), + {ok, {_, Port}} = sockname(LSock), IpAddress = inet_parse:ntoa(IP), Cmd = mk_cmd("EPRT |2|~s|~p|", [IpAddress, Port]), send_ctrl_message(State, Cmd), @@ -2029,20 +2077,6 @@ setup_data_connection(#state{mode = passive, ipfamily = inet, activate_ctrl_connection(State), {noreply, State#state{caller = {setup_data_connection, Caller}}}. - -%% setup_data_connection(#state{mode = passive, ip_v6_disabled = false, -%% caller = Caller} = State) -> -%% send_ctrl_message(State, mk_cmd("EPSV", [])), -%% activate_ctrl_connection(State), -%% {noreply, State#state{caller = {setup_data_connection, Caller}}}; - -%% setup_data_connection(#state{mode = passive, ip_v6_disabled = true, -%% caller = Caller} = State) -> -%% send_ctrl_message(State, mk_cmd("PASV", [])), -%% activate_ctrl_connection(State), -%% {noreply, State#state{caller = {setup_data_connection, Caller}}}. - - connect(Host, Port, Timeout, #state{ipfamily = inet = IpFam}) -> connect2(Host, Port, IpFam, Timeout); @@ -2088,39 +2122,40 @@ connect2(Host, Port, IpFam, Timeout) -> accept_data_connection(#state{mode = active, dtimeout = DTimeout, - dsock = {lsock, LSock}} = State) -> + dsock = {lsock, LSock}} = State0) -> case gen_tcp:accept(LSock, DTimeout) of {ok, Socket} -> gen_tcp:close(LSock), - {ok, State#state{dsock = Socket}}; + maybe_requests_tls_upgrade(State0#state{dsock = {tcp, Socket}}); {error, Reason} -> {error, {data_connect_failed, Reason}} end; accept_data_connection(#state{mode = passive} = State) -> - {ok, State}. + maybe_requests_tls_upgrade(State). send_ctrl_message(#state{csock = Socket, verbose = Verbose}, Message) -> - %% io:format("send control message: ~n~p~n", [lists:flatten(Message)]), verbose(lists:flatten(Message),Verbose,send), send_message(Socket, Message). send_data_message(#state{dsock = Socket}, Message) -> - send_message(Socket, Message). - -send_message(Socket, Message) -> - case gen_tcp:send(Socket, Message) of + case send_message(Socket, Message) of ok -> ok; {error, Reason} -> - Report = io_lib:format("gen_tcp:send/2 failed for " - "reason ~p~n", [Reason]), + Report = io_lib:format("send/2 for socket ~p failed with " + "reason ~p~n", [Socket, Reason]), error_logger:error_report(Report), - %% If tcp does not work the only option is to terminate, + %% If tcp/ssl does not work the only option is to terminate, %% this is the expected behavior under these circumstances. exit(normal) %% User will get error message from terminate/2 end. +send_message({tcp, Socket}, Message) -> + gen_tcp:send(Socket, Message); +send_message({ssl, Socket}, Message) -> + ssl:send(Socket, Message). + activate_ctrl_connection(#state{csock = Socket, ctrl_data = {<<>>, _, _}}) -> activate_connection(Socket); activate_ctrl_connection(#state{csock = Socket}) -> @@ -2128,35 +2163,39 @@ activate_ctrl_connection(#state{csock = Socket}) -> %% that has been saved in ctrl_data, process this first. self() ! {tcp, Socket, <<>>}. -activate_data_connection(#state{dsock = Socket}) -> - activate_connection(Socket). - -activate_connection(Socket) -> - inet:setopts(Socket, [{active, once}]). +activate_data_connection(#state{tls_upgrading_data_connection = {false, _, _}, + dsock = Socket} = State) -> + activate_connection(Socket), + State; +activate_data_connection(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) -> + State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, activate_data_connection, undefined}}. +activate_connection({tcp, Socket}) -> + inet:setopts(Socket, [{active, once}]); +activate_connection({ssl, Socket}) -> + ssl:setopts(Socket, [{active, once}]). close_ctrl_connection(#state{csock = undefined}) -> ok; -close_ctrl_connection(#state{csock = Socket}) -> +close_ctrl_connection(#state{csock = {_, Socket}}) -> close_connection(Socket). close_data_connection(#state{dsock = undefined}) -> ok; -close_data_connection(#state{dsock = {lsock, Socket}}) -> - close_connection(Socket); -close_data_connection(#state{dsock = Socket}) -> +close_data_connection(#state{dsock = {_, Socket}}) -> close_connection(Socket). close_connection(Socket) -> gen_tcp:close(Socket). %% ------------ FILE HANDELING ---------------------------------------- - -send_file(Fd, State) -> +send_file(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Fd) -> + {noreply, State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, send_file, Fd}}}; +send_file(State, Fd) -> case file_read(Fd) of {ok, N, Bin} when N > 0-> send_data_message(State, Bin), progress_report({binary, Bin}, State), - send_file(Fd, State); + send_file(State, Fd); {ok, _, _} -> file_close(Fd), close_data_connection(State), @@ -2206,6 +2245,15 @@ call(GenServer, Msg, Format, Timeout) -> cast(GenServer, Msg) -> gen_server:cast(GenServer, {self(), Msg}). +send_bin(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Bin) -> + State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, send_bin, Bin}}; +send_bin(State, Bin) -> + send_data_message(State, Bin), + close_data_connection(State), + activate_ctrl_connection(State), + {noreply, State#state{caller = transfer_data_second_phase, + dsock = undefined}}. + mk_cmd(Fmt, Args) -> [io_lib:format(Fmt, Args)| [?CR, ?LF]]. % Deep list ok. @@ -2216,20 +2264,6 @@ pwd_result(Lines) -> lists:splitwith(fun(?DOUBLE_QUOTE) -> false; (_) -> true end, Rest), Dir. -%% is_verbose(Params) -> -%% check_param(verbose, Params). - -%% is_debug(Flags) -> -%% check_param(debug, Flags). - -%% is_trace(Flags) -> -%% check_param(trace, Flags). - -%% is_ipv6_disabled(Flags) -> -%% check_param(ip_v6_disabled, Flags). - -%% check_param(Param, Params) -> -%% lists:member(Param, Params). key_search(Key, List, Default) -> case lists:keysearch(Key, 1, List) of @@ -2239,14 +2273,6 @@ key_search(Key, List, Default) -> Default end. -%% check_option(Pred, Value, Default) -> -%% case Pred(Value) of -%% true -> -%% Value; -%% false -> -%% Default -%% end. - verbose(Lines, true, Direction) -> DirStr = case Direction of @@ -2276,3 +2302,37 @@ progress_report(Report, #state{progress = ProgressPid}) -> millisec_time() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). + +peername({tcp, Socket}) -> + inet:peername(Socket); +peername({ssl, Socket}) -> + ssl:peername(Socket). +sockname({tcp, Socket}) -> + inet:peername(Socket); +sockname({ssl, Socket}) -> + ssl:peername(Socket). + +maybe_tls_upgrade(Pid, undefined) -> + {ok, Pid}; +maybe_tls_upgrade(Pid, TLSOptions) -> + call(Pid, {open, tls_upgrade, TLSOptions}, plain). + +maybe_requests_tls_upgrade(#state{tls_options = [_|_]} = State) -> + send_ctrl_message(State, mk_cmd("PBSZ 0", [])), + activate_ctrl_connection(State), + {ok, State#state{tls_upgrading_data_connection = {true, pbsz, undefined}}}; +maybe_requests_tls_upgrade(#state{tls_options = undefined} = State) -> + {ok, State}. + +next_action_after_tls_upgrade({M, F, undefined}, State) -> + M:F(State); +next_action_after_tls_upgrade({M, F, A}, State) -> + M:F(State, A). + +start_chunk(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) -> + State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, start_chunk, undefined}}; +start_chunk(#state{client = From} = State) -> + gen_server:reply(From, ok), + State#state{chunk = true, + client = undefined, + caller = undefined}. diff --git a/lib/inets/src/ftp/ftp_response.erl b/lib/inets/src/ftp/ftp_response.erl index 4bf788e946..b0e8a2ef07 100644 --- a/lib/inets/src/ftp/ftp_response.erl +++ b/lib/inets/src/ftp/ftp_response.erl @@ -175,6 +175,7 @@ error_string(Reason) -> %% Positive Preleminary Reply interpret_status(?POS_PREL,_,_) -> pos_prel; +interpret_status(?POS_COMPL, ?AUTH_ACC, 3) -> tls_upgrade; %% Positive Completion Reply interpret_status(?POS_COMPL,_,_) -> pos_compl; %% Positive Intermediate Reply nedd account diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index 2f2f6ec16e..f08bb1a15e 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -150,6 +150,7 @@ INETS_ROOT = ../../inets MODULES = \ inets_test_lib \ erl_make_certs \ + old_ftp_SUITE \ ftp_SUITE \ ftp_format_SUITE \ ftp_solaris8_sparc_test \ diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl index 17e5f6777e..ed6730cf08 100644 --- a/lib/inets/test/ftp_SUITE.erl +++ b/lib/inets/test/ftp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -18,110 +18,88 @@ %% %% +%% +%% ct:run("../inets_test", ftp_SUITE). +%% + -module(ftp_SUITE). +-include_lib("kernel/include/file.hrl"). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). - -%% Test server specific exports --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). -% -export([init_per_testcase/2, end_per_testcase/2]). --export([init_per_suite/1, end_per_suite/1]). - --define(FTP_USER, "anonymous"). --define(FTP_PASS, passwd()). --define(FTP_PORT, 21). - --define(BAD_HOST, "badhostname"). --define(BAD_USER, "baduser"). --define(BAD_DIR, "baddirectory"). - --ifdef(ftp_debug_client). --define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)). --else. --ifdef(ftp_trace_client). --define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)). --else. --define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)). --endif. --endif. +-include("inets_test_lib.hrl"). +%% Note: This directive should only be used in test suites. +-compile(export_all). %%-------------------------------------------------------------------- -%% all(Arg) -> [Doc] | [Case] | {skip, Comment} -%% Arg - doc | suite -%% Doc - string() -%% Case - atom() -%% Name of a test case function. -%% Comment - string() -%% Description: Returns documentation/test cases in this test suite -%% or a skip tuple if the platform is not supported. +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- -suite() -> [{ct_hooks, [ts_install_cth]}]. +all() -> + [ + {group, ftp_passive}, + {group, ftp_active}, + {group, ftps_passive}, + {group, ftps_active} + ]. -all() -> +groups() -> [ - {group, solaris8_test}, - {group, solaris9_test}, - {group, solaris10_test}, - {group, linux_x86_test}, - {group, linux_ppc_test}, - {group, macosx_x86_test}, - {group, macosx_ppc_test}, - {group, openbsd_test}, - {group, freebsd_test}, - {group, netbsd_test}, - {group, windows_xp_test}, - {group, windows_2003_server_test}, - {group, ticket_tests} + {ftp_passive, [], ftp_tests()}, + {ftp_active, [], ftp_tests()}, + {ftps_passive, [], ftp_tests()}, + {ftps_active, [], ftp_tests()} ]. -groups() -> +ftp_tests()-> [ - {solaris8_test, [], [{ftp_solaris8_sparc_test, all}]}, - {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]}, - {solaris10_test, [], [{ftp_solaris10_sparc_test, all}, - {ftp_solaris10_x86_test, all}]}, - {linux_x86_test, [], [{ftp_linux_x86_test, all}]}, - {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]}, - {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]}, - {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]}, - {openbsd_test, [], [{ftp_openbsd_x86_test, all}]}, - {freebsd_test, [], [{ftp_freebsd_x86_test, all}]}, - {netbsd_test, [], [{ftp_netbsd_x86_test, all}]}, - {windows_xp_test, [], [{ftp_windows_xp_test, all}]}, - {windows_2003_server_test, [], [{ftp_windows_2003_server_test, all}]}, - {ticket_tests, [], [{ftp_ticket_test, all}]} + user, + pwd, + cd, + lcd, + ls, + nlist, + rename, + delete, + mkdir, + send, + send_bin, + send_chunk, + append, + append_bin, + append_chunk, + recv, + recv_bin, + recv_chunk, + type, + quote, + ip_v6_disabled ]. -init_per_group(_GroupName, Config) -> - Config. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. -end_per_group(_GroupName, Config) -> - Config. +%%-------------------------------------------------------------------- +init_per_group(_Group, Config) -> + Config. +end_per_group(_, _Config) -> + ok. +%%-------------------------------------------------------------------- +init_per_testcase(_Case, Config) -> + Config. +end_per_testcase(_Case, _Config) -> + ok. %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. +%% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- -init_per_suite(Config) -> - inets:start(), - Config. %%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite +%% Internal functions ----------------------------------------------- %%-------------------------------------------------------------------- -end_per_suite(_Config) -> - inets:stop(), - ok. diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel deleted file mode 100644 index 75096ce687..0000000000 --- a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel +++ /dev/null @@ -1,18 +0,0 @@ -%% Add a host name in the appropriate list -%% Each "platform" contains a list of hostnames (a string) that can -%% be used for testing the ftp client. -%% The definition below are an example!! -[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]}, - {solaris9_sparc, ["solaris9_sparc_dummy1"]}, - {solaris10_sparc, ["solaris10_sparc_dummy1"]}, - {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]}, - {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]}, - {linux_ppc, ["linux_ppc_dummy1"]}, - {macosx_ppc, ["macosx_ppc_dummy1"]}, - {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]}, - {openbsd_x86, []}, - {freebsd_x86, ["freebsd_x86_dummy1"]}, - {netbsd_x86, []}, - {windows_xp, []}, - {windows_2003_server, ["win2003_dummy1"]}, - {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}]. diff --git a/lib/inets/test/old_ftp_SUITE.erl b/lib/inets/test/old_ftp_SUITE.erl new file mode 100644 index 0000000000..81d8ca6282 --- /dev/null +++ b/lib/inets/test/old_ftp_SUITE.erl @@ -0,0 +1,127 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(old_ftp_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include("test_server_line.hrl"). + +%% Test server specific exports +-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). +% -export([init_per_testcase/2, end_per_testcase/2]). +-export([init_per_suite/1, end_per_suite/1]). + +-define(FTP_USER, "anonymous"). +-define(FTP_PASS, passwd()). +-define(FTP_PORT, 21). + +-define(BAD_HOST, "badhostname"). +-define(BAD_USER, "baduser"). +-define(BAD_DIR, "baddirectory"). + +-ifdef(ftp_debug_client). +-define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)). +-else. +-ifdef(ftp_trace_client). +-define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)). +-else. +-define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)). +-endif. +-endif. + + +%%-------------------------------------------------------------------- +%% all(Arg) -> [Doc] | [Case] | {skip, Comment} +%% Arg - doc | suite +%% Doc - string() +%% Case - atom() +%% Name of a test case function. +%% Comment - string() +%% Description: Returns documentation/test cases in this test suite +%% or a skip tuple if the platform is not supported. +%%-------------------------------------------------------------------- +suite() -> [{ct_hooks, [ts_install_cth]}]. + +all() -> + [ + {group, solaris8_test}, + {group, solaris9_test}, + {group, solaris10_test}, + {group, linux_x86_test}, + {group, linux_ppc_test}, + {group, macosx_x86_test}, + {group, macosx_ppc_test}, + {group, openbsd_test}, + {group, freebsd_test}, + {group, netbsd_test}, + {group, windows_xp_test}, + {group, windows_2003_server_test}, + {group, ticket_tests} + ]. + +groups() -> + [ + {solaris8_test, [], [{ftp_solaris8_sparc_test, all}]}, + {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]}, + {solaris10_test, [], [{ftp_solaris10_sparc_test, all}, + {ftp_solaris10_x86_test, all}]}, + {linux_x86_test, [], [{ftp_linux_x86_test, all}]}, + {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]}, + {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]}, + {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]}, + {openbsd_test, [], [{ftp_openbsd_x86_test, all}]}, + {freebsd_test, [], [{ftp_freebsd_x86_test, all}]}, + {netbsd_test, [], [{ftp_netbsd_x86_test, all}]}, + {windows_xp_test, [], [{ftp_windows_xp_test, all}]}, + {windows_2003_server_test, [], [{ftp_windows_2003_server_test, all}]}, + {ticket_tests, [], [{ftp_ticket_test, all}]} + ]. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + + + + +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initiation before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + inets:start(), + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + inets:stop(), + ok. diff --git a/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel new file mode 100644 index 0000000000..75096ce687 --- /dev/null +++ b/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel @@ -0,0 +1,18 @@ +%% Add a host name in the appropriate list +%% Each "platform" contains a list of hostnames (a string) that can +%% be used for testing the ftp client. +%% The definition below are an example!! +[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]}, + {solaris9_sparc, ["solaris9_sparc_dummy1"]}, + {solaris10_sparc, ["solaris10_sparc_dummy1"]}, + {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]}, + {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]}, + {linux_ppc, ["linux_ppc_dummy1"]}, + {macosx_ppc, ["macosx_ppc_dummy1"]}, + {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]}, + {openbsd_x86, []}, + {freebsd_x86, ["freebsd_x86_dummy1"]}, + {netbsd_x86, []}, + {windows_xp, []}, + {windows_2003_server, ["win2003_dummy1"]}, + {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}]. -- cgit v1.2.3 From 66164ddcf85071e469c86c0f11912b6a1e2c9c47 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 27 Sep 2013 16:04:45 +0200 Subject: ftp: Implement ftps (upgrade to TLS) --- lib/inets/test/ftp_SUITE_data/vsftpd.conf | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib/inets/test/ftp_SUITE_data/vsftpd.conf diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf new file mode 100644 index 0000000000..4763e439a4 --- /dev/null +++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf @@ -0,0 +1,9 @@ +listen=YES +listen_port=9999 +run_as_launching_user=YES +#ssl_enable=YES +#allow_anon_ssl=YES +background=YES +anonymous_enable=YES +#rsa_cert_file=cert.pem +#rsa_key_file=key.pem \ No newline at end of file -- cgit v1.2.3 From 0ec450535d350a8ccaf10cbe660d2c36c1ed85f0 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 8 Nov 2013 12:10:57 +0100 Subject: ftp: old ftp_SUITE re-written and works --- lib/inets/test/ftp_SUITE.erl | 726 +++++++++++++++++++++++++++++- lib/inets/test/ftp_SUITE_data/vsftpd.conf | 11 +- 2 files changed, 725 insertions(+), 12 deletions(-) diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl index ed6730cf08..fcee2eddde 100644 --- a/lib/inets/test/ftp_SUITE.erl +++ b/lib/inets/test/ftp_SUITE.erl @@ -31,6 +31,16 @@ %% Note: This directive should only be used in test suites. -compile(export_all). +-define(FTP_USER, "anonymous"). +-define(FTP_PASS, (fun({ok,__H}) -> "ftp_SUITE@" ++ __H; + (_) -> "ftp_SUITE@localhost" + end)(inet:gethostname()) + ). + +-define(BAD_HOST, "badhostname"). +-define(BAD_USER, "baduser"). +-define(BAD_DIR, "baddirectory"). + %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- @@ -52,7 +62,8 @@ groups() -> ftp_tests()-> [ - user, + user, + bad_user, pwd, cd, lcd, @@ -61,13 +72,16 @@ ftp_tests()-> rename, delete, mkdir, + rmdir, send, + send_3, send_bin, send_chunk, append, append_bin, append_chunk, recv, + recv_3, recv_bin, recv_chunk, type, @@ -76,30 +90,720 @@ ftp_tests()-> ]. %%-------------------------------------------------------------------- + +%%% Config +%%% key meaning +%%% ................................................................ +%%% ftpservers list of servers to check if they are available +%%% The element is: +%%% {Name, % string(). The os command name +%%% StartCommand, % fun()->{ok,start_result()} | {error,string()}. +%%% % The command to start the daemon with. +%%% ChkUp, % fun(start_result()) -> string(). Os command to check +%%% % if the server is running. [] if not running. +%%% % The string in string() is suitable for logging. +%%% StopCommand, % fun(start_result()) -> void(). The command to stop the daemon with. +%%% Host, % string(). Mostly "localhost" +%%% Port % pos_integer() +%%% } +%%% + +-define(default_ftp_servers, + [{"vsftpd", + fun(__CONF__) -> +%% make_config_file(vsftpd, Conf), + ConfFile = filename:join(?config(data_dir,__CONF__), "vsftpd.conf"), + AnonRoot = ?config(priv_dir,__CONF__), + Cmd = ["vsftpd \"",ConfFile,"\"", + " -oftpd_banner=erlang_otp_testing", + " -oanon_root=\"",AnonRoot,"\"" + ], + ct:log("~s",[Cmd]), + case os:cmd(Cmd) of + [] -> {ok,'dont care'}; + [Msg] -> {error,Msg} + end + end, + fun(_StartResult) -> os:cmd("ps ax | grep erlang_otp_testing | grep -v grep") + end, + fun(_StartResult) -> os:cmd("kill `ps ax | grep erlang_otp_testing | awk '/vsftpd/{print $1}'`") + end, + fun(__CONF__) -> + AnonRoot = ?config(priv_dir,__CONF__), + [{id2ftp, fun(Id) -> filename:join(AnonRoot,Id) end}, + {id2ftp_result,fun(Id) -> filename:join(AnonRoot,Id) end} | __CONF__] + end, + "localhost", + 9999 + } + ] + ). + + init_per_suite(Config) -> - Config. + case find_executable(Config) of + false -> + {skip, "No ftp server found"}; + {ok,Data} -> + TstDir = filename:join(?config(priv_dir,Config), "test"), + file:make_dir(TstDir), + start_ftpd([{test_dir,TstDir}, + {ftpd_data,Data} + | Config]) + end. -end_per_suite(_Config) -> +end_per_suite(Config) -> + ps_ftpd(Config), +%% stop_ftpd(Config), + ps_ftpd(Config), ok. %%-------------------------------------------------------------------- -init_per_group(_Group, Config) -> - Config. +init_per_group(_Group, Config) -> Config. + +end_per_group(_Group, Config) -> Config. + +%%-------------------------------------------------------------------- +init_per_testcase(Case, Config0) -> + Group = proplists:get_value(name,?config(tc_group_properties,Config0)), + try ?MODULE:Case(doc) of + Msg -> ct:comment(Msg) + catch + _:_-> ok + end, + Config = + case Group of + ftp_active -> ftp__open(Config0, [{mode,active}]); + ftps_active -> ftp__open(Config0, [{mode,active}]); + ftp_passive -> ftp__open(Config0, [{mode,passive}]); + ftps_passive -> ftp__open(Config0, [{mode,passive}]) + end, + case Case of + user -> Config; + bad_user -> Config; + _ -> + Pid = ?config(ftp,Config), + ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), + ok = ftp:cd(Pid, ?config(priv_dir,Config)), + Config + end. + + +end_per_testcase(user, _Config) -> ok; +end_per_testcase(bad_user, _Config) -> ok; +end_per_testcase(_Case, Config) -> ftp__close(Config). + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +user(doc) -> ["Open an ftp connection to a host, and logon as anonymous ftp, then logoff"]; +user(Config) -> + Pid = ?config(ftp, Config), + ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), % logon + ok = ftp:close(Pid), % logoff + {error,eclosed} = ftp:pwd(Pid), % check logoff result + ok. + +%%------------------------------------------------------------------------- +bad_user(doc) -> ["Open an ftp connection to a host, and logon with bad user."]; +bad_user(Config) -> + Pid = ?config(ftp, Config), + {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS), + ok. + +%%------------------------------------------------------------------------- +pwd(doc) -> ["Test ftp:pwd/1 & ftp:lpwd/1"]; +pwd(Config0) -> + Config = set_state([reset], Config0), + Pid = ?config(ftp, Config), + {ok, PWD} = ftp:pwd(Pid), + {ok, PathLpwd} = ftp:lpwd(Pid), + ct:log("PWD=~p~nPathLpwd=~p",[PWD,PathLpwd]), + PWD = id2ftp_result("", Config), + PathLpwd = id2ftp_result("", Config). + +%%------------------------------------------------------------------------- +cd(doc) -> ["Open an ftp connection, log on as anonymous ftp, and cd to a" + "directory and to a non-existent directory."]; +cd(Config0) -> + Dir = "test", + Config = set_state([reset,{mkdir,Dir}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:cd(Pid, id2ftp(Dir,Config)), + {ok, PWD} = ftp:pwd(Pid), + ExpectedPWD = id2ftp_result(Dir, Config), + ct:log("PWD=~p~nExpectedPWD=~p",[PWD,ExpectedPWD]), + PWD = ExpectedPWD, + {error, epath} = ftp:cd(Pid, ?BAD_DIR). + +%%------------------------------------------------------------------------- +lcd(doc) -> + ["Test api function ftp:lcd/2"]; +lcd(Config0) -> + Dir = "test", + Config = set_state([reset,{mkdir,Dir}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:lcd(Pid, id2ftp(Dir,Config)), + {ok, PWD} = ftp:lpwd(Pid), + ExpectedPWD = id2ftp_result(Dir, Config), + ct:log("PWD=~p~nExpectedPWD=~p",[PWD,ExpectedPWD]), + PWD = ExpectedPWD, + {error, epath} = ftp:lcd(Pid, ?BAD_DIR). + +%%------------------------------------------------------------------------- +ls(doc) -> ["Open an ftp connection; ls the current directory, and the " + "\"test\" directory. We assume that ls never fails, since " + "it's output is meant to be read by humans. "]; +ls(Config0) -> + Config = set_state([reset,{mkdir,"test"}], Config0), + Pid = ?config(ftp, Config), + {ok, _R1} = ftp:ls(Pid), + {ok, _R2} = ftp:ls(Pid, id2ftp("test",Config)), + %% neither nlist nor ls operates on a directory + %% they operate on a pathname, which *can* be a + %% directory, but can also be a filename or a group + %% of files (including wildcards). + case ?config(wildcard_support, Config) of + true -> + {ok, _R3} = ftp:ls(Pid, id2ftp("te*",Config)); + _ -> + ok + end. + +%%------------------------------------------------------------------------- +nlist(doc) -> ["Open an ftp connection; nlist the current directory, and the " + "\"test\" directory. Nlist does not behave consistenly over " + "operating systems. On some it is an error to have an empty " + "directory."]; +nlist(Config0) -> + Config = set_state([reset,{mkdir,"test"}], Config0), + Pid = ?config(ftp, Config), + {ok, _R1} = ftp:nlist(Pid), + {ok, _R2} = ftp:nlist(Pid, id2ftp("test",Config)), + %% neither nlist nor ls operates on a directory + %% they operate on a pathname, which *can* be a + %% directory, but can also be a filename or a group + %% of files (including wildcards). + case ?config(wildcard_support, Config) of + true -> + {ok, _R3} = ftp:nlist(Pid, id2ftp("te*",Config)); + _ -> + ok + end. + +%%------------------------------------------------------------------------- +rename(doc) -> ["Rename a file."]; +rename(Config0) -> + Contents = <<"ftp_SUITE test ...">>, + OldFile = "old.txt", + NewFile = "new.txt", + Config = set_state([reset,{mkfile,OldFile,Contents}], Config0), + Pid = ?config(ftp, Config), + + ok = ftp:rename(Pid, + id2ftp(OldFile,Config), + id2ftp(NewFile,Config)), + + true = (chk_file(NewFile,Contents,Config) + and chk_no_file([OldFile],Config)). -end_per_group(_, _Config) -> + +%%------------------------------------------------------------------------- +send(doc) -> ["Transfer a file with ftp using send/2."]; +send(Config0) -> + Contents = <<"ftp_SUITE test ...">>, + SrcDir = "data", + File = "file.txt", + Config = set_state([reset,{mkfile,[SrcDir,File],Contents}], Config0), + Pid = ?config(ftp, Config), + +chk_no_file([File],Config), +chk_file([SrcDir,File],Contents,Config), + + ok = ftp:lcd(Pid, id2ftp(SrcDir,Config)), + ok = ftp:cd(Pid, id2ftp("",Config)), + ok = ftp:send(Pid, File), + + chk_file(File, Contents, Config). + +%%------------------------------------------------------------------------- +send_3(doc) -> ["Transfer a file with ftp using send/3."]; +send_3(Config0) -> + Contents = <<"ftp_SUITE test ...">>, + Dir = "incoming", + File = "file.txt", + RemoteFile = "remfile.txt", + Config = set_state([reset,{mkfile,File,Contents},{mkdir,Dir}], Config0), + Pid = ?config(ftp, Config), + + ok = ftp:cd(Pid, id2ftp(Dir,Config)), + ok = ftp:lcd(Pid, id2ftp("",Config)), + ok = ftp:send(Pid, File, RemoteFile), + + chk_file([Dir,RemoteFile], Contents, Config). + +%%------------------------------------------------------------------------- +send_bin(doc) -> ["Send a binary."]; +send_bin(Config0) -> + BinContents = <<"ftp_SUITE test ...">>, + File = "file.txt", + Config = set_state([reset], Config0), + Pid = ?config(ftp, Config), + {error, enotbinary} = ftp:send_bin(Pid, "some string", id2ftp(File,Config)), + ok = ftp:send_bin(Pid, BinContents, id2ftp(File,Config)), + chk_file(File, BinContents, Config). + +%%------------------------------------------------------------------------- +send_chunk(doc) -> ["Send a binary using chunks."]; +send_chunk(Config0) -> + Contents = <<"ftp_SUITE test ...">>, + File = "file.txt", + Config = set_state([reset,{mkdir,"incoming"}], Config0), + Pid = ?config(ftp, Config), + + ok = ftp:send_chunk_start(Pid, id2ftp(File,Config)), + {error, echunk} = ftp:cd(Pid, "incoming"), + {error, enotbinary} = ftp:send_chunk(Pid, "some string"), + ok = ftp:send_chunk(Pid, Contents), + ok = ftp:send_chunk(Pid, Contents), + ok = ftp:send_chunk_end(Pid), + chk_file(File, <>, Config). + +%%------------------------------------------------------------------------- +delete(doc) -> ["Delete a file."]; +delete(Config0) -> + Contents = <<"ftp_SUITE test ...">>, + File = "file.txt", + Config = set_state([reset,{mkfile,File,Contents}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:delete(Pid, id2ftp(File,Config)), + chk_no_file([File], Config). + +%%------------------------------------------------------------------------- +mkdir(doc) -> ["Make a remote directory."]; +mkdir(Config0) -> + NewDir = "new_dir", + Config = set_state([reset], Config0), + Pid = ?config(ftp, Config), + ok = ftp:mkdir(Pid, id2ftp(NewDir,Config)), + chk_dir([NewDir], Config). + +%%------------------------------------------------------------------------- +rmdir(doc) -> ["Remove a directory."]; +rmdir(Config0) -> + Dir = "dir", + Config = set_state([reset,{mkdir,Dir}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:rmdir(Pid, id2ftp(Dir,Config)), + chk_no_dir([Dir], Config). + +%%------------------------------------------------------------------------- +append(doc) -> ["Append a local file twice to a remote file"]; +append(Config0) -> + SrcFile = "f_src.txt", + DstFile = "f_dst.txt", + Contents = <<"ftp_SUITE test ...">>, + Config = set_state([reset,{mkfile,SrcFile,Contents}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)), + ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)), + chk_file(DstFile, <>, Config). + +%%------------------------------------------------------------------------- +append_bin(doc) -> ["Append a local file twice to a remote file using append_bin"]; +append_bin(Config0) -> + DstFile = "f_dst.txt", + Contents = <<"ftp_SUITE test ...">>, + Config = set_state([reset], Config0), + Pid = ?config(ftp, Config), + ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)), + ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)), + chk_file(DstFile, <>, Config). + +%%------------------------------------------------------------------------- +append_chunk(doc) -> ["Append chunks."]; +append_chunk(Config0) -> + File = "f_dst.txt", + Contents = [<<"ER">>,<<"LE">>,<<"RL">>], + Config = set_state([reset], Config0), + Pid = ?config(ftp, Config), + ok = ftp:append_chunk_start(Pid, id2ftp(File,Config)), + {error, enotbinary} = ftp:append_chunk(Pid, binary_to_list(lists:nth(1,Contents))), + ok = ftp:append_chunk(Pid,lists:nth(1,Contents)), + ok = ftp:append_chunk(Pid,lists:nth(2,Contents)), + ok = ftp:append_chunk(Pid,lists:nth(3,Contents)), + ok = ftp:append_chunk_end(Pid), + chk_file(File, <<"ERLERL">>, Config). + +%%------------------------------------------------------------------------- +recv(doc) -> ["Receive a file using recv/2"]; +recv(Config0) -> + File = "f_dst.txt", + SrcDir = "a_dir", + Contents = <<"ftp_SUITE test ...">>, + Config = set_state([reset, {mkfile,[SrcDir,File],Contents}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:cd(Pid, id2ftp(SrcDir,Config)), + ok = ftp:lcd(Pid, id2ftp("",Config)), + ok = ftp:recv(Pid, File), + chk_file(File, Contents, Config). + +%%------------------------------------------------------------------------- +recv_3(doc) -> ["Receive a file using recv/3"]; +recv_3(Config0) -> + DstFile = "f_src.txt", + SrcFile = "f_dst.txt", + Contents = <<"ftp_SUITE test ...">>, + Config = set_state([reset, {mkfile,SrcFile,Contents}], Config0), + Pid = ?config(ftp, Config), + ok = ftp:cd(Pid, id2ftp("",Config)), + ok = ftp:recv(Pid, SrcFile, id2abs(DstFile,Config)), + chk_file(DstFile, Contents, Config). + +%%------------------------------------------------------------------------- +recv_bin(doc) -> ["Receive a file as a binary."]; +recv_bin(Config0) -> + File = "f_dst.txt", + Contents = <<"ftp_SUITE test ...">>, + Config = set_state([reset, {mkfile,File,Contents}], Config0), + Pid = ?config(ftp, Config), + {ok,Received} = ftp:recv_bin(Pid, id2ftp(File,Config)), + find_diff(Received, Contents). + +%%------------------------------------------------------------------------- +recv_chunk(doc) -> ["Receive a file using chunk-wise."]; +recv_chunk(Config0) -> + File = "big_file.txt", + Contents = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ), + Config = set_state([reset, {mkfile,File,Contents}], Config0), + Pid = ?config(ftp, Config), + {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), + ok = ftp:recv_chunk_start(Pid, id2ftp(File,Config)), + {ok, ReceivedContents, Nchunks} = recv_chunk(Pid, <<>>), + ct:log("Received ~p chunks",[Nchunks]), + find_diff(ReceivedContents, Contents). + +recv_chunk(Pid, Acc) -> recv_chunk(Pid, Acc, 0). + +recv_chunk(Pid, Acc, N) -> + case ftp:recv_chunk(Pid) of + ok -> {ok, Acc, N}; + {ok, Bin} -> recv_chunk(Pid, <>, N+1); + Error -> {Error, N} + end. + +%%------------------------------------------------------------------------- +type(doc) -> ["Test that we can change btween ASCCI and binary transfer mode"]; +type(Config) -> + Pid = ?config(ftp, Config), + ok = ftp:type(Pid, ascii), + ok = ftp:type(Pid, binary), + ok = ftp:type(Pid, ascii), + {error, etype} = ftp:type(Pid, foobar). + +%%------------------------------------------------------------------------- +quote(doc) -> [""]; +quote(Config) -> + Pid = ?config(ftp, Config), + ["257 \""++_Rest] = ftp:quote(Pid, "pwd"), %% 257 + [_| _] = ftp:quote(Pid, "help"), + %% This negativ test causes some ftp servers to hang. This test + %% is not important for the client, so we skip it for now. + %%["425 Can't build data connection: Connection refused."] + %% = ftp:quote(Pid, "list"), ok. + +%%------------------------------------------------------------------------- +ip_v6_disabled(doc) -> ["Test ipv4 command PORT"]; +ip_v6_disabled(_Config) -> + %%% FIXME!!!! What is this??? + ok.%% send(Config). + +%%------------------------------------------------------------------------- +%% big_one(doc) -> +%% ["Create a local file and transfer it to the remote host into the " +%% "the \"incoming\" directory, remove " +%% "the local file. Then open a new connection; cd to \"incoming\", " +%% "lcd to the private directory; receive the file; delete the " +%% "remote file; close connection; check that received file is in " +%% "the correct directory; cleanup." ]; +%% big_one(Config) -> +%% Pid = ?config(ftp, Config), +%% do_recv(Pid, Config). + +%% do_recv(Pid, Config) -> +%% PrivDir = ?config(priv_dir, Config), +%% File = ?config(file, Config), +%% Newfile = ?config(new_file, Config), +%% AbsFile = filename:absname(File, PrivDir), +%% Contents = "ftp_SUITE:recv test ...", +%% ok = file:write_file(AbsFile, list_to_binary(Contents)), +%% ok = ftp:cd(Pid, "incoming"), +%% ftp:delete(Pid, File), % reset +%% ftp:lcd(Pid, PrivDir), +%% ok = ftp:send(Pid, File), +%% ok = file:delete(AbsFile), % cleanup +%% test_server:sleep(100), +%% ok = ftp:lcd(Pid, PrivDir), +%% ok = ftp:recv(Pid, File), +%% {ok, Files} = file:list_dir(PrivDir), +%% true = lists:member(File, Files), +%% ok = file:delete(AbsFile), % cleanup +%% ok = ftp:recv(Pid, File, Newfile), +%% ok = ftp:delete(Pid, File), % cleanup +%% ok. + + +%%-------------------------------------------------------------------- +%% Internal functions ----------------------------------------------- +%%-------------------------------------------------------------------- + +chk_file(Path=[C|_], ExpectedContents, Config) when 0 + chk_file([Path], ExpectedContents, Config); + +chk_file(PathList, ExpectedContents, Config) -> + Path = filename:join(PathList), + AbsPath = id2abs(Path,Config), +ct:log("chk_file/3 dbg: PathList=~p, Path=~p~nAbsPath=~p",[PathList,Path,AbsPath]), + case file:read_file(AbsPath) of + {ok,ExpectedContents} -> + true; + {ok,ReadContents} -> + {error,{diff,Pos,RC,LC}} = find_diff(ReadContents, ExpectedContents, 1), + ct:log("Bad contents of ~p.~nGot:~n~p~nExpected:~n~p~nDiff at pos ~p ~nRead: ~p~nExp : ~p", + [AbsPath,ReadContents,ExpectedContents,Pos,RC,LC]), + ct:fail("Bad contents of ~p", [Path]); + {error,Error} -> + try begin + {ok,CWD} = file:get_cwd(), + ct:log("file:get_cwd()=~p~nfiles:~n~p",[CWD,file:list_dir(CWD)]) + end + of _ -> ok + catch _:_ ->ok + end, + ct:fail("Error reading ~p: ~p",[Path,Error]) + end. + + +chk_no_file(Path=[C|_], Config) when 0 + chk_no_file([Path], Config); + +chk_no_file(PathList, Config) -> + Path = filename:join(PathList), + AbsPath = id2abs(Path,Config), + case file:read_file(AbsPath) of + {error,enoent} -> + true; + {ok,Contents} -> + ct:log("File ~p exists although it shouldn't. Contents:~n~p", + [AbsPath,Contents]), + ct:fail("File exists: ~p", [Path]); + {error,Error} -> + ct:fail("Unexpected error reading ~p: ~p",[Path,Error]) + end. + + +chk_dir(Path=[C|_], Config) when 0 + chk_dir([Path], Config); + +chk_dir(PathList, Config) -> + Path = filename:join(PathList), + AbsPath = id2abs(Path,Config), + case file:read_file_info(AbsPath) of + {ok, #file_info{type=directory}} -> + true; + {ok, #file_info{type=Type}} -> + ct:fail("Expected dir ~p is a ~p",[Path,Type]); + {error,Error} -> + ct:fail("Expected dir ~p: ~p",[Path,Error]) + end. + +chk_no_dir(PathList, Config) -> + Path = filename:join(PathList), + AbsPath = id2abs(Path,Config), + case file:read_file_info(AbsPath) of + {error,enoent} -> + true; + {ok, #file_info{type=directory}} -> + ct:fail("Dir ~p erroneously exists",[Path]); + {ok, #file_info{type=Type}} -> + ct:fail("~p ~p erroneously exists",[Type,Path]); + {error,Error} -> + ct:fail("Unexpected error for ~p: ~p",[Path,Error]) + end. + + +%%-------------------------------------------------------------------- +%%-------------------------------------------------------------------- +%% find a suitable ftpd +%% +find_executable(Config) -> + FTPservers = case ?config(ftpservers,Config) of + undefined -> ?default_ftp_servers; + L -> L + end, + case lists:dropwhile(fun not_available/1, FTPservers) of + [] -> false; + [FTPD_data|_] -> {ok, FTPD_data} + end. + +not_available({Name,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}) -> + os:find_executable(Name) == false. + %%-------------------------------------------------------------------- -init_per_testcase(_Case, Config) -> +%% start/stop of ftpd +%% +start_ftpd(Config) -> + {Name,StartCmd,ChkUp,_StopCommand,ConfigRewrite,Host,Port} = ?config(ftpd_data, Config), + case StartCmd(Config) of + {ok,StartResult} -> + ct:log( ChkUp(StartResult) ), + [{ftpd_host,Host}, + {ftpd_port,Port}, + {ftpd_start_result,StartResult} | ConfigRewrite(Config)]; + {error,Msg} -> + {skip, [Name," not started: ",Msg]} + end. + +stop_ftpd(Config) -> + {_Name,_StartCmd,_ChkUp,StopCommand,_ConfigUpd,_Host,_Port} = ?config(ftpd_data, Config), + StopCommand(?config(ftpd_start_result,Config)). + +ps_ftpd(Config) -> + {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = ?config(ftpd_data, Config), + ct:log( ChkUp(?config(ftpd_start_result,Config)) ). + + +ftpd_running(Config) -> + {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = ?config(ftpd_data, Config), + ChkUp(?config(ftpd_start_result,Config)). + +%%-------------------------------------------------------------------- +%% start/stop of ftpc +%% +ftp__open(Config, Options) -> + Host = ?config(ftpd_host,Config), + Port = ?config(ftpd_port,Config), + ct:log("Host=~p, Port=~p",[Host,Port]), + {ok,Pid} = ftp:open(Host, [{port,Port} | Options]), + [{ftp,Pid}|Config]. + +ftp__close(Config) -> + ok = ftp:close(?config(ftp,Config)), Config. -end_per_testcase(_Case, _Config) -> - ok. +%%-------------------------------------------------------------------- +%% +split(Cs) -> string:tokens(Cs, "\r\n"). %%-------------------------------------------------------------------- -%% Test Cases -------------------------------------------------------- +%% +find_diff(Bin1, Bin2) -> + case find_diff(Bin1, Bin2, 1) of + {error, {diff,Pos,RC,LC}} -> + ct:log("Contents differ at position ~p.~nOp1: ~p~nOp2: ~p",[Pos,RC,LC]), + ct:fail("Contents differ at pos ~p",[Pos]); + Other -> + Other + end. + +find_diff(A, A, _) -> true; +find_diff(<>, <>, Pos) -> find_diff(T1, T2, Pos+1); +find_diff(RC, LC, Pos) -> {error, {diff, Pos, RC, LC}}. %%-------------------------------------------------------------------- +%% +make_config_file(vsftpd, Config) -> + ct:log("Config=~p",[Config]), + DstFileName = filename:join(?config(data_dir,Config), "vsftpd.conf"), + ct:log("DstFileName=~p",[DstFileName]), + SrcFileName = DstFileName ++ ".src", + ct:log("SrcFileName=~p",[SrcFileName]), + Chroot = ?config(priv_dir,Config), + ct:log("Chroot=~p",[Chroot]), + {ok,SrcContents} = file:read_file(SrcFileName), + ct:log("SrcContents=~p",[SrcContents]), + SFN = list_to_binary(SrcFileName), + CHR = list_to_binary(Chroot), + DstContents = + <<"## Generated, do not edit!\n", + "## Source: ",SFN/binary,"\n", + "\n", + "chroot_local_user=YES\n", + "passwd_chroot_enable=",CHR/binary,"\n", + "\n", + SrcContents/binary + >>, + ct:log("DstContents=~p",[DstContents]), + file:write_file(DstFileName, DstContents). + %%-------------------------------------------------------------------- -%% Internal functions ----------------------------------------------- +%% +set_state(Ops, Config) when is_list(Ops) -> lists:foldl(fun set_state/2, Config, Ops); + +set_state(reset, Config) -> + rm('*', id2abs("",Config)), + PrivDir = ?config(priv_dir,Config), + file:set_cwd(PrivDir), + ftp:lcd(?config(ftp,Config),PrivDir), + set_state({mkdir,""},Config); +set_state({mkdir,Id}, Config) -> + Abs = id2abs(Id, Config), + mk_path(Abs), + file:make_dir(Abs), + Config; +set_state({mkfile,Id,Contents}, Config) -> + Abs = id2abs(Id, Config), + mk_path(Abs), + ok = file:write_file(Abs, Contents), + Config. + +mk_path(Abs) -> lists:foldl(fun mk_path/2, [], filename:split(filename:dirname(Abs))). + +mk_path(F, Pfx) -> +io:format('~p~n',[filename:join(Pfx,F)]), + case file:read_file_info(AbsName=filename:join(Pfx,F)) of + {ok,#file_info{type=directory}} -> + AbsName; + {error,eexist} -> + AbsName; + {error,enoent} -> + ok = file:make_dir(AbsName), + AbsName + end. + + +rm('*', Pfx) -> + {ok,Fs} = file:list_dir(Pfx), + ct:log("Deleting ~p with prefix=~p",[Fs,Pfx]), + lists:foreach(fun(F) -> rm(F, Pfx) end, Fs); +rm(F, Pfx) -> + ct:log("rm ~p in ~p",[F,Pfx]), + case file:read_file_info(AbsName=filename:join(Pfx,F)) of + {ok,#file_info{type=directory}} -> + {ok,Fs} = file:list_dir(AbsName), + lists:foreach(fun(F1) -> rm(F1,AbsName) end, Fs), + ok = file:del_dir(AbsName); + + {ok,#file_info{type=regular}} -> + ok = file:delete(AbsName); + + {error,enoent} -> + ok + end. + %%-------------------------------------------------------------------- +%% + +id2abs(Id, Conf) -> filename:join(?config(priv_dir,Conf),ids(Id)). +id2ftp(Id, Conf) -> (?config(id2ftp,Conf))(ids(Id)). +id2ftp_result(Id, Conf) -> (?config(id2ftp_result,Conf))(ids(Id)). + +ids([[_|_]|_]=Ids) -> filename:join(Ids); +ids(Id) -> Id. + + +is_expected_absName(Id, File, Conf) -> File = (?config(id2abs,Conf))(Id). +is_expected_ftpInName(Id, File, Conf) -> File = (?config(id2ftp,Conf))(Id). +is_expected_ftpOutName(Id, File, Conf) -> File = (?config(id2ftp_result,Conf))(Id). diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf index 4763e439a4..a7b260282c 100644 --- a/lib/inets/test/ftp_SUITE_data/vsftpd.conf +++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf @@ -1,9 +1,18 @@ + listen=YES listen_port=9999 run_as_launching_user=YES #ssl_enable=YES #allow_anon_ssl=YES background=YES + +write_enable=YES anonymous_enable=YES +anon_upload_enable=YES +anon_mkdir_write_enable=YES +anon_other_write_enable=YES +anon_world_readable_only=NO + #rsa_cert_file=cert.pem -#rsa_key_file=key.pem \ No newline at end of file +#rsa_key_file=key.pem + -- cgit v1.2.3 From 3661fbde3b91b53fcdcf4db272407425647b9a45 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Nov 2013 15:35:37 +0100 Subject: ftp: towards a working ftps, chapter 1 --- lib/inets/src/ftp/ftp.erl | 53 +++++++++++++++++++++----------------- lib/inets/src/ftp/ftp_response.erl | 3 ++- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index f937402477..8576a60a23 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -54,7 +54,7 @@ -include("ftp_internal.hrl"). -%% Constante used in internal state definition +%% Constants used in internal state definition -define(CONNECTION_TIMEOUT, 60*1000). -define(DATA_ACCEPT_TIMEOUT, infinity). -define(DEFAULT_MODE, passive). @@ -92,7 +92,7 @@ ipfamily, % inet | inet6 | inet6fb4 progress = ignore, % ignore | pid() dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity - tls_upgrading_data_connection + tls_upgrading_data_connection = {false,undefined} }). @@ -1104,6 +1104,7 @@ handle_call({_, {open, ip_comm, Host, Opts}}, From, State) -> handle_call({_, {open, tls_upgrade, TLSOptions}}, From, State) -> send_ctrl_message(State, mk_cmd("AUTH TLS", [])), + activate_ctrl_connection(State), {noreply, State#state{client = From, caller = open, tls_options = TLSOptions}}; handle_call({_, {user, User, Password}}, From, @@ -1315,25 +1316,25 @@ handle_info(timeout, State) -> %%% Data socket messages %%% handle_info({tcp, Socket, Data}, - #state{dsock = Socket, + #state{dsock = {tcp,Socket}, caller = {recv_file, Fd}} = State0) -> file_write(binary_to_list(Data), Fd), progress_report({binary, Data}, State0), State = activate_data_connection(State0), {noreply, State}; -handle_info({tcp, Socket, Data}, #state{dsock = Socket, client = From, +handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}, client = From, caller = recv_chunk} = State) -> gen_server:reply(From, {ok, Data}), {noreply, State#state{client = undefined, data = <<>>}}; -handle_info({tcp, Socket, Data}, #state{dsock = Socket} = State0) -> +handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}} = State0) -> State = activate_data_connection(State0), {noreply, State#state{data = <<(State#state.data)/binary, Data/binary>>}}; -handle_info({tcp_closed, Socket}, #state{dsock = Socket, +handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, caller = {recv_file, Fd}} = State) -> file_close(Fd), @@ -1341,7 +1342,7 @@ handle_info({tcp_closed, Socket}, #state{dsock = Socket, activate_ctrl_connection(State), {noreply, State#state{dsock = undefined, data = <<>>}}; -handle_info({tcp_closed, Socket}, #state{dsock = Socket, client = From, +handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, client = From, caller = recv_chunk} = State) -> gen_server:reply(From, ok), @@ -1349,13 +1350,13 @@ handle_info({tcp_closed, Socket}, #state{dsock = Socket, client = From, data = <<>>, caller = undefined, chunk = false}}; -handle_info({tcp_closed, Socket}, #state{dsock = Socket, caller = recv_bin, +handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, caller = recv_bin, data = Data} = State) -> activate_ctrl_connection(State), {noreply, State#state{dsock = undefined, data = <<>>, caller = {recv_bin, Data}}}; -handle_info({tcp_closed, Socket}, #state{dsock = Socket, data = Data, +handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, data = Data, caller = {handle_dir_result, Dir}} = State) -> activate_ctrl_connection(State), @@ -1444,8 +1445,8 @@ handle_info({'EXIT', Pid, Reason}, #state{progress = Pid} = State) -> %% so we do not want to crash, but we make a log entry as it is an %% unwanted behaviour.) handle_info(Info, State) -> - Report = io_lib:format("ftp : ~p : Unexpected message: ~p\n", - [self(), Info]), + Report = io_lib:format("ftp : ~p : Unexpected message: ~p~nState: ~p~n", + [self(), Info, State]), error_logger:info_report(Report), {noreply, State}. @@ -1590,7 +1591,7 @@ handle_user_account(Acc, State) -> handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz, _}} = State) -> send_ctrl_message(State, mk_cmd("PROT P", [])), activate_ctrl_connection(State), - {noreply, State#state{tls_upgrading_data_connection = {true, prot}}}; + {noreply, State#state{tls_upgrading_data_connection = {true, prot, undefined}}}; handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot, NextAction}, dsock = {tcp, Socket}, client = From, @@ -1681,7 +1682,7 @@ handle_ctrl_result({pos_compl, Lines}, Port = (P1 * 256) + P2, case connect(IP, Port, Timeout, State) of {ok, _, Socket} -> - handle_caller(State#state{caller = Caller, dsock = Socket}); + handle_caller(State#state{caller = Caller, dsock = {tcp,Socket}}); {error, _Reason} = Error -> gen_server:reply(From, Error), {noreply,State#state{client = undefined, caller = undefined}} @@ -2152,7 +2153,7 @@ send_data_message(#state{dsock = Socket}, Message) -> end. send_message({tcp, Socket}, Message) -> - gen_tcp:send(Socket, Message); + gen_tcp:send(Socket, Message); send_message({ssl, Socket}, Message) -> ssl:send(Socket, Message). @@ -2163,12 +2164,13 @@ activate_ctrl_connection(#state{csock = Socket}) -> %% that has been saved in ctrl_data, process this first. self() ! {tcp, Socket, <<>>}. -activate_data_connection(#state{tls_upgrading_data_connection = {false, _, _}, +activate_data_connection(#state{tls_upgrading_data_connection = {false, _}, dsock = Socket} = State) -> activate_connection(Socket), State; activate_data_connection(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) -> - State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, activate_data_connection, undefined}}. + State#state{tls_upgrading_data_connection = {true, CTRL, {?MODULE,activate_data_connection,undefined}}}. + activate_connection({tcp, Socket}) -> inet:setopts(Socket, [{active, once}]); activate_connection({ssl, Socket}) -> @@ -2176,16 +2178,18 @@ activate_connection({ssl, Socket}) -> close_ctrl_connection(#state{csock = undefined}) -> ok; -close_ctrl_connection(#state{csock = {_, Socket}}) -> +close_ctrl_connection(#state{csock = Socket}) -> close_connection(Socket). close_data_connection(#state{dsock = undefined}) -> ok; -close_data_connection(#state{dsock = {_, Socket}}) -> +close_data_connection(#state{dsock = Socket}) -> close_connection(Socket). -close_connection(Socket) -> - gen_tcp:close(Socket). +close_connection({tcp, Socket}) -> + gen_tcp:close(Socket); +close_connection({ssl, Socket}) -> + ssl:close(Socket). %% ------------ FILE HANDELING ---------------------------------------- send_file(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Fd) -> @@ -2315,14 +2319,15 @@ sockname({ssl, Socket}) -> maybe_tls_upgrade(Pid, undefined) -> {ok, Pid}; maybe_tls_upgrade(Pid, TLSOptions) -> + catch ssl:start(), call(Pid, {open, tls_upgrade, TLSOptions}, plain). -maybe_requests_tls_upgrade(#state{tls_options = [_|_]} = State) -> +maybe_requests_tls_upgrade(#state{tls_options=undefined} = State) -> + {ok, State}; +maybe_requests_tls_upgrade(State) -> send_ctrl_message(State, mk_cmd("PBSZ 0", [])), activate_ctrl_connection(State), - {ok, State#state{tls_upgrading_data_connection = {true, pbsz, undefined}}}; -maybe_requests_tls_upgrade(#state{tls_options = undefined} = State) -> - {ok, State}. + {ok, State#state{tls_upgrading_data_connection = {true, pbsz, undefined}}}. next_action_after_tls_upgrade({M, F, undefined}, State) -> M:F(State); diff --git a/lib/inets/src/ftp/ftp_response.erl b/lib/inets/src/ftp/ftp_response.erl index b0e8a2ef07..dfe180ff18 100644 --- a/lib/inets/src/ftp/ftp_response.erl +++ b/lib/inets/src/ftp/ftp_response.erl @@ -175,7 +175,8 @@ error_string(Reason) -> %% Positive Preleminary Reply interpret_status(?POS_PREL,_,_) -> pos_prel; -interpret_status(?POS_COMPL, ?AUTH_ACC, 3) -> tls_upgrade; +%%FIXME ??? 3??? interpret_status(?POS_COMPL, ?AUTH_ACC, 3) -> tls_upgrade; +interpret_status(?POS_COMPL, ?AUTH_ACC, 4) -> tls_upgrade; %% Positive Completion Reply interpret_status(?POS_COMPL,_,_) -> pos_compl; %% Positive Intermediate Reply nedd account -- cgit v1.2.3 From 655c2a071feef2bfcc64f26ae7a752480da924ce Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Nov 2013 16:18:26 +0100 Subject: added some printouts --- lib/inets/src/ftp/ftp.erl | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 8576a60a23..46416bc98e 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -1318,6 +1318,7 @@ handle_info(timeout, State) -> handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}, caller = {recv_file, Fd}} = State0) -> + io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), file_write(binary_to_list(Data), Fd), progress_report({binary, Data}, State0), State = activate_data_connection(State0), @@ -1326,10 +1327,12 @@ handle_info({tcp, Socket, Data}, handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}, client = From, caller = recv_chunk} = State) -> + io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State]), gen_server:reply(From, {ok, Data}), {noreply, State#state{client = undefined, data = <<>>}}; handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}} = State0) -> + io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), State = activate_data_connection(State0), {noreply, State#state{data = <<(State#state.data)/binary, Data/binary>>}}; @@ -1380,6 +1383,7 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, ctrl_data = {CtrlData, AccLines, LineStatus}} = State) -> + io:format('--ctrl ~p ----> ~s~p~n',[Socket,<>,State]), case ftp_response:parse_lines(<>, AccLines, LineStatus) of {ok, Lines, NextMsgData} -> @@ -1393,11 +1397,13 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, ctrl_data = {NextMsgData, [], start}}}; _ -> + io:format(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]), handle_ctrl_result(CtrlResult, State#state{ctrl_data = {NextMsgData, [], start}}) end; {continue, NewCtrlData} -> + io:format(' ...Continue... ctrl_data=~p~n',[NewCtrlData]), activate_ctrl_connection(State), {noreply, State#state{ctrl_data = NewCtrlData}} end; @@ -1596,21 +1602,23 @@ handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot, NextAction}, dsock = {tcp, Socket}, client = From, tls_options = TLSOptions} = State0) -> - case ssl:connect(Socket, TLSOptions) of - {ok, TLSSocket} -> - State = State0#state{dsock = {ssl, TLSSocket}, - tls_upgrading_data_connection = {false, undefined}}, - next_action_after_tls_upgrade(NextAction, State); - {error, _} = Error -> - gen_server:reply(From, {Error, self()}), - {stop, normal, State0#state{client = undefined, + io:format('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), + case ssl:connect(Socket, TLSOptions) of + {ok, TLSSocket} -> + State = State0#state{dsock = {ssl, TLSSocket}, + tls_upgrading_data_connection = {false, undefined}}, + next_action_after_tls_upgrade(NextAction, State); + {error, _} = Error -> + gen_server:reply(From, {Error, self()}), + {stop, normal, State0#state{client = undefined, caller = undefined}} - end; + end; handle_ctrl_result({tls_upgrade, _}, #state{csock = {tcp, Socket}, tls_options = TLSOptions, caller = open, client = From} = State) -> + io:format('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]), case ssl:connect(Socket, TLSOptions) of {ok, TLSSocket} -> gen_server:reply(From, {ok, self()}), @@ -2135,11 +2143,13 @@ accept_data_connection(#state{mode = active, accept_data_connection(#state{mode = passive} = State) -> maybe_requests_tls_upgrade(State). -send_ctrl_message(#state{csock = Socket, verbose = Verbose}, Message) -> +send_ctrl_message(S=#state{csock = Socket, verbose = Verbose}, Message) -> verbose(lists:flatten(Message),Verbose,send), + io:format('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]), send_message(Socket, Message). -send_data_message(#state{dsock = Socket}, Message) -> +send_data_message(S=#state{dsock = Socket}, Message) -> + io:format('<==data ~p ==== ~s~p~n',[Socket,Message,S]), case send_message(Socket, Message) of ok -> ok; -- cgit v1.2.3 From 3d0277ef3839b1f17769151b889f4f83ef2586d2 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Nov 2013 20:17:43 +0100 Subject: . --- lib/inets/src/ftp/ftp.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 46416bc98e..98f4276eeb 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -1688,6 +1688,7 @@ handle_ctrl_result({pos_compl, Lines}, string:tokens(NewPortAddr, [$,])), IP = {A1, A2, A3, A4}, Port = (P1 * 256) + P2, +io:format('tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]), case connect(IP, Port, Timeout, State) of {ok, _, Socket} -> handle_caller(State#state{caller = Caller, dsock = {tcp,Socket}}); -- cgit v1.2.3 From 9e1030ef6e80e101b0e572e3746ab84dde244a01 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Nov 2013 10:39:39 +0100 Subject: ftps: working --- lib/inets/src/ftp/ftp.erl | 218 +++++++++++++++--------------- lib/inets/test/ftp_SUITE.erl | 49 ++++--- lib/inets/test/ftp_SUITE_data/vsftpd.conf | 10 +- 3 files changed, 146 insertions(+), 131 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 98f4276eeb..df2ee7d201 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -18,7 +18,7 @@ %% %% %% Description: This module implements an ftp client, RFC 959. -%% It also supports ipv6 RFC 2428. +%% It also supports ipv6 RFC 2428 and starttls RFC 4217. -module(ftp). @@ -92,7 +92,7 @@ ipfamily, % inet | inet6 | inet6fb4 progress = ignore, % ignore | pid() dtimeout = ?DATA_ACCEPT_TIMEOUT, % non_neg_integer() | infinity - tls_upgrading_data_connection = {false,undefined} + tls_upgrading_data_connection = false }). @@ -101,6 +101,8 @@ -type common_reason() :: 'econn' | 'eclosed' | term(). -type file_write_error_reason() :: term(). % See file:write for more info +%%-define(DBG(F,A), 'n/a'). +-define(DBG(F,A), io:format(F,A)). %%%========================================================================= %%% API - CLIENT FUNCTIONS @@ -1315,61 +1317,63 @@ handle_info(timeout, State) -> {noreply, State}; %%% Data socket messages %%% -handle_info({tcp, Socket, Data}, - #state{dsock = {tcp,Socket}, - caller = {recv_file, Fd}} = State0) -> - io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), +handle_info({Trpt, Socket, Data}, + #state{dsock = {Trpt,Socket}, + caller = {recv_file, Fd}} = State0) when Trpt==tcp;Trpt==ssl -> + ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), file_write(binary_to_list(Data), Fd), progress_report({binary, Data}, State0), State = activate_data_connection(State0), {noreply, State}; -handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}, client = From, +handle_info({Trpt, Socket, Data}, #state{dsock = {Trpt,Socket}, client = From, caller = recv_chunk} - = State) -> - io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State]), + = State) when Trpt==tcp;Trpt==ssl -> + ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State]), gen_server:reply(From, {ok, Data}), {noreply, State#state{client = undefined, data = <<>>}}; -handle_info({tcp, Socket, Data}, #state{dsock = {tcp,Socket}} = State0) -> - io:format('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), +handle_info({Trpt, Socket, Data}, #state{dsock = {Trpt,Socket}} = State0) when Trpt==tcp;Trpt==ssl -> + ?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]), State = activate_data_connection(State0), {noreply, State#state{data = <<(State#state.data)/binary, Data/binary>>}}; -handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, +handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = {recv_file, Fd}} - = State) -> + = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} -> file_close(Fd), progress_report({transfer_size, 0}, State), activate_ctrl_connection(State), {noreply, State#state{dsock = undefined, data = <<>>}}; -handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, client = From, +handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, client = From, caller = recv_chunk} - = State) -> + = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} -> gen_server:reply(From, ok), {noreply, State#state{dsock = undefined, client = undefined, data = <<>>, caller = undefined, chunk = false}}; -handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, caller = recv_bin, - data = Data} = State) -> +handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = recv_bin, + data = Data} = State) + when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} -> activate_ctrl_connection(State), {noreply, State#state{dsock = undefined, data = <<>>, caller = {recv_bin, Data}}}; -handle_info({tcp_closed, Socket}, #state{dsock = {tcp,Socket}, data = Data, +handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, data = Data, caller = {handle_dir_result, Dir}} - = State) -> + = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} -> activate_ctrl_connection(State), {noreply, State#state{dsock = undefined, caller = {handle_dir_result, Dir, Data}, % data = <>}}; data = <<>>}}; - -handle_info({tcp_error, Socket, Reason}, #state{dsock = Socket, - client = From} = State) -> + +handle_info({Err, Socket, Reason}, #state{dsock = {Trpt,Socket}, + client = From} = State) + when {Err,Trpt}=={tcp_error,tcp} ; {Err,Trpt}=={ssl_error,ssl} -> gen_server:reply(From, {error, Reason}), close_data_connection(State), {noreply, State#state{dsock = undefined, client = undefined, @@ -1383,7 +1387,7 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, ctrl_data = {CtrlData, AccLines, LineStatus}} = State) -> - io:format('--ctrl ~p ----> ~s~p~n',[Socket,<>,State]), + ?DBG('--ctrl ~p ----> ~s~p~n',[Socket,<>,State]), case ftp_response:parse_lines(<>, AccLines, LineStatus) of {ok, Lines, NextMsgData} -> @@ -1397,34 +1401,31 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, ctrl_data = {NextMsgData, [], start}}}; _ -> - io:format(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]), + ?DBG(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]), handle_ctrl_result(CtrlResult, State#state{ctrl_data = {NextMsgData, [], start}}) end; {continue, NewCtrlData} -> - io:format(' ...Continue... ctrl_data=~p~n',[NewCtrlData]), + ?DBG(' ...Continue... ctrl_data=~p~n',[NewCtrlData]), activate_ctrl_connection(State), {noreply, State#state{ctrl_data = NewCtrlData}} end; %% If the server closes the control channel it is %% the expected behavior that connection process terminates. -handle_info({tcp_closed, Socket}, #state{csock = {tcp, Socket}}) -> +handle_info({Cls, Socket}, #state{csock = {Trpt, Socket}}) + when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} -> exit(normal); %% User will get error message from terminate/2 -handle_info({ssl_closed, Socket}, #state{csock = {ssl, Socket}}) -> - exit(normal); -handle_info({tcp_error, Socket, Reason}, _) -> +handle_info({Err, Socket, Reason}, _) when Err==tcp_error ; Err==ssl_error -> Report = - io_lib:format("tcp_error on socket: ~p for reason: ~p~n", - [Socket, Reason]), + io_lib:format("~p on socket: ~p for reason: ~p~n", + [Err, Socket, Reason]), error_logger:error_report(Report), %% If tcp does not work the only option is to terminate, %% this is the expected behavior under these circumstances. exit(normal); %% User will get error message from terminate/2 -handle_info({ssl_error, _Socket, _Reason}, _) -> - exit(normal); %% TODO?? %% Monitor messages - if the process owning the ftp connection goes %% down there is no point in continuing. @@ -1592,44 +1593,36 @@ handle_user_account(Acc, State) -> %%-------------------------------------------------------------------------- %% handle_ctrl_result %%-------------------------------------------------------------------------- -%%-------------------------------------------------------------------------- -%% Handling of control connection setup -handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz, _}} = State) -> - send_ctrl_message(State, mk_cmd("PROT P", [])), - activate_ctrl_connection(State), - {noreply, State#state{tls_upgrading_data_connection = {true, prot, undefined}}}; - -handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot, NextAction}, - dsock = {tcp, Socket}, client = From, - tls_options = TLSOptions} = State0) -> - io:format('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), - case ssl:connect(Socket, TLSOptions) of - {ok, TLSSocket} -> - State = State0#state{dsock = {ssl, TLSSocket}, - tls_upgrading_data_connection = {false, undefined}}, - next_action_after_tls_upgrade(NextAction, State); - {error, _} = Error -> - gen_server:reply(From, {Error, self()}), - {stop, normal, State0#state{client = undefined, - caller = undefined}} - end; - handle_ctrl_result({tls_upgrade, _}, #state{csock = {tcp, Socket}, tls_options = TLSOptions, caller = open, client = From} - = State) -> - io:format('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]), + = State0) -> + ?DBG('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), case ssl:connect(Socket, TLSOptions) of {ok, TLSSocket} -> - gen_server:reply(From, {ok, self()}), - {noreply, State#state{csock = {ssl, TLSSocket}, - client = undefined, - caller = undefined }}; + State = State0#state{csock = {ssl,TLSSocket}}, + send_ctrl_message(State, mk_cmd("PBSZ 0", [])), + activate_ctrl_connection(State), + {noreply, State#state{tls_upgrading_data_connection = {true, pbsz}} }; {error, _} = Error -> gen_server:reply(From, {Error, self()}), - {stop, normal, State#state{client = undefined, - caller = undefined}} + {stop, normal, State0#state{client = undefined, + caller = undefined, + tls_upgrading_data_connection = false}} end; + +handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, pbsz}} = State) -> + send_ctrl_message(State, mk_cmd("PROT P", [])), + activate_ctrl_connection(State), + {noreply, State#state{tls_upgrading_data_connection = {true, prot}}}; + +handle_ctrl_result({pos_compl, _}, #state{tls_upgrading_data_connection = {true, prot}, + client = From} = State) -> + gen_server:reply(From, {ok, self()}), + {noreply, State#state{client = undefined, + caller = undefined, + tls_upgrading_data_connection = false}}; + handle_ctrl_result({pos_compl, _}, #state{caller = open, client = From} = State) -> gen_server:reply(From, {ok, self()}), @@ -1676,7 +1669,7 @@ handle_ctrl_result({pos_compl, Lines}, #state{mode = passive, ipfamily = inet, client = From, - caller = {setup_data_connection, Caller}, + caller = {setup_data_connection, Caller}, timeout = Timeout} = State) -> {_, [?LEFT_PAREN | Rest]} = @@ -1688,9 +1681,10 @@ handle_ctrl_result({pos_compl, Lines}, string:tokens(NewPortAddr, [$,])), IP = {A1, A2, A3, A4}, Port = (P1 * 256) + P2, -io:format('tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]), + + ?DBG('<--data tcp connect to ~p:~p, Caller=~p~n',[IP,Port,Caller]), case connect(IP, Port, Timeout, State) of - {ok, _, Socket} -> + {ok, _, Socket} -> handle_caller(State#state{caller = Caller, dsock = {tcp,Socket}}); {error, _Reason} = Error -> gen_server:reply(From, Error), @@ -2132,25 +2126,46 @@ connect2(Host, Port, IpFam, Timeout) -> accept_data_connection(#state{mode = active, dtimeout = DTimeout, + tls_options = TLSOptions, dsock = {lsock, LSock}} = State0) -> case gen_tcp:accept(LSock, DTimeout) of + {ok, Socket} when is_list(TLSOptions) -> + gen_tcp:close(LSock), + ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), + case ssl:connect(Socket, TLSOptions) of + {ok, TLSSocket} -> + {ok, State0#state{dsock={ssl,TLSSocket}}}; + {error, Reason} -> + {error, {ssl_connect_failed, Reason}} + end; {ok, Socket} -> gen_tcp:close(LSock), - maybe_requests_tls_upgrade(State0#state{dsock = {tcp, Socket}}); + {ok, State0#state{dsock={tcp,Socket}}}; {error, Reason} -> {error, {data_connect_failed, Reason}} end; +accept_data_connection(#state{mode = passive, + dsock = {tcp,Socket}, + tls_options = TLSOptions} = State) when is_list(TLSOptions) -> + ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]), + case ssl:connect(Socket, TLSOptions) of + {ok, TLSSocket} -> + {ok, State#state{dsock={ssl,TLSSocket}}}; + {error, Reason} -> + {error, {ssl_connect_failed, Reason}} + end; accept_data_connection(#state{mode = passive} = State) -> - maybe_requests_tls_upgrade(State). + {ok,State}. + send_ctrl_message(S=#state{csock = Socket, verbose = Verbose}, Message) -> verbose(lists:flatten(Message),Verbose,send), - io:format('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]), + ?DBG('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]), send_message(Socket, Message). send_data_message(S=#state{dsock = Socket}, Message) -> - io:format('<==data ~p ==== ~s~p~n',[Socket,Message,S]), + ?DBG('<==data ~p ==== ~s~p~n',[Socket,Message,S]), case send_message(Socket, Message) of ok -> ok; @@ -2173,34 +2188,28 @@ activate_ctrl_connection(#state{csock = Socket, ctrl_data = {<<>>, _, _}}) -> activate_ctrl_connection(#state{csock = Socket}) -> %% We have already received at least part of the next control message, %% that has been saved in ctrl_data, process this first. - self() ! {tcp, Socket, <<>>}. + self() ! {tcp, unwrap_socket(Socket), <<>>}. -activate_data_connection(#state{tls_upgrading_data_connection = {false, _}, - dsock = Socket} = State) -> +unwrap_socket({tcp,Socket}) -> Socket; +unwrap_socket({ssl,Socket}) -> Socket; +unwrap_socket(Socket) -> Socket. + + +activate_data_connection(#state{dsock = Socket} = State) -> activate_connection(Socket), - State; -activate_data_connection(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) -> - State#state{tls_upgrading_data_connection = {true, CTRL, {?MODULE,activate_data_connection,undefined}}}. + State. -activate_connection({tcp, Socket}) -> - inet:setopts(Socket, [{active, once}]); -activate_connection({ssl, Socket}) -> - ssl:setopts(Socket, [{active, once}]). +activate_connection({tcp, Socket}) -> inet:setopts(Socket, [{active, once}]); +activate_connection({ssl, Socket}) -> ssl:setopts(Socket, [{active, once}]). -close_ctrl_connection(#state{csock = undefined}) -> - ok; -close_ctrl_connection(#state{csock = Socket}) -> - close_connection(Socket). +close_ctrl_connection(#state{csock = undefined}) -> ok; +close_ctrl_connection(#state{csock = Socket}) -> close_connection(Socket). -close_data_connection(#state{dsock = undefined}) -> - ok; -close_data_connection(#state{dsock = Socket}) -> - close_connection(Socket). +close_data_connection(#state{dsock = undefined}) -> ok; +close_data_connection(#state{dsock = Socket}) -> close_connection(Socket). -close_connection({tcp, Socket}) -> - gen_tcp:close(Socket); -close_connection({ssl, Socket}) -> - ssl:close(Socket). +close_connection({tcp, Socket}) -> gen_tcp:close(Socket); +close_connection({ssl, Socket}) -> ssl:close(Socket). %% ------------ FILE HANDELING ---------------------------------------- send_file(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Fd) -> @@ -2318,14 +2327,11 @@ millisec_time() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). -peername({tcp, Socket}) -> - inet:peername(Socket); -peername({ssl, Socket}) -> - ssl:peername(Socket). -sockname({tcp, Socket}) -> - inet:peername(Socket); -sockname({ssl, Socket}) -> - ssl:peername(Socket). +peername({tcp, Socket}) -> inet:peername(Socket); +peername({ssl, Socket}) -> ssl:peername(Socket). + +sockname({tcp, Socket}) -> inet:peername(Socket); +sockname({ssl, Socket}) -> ssl:peername(Socket). maybe_tls_upgrade(Pid, undefined) -> {ok, Pid}; @@ -2333,18 +2339,6 @@ maybe_tls_upgrade(Pid, TLSOptions) -> catch ssl:start(), call(Pid, {open, tls_upgrade, TLSOptions}, plain). -maybe_requests_tls_upgrade(#state{tls_options=undefined} = State) -> - {ok, State}; -maybe_requests_tls_upgrade(State) -> - send_ctrl_message(State, mk_cmd("PBSZ 0", [])), - activate_ctrl_connection(State), - {ok, State#state{tls_upgrading_data_connection = {true, pbsz, undefined}}}. - -next_action_after_tls_upgrade({M, F, undefined}, State) -> - M:F(State); -next_action_after_tls_upgrade({M, F, A}, State) -> - M:F(State, A). - start_chunk(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State) -> State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, start_chunk, undefined}}; start_chunk(#state{client = From} = State) -> diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl index fcee2eddde..dea147fb56 100644 --- a/lib/inets/test/ftp_SUITE.erl +++ b/lib/inets/test/ftp_SUITE.erl @@ -32,15 +32,18 @@ -compile(export_all). -define(FTP_USER, "anonymous"). --define(FTP_PASS, (fun({ok,__H}) -> "ftp_SUITE@" ++ __H; - (_) -> "ftp_SUITE@localhost" - end)(inet:gethostname()) +-define(FTP_PASS(Cmnt), (fun({ok,__H}) -> "ftp_SUITE_"++Cmnt++"@" ++ __H; + (_) -> "ftp_SUITE_"++Cmnt++"@localhost" + end)(inet:gethostname()) ). -define(BAD_HOST, "badhostname"). -define(BAD_USER, "baduser"). -define(BAD_DIR, "baddirectory"). +go() -> ct:run_test([{suite,"ftp_SUITE"}, {logdir,"LOG"}]). +gos() -> ct:run_test([{suite,"ftp_SUITE"}, {group,ftps_passive}, {logdir,"LOG"}]). + %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- @@ -112,14 +115,24 @@ ftp_tests()-> [{"vsftpd", fun(__CONF__) -> %% make_config_file(vsftpd, Conf), - ConfFile = filename:join(?config(data_dir,__CONF__), "vsftpd.conf"), + DataDir = ?config(data_dir,__CONF__), + ConfFile = filename:join(DataDir, "vsftpd.conf"), AnonRoot = ?config(priv_dir,__CONF__), - Cmd = ["vsftpd \"",ConfFile,"\"", + Cmd = ["vsftpd "++filename:join(DataDir,"vsftpd.conf"), " -oftpd_banner=erlang_otp_testing", - " -oanon_root=\"",AnonRoot,"\"" + " -oanon_root=\"",AnonRoot,"\"", + " -orsa_cert_file=\"",filename:join(DataDir,"cert.pem"),"\"", + " -orsa_private_key_file=\"",filename:join(DataDir,"key.pem"),"\"" ], - ct:log("~s",[Cmd]), - case os:cmd(Cmd) of + Result = os:cmd(Cmd), + ct:log("Config file:~n~s~n~nServer start command:~n ~s~nResult:~n ~p", + [case file:read_file(ConfFile) of + {ok,X} -> X; + _ -> "" + end, + Cmd, Result + ]), + case Result of [] -> {ok,'dont care'}; [Msg] -> {error,Msg} end @@ -154,7 +167,7 @@ init_per_suite(Config) -> end_per_suite(Config) -> ps_ftpd(Config), -%% stop_ftpd(Config), + stop_ftpd(Config), ps_ftpd(Config), ok. @@ -171,19 +184,23 @@ init_per_testcase(Case, Config0) -> catch _:_-> ok end, + TLS = [{tls,[{reuse_sessions,true}]}], + ACTIVE = [{mode,active}], + PASSIVE = [{mode,passive}], + ExtraOpts = [verbose], Config = case Group of - ftp_active -> ftp__open(Config0, [{mode,active}]); - ftps_active -> ftp__open(Config0, [{mode,active}]); - ftp_passive -> ftp__open(Config0, [{mode,passive}]); - ftps_passive -> ftp__open(Config0, [{mode,passive}]) + ftp_active -> ftp__open(Config0, ACTIVE ++ExtraOpts); + ftps_active -> ftp__open(Config0, TLS++ ACTIVE ++ExtraOpts); + ftp_passive -> ftp__open(Config0, PASSIVE ++ExtraOpts); + ftps_passive -> ftp__open(Config0, TLS++PASSIVE ++ExtraOpts) end, case Case of user -> Config; bad_user -> Config; _ -> Pid = ?config(ftp,Config), - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), + ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS(atom_to_list(Group)++"-"++atom_to_list(Case)) ), ok = ftp:cd(Pid, ?config(priv_dir,Config)), Config end. @@ -199,7 +216,7 @@ end_per_testcase(_Case, Config) -> ftp__close(Config). user(doc) -> ["Open an ftp connection to a host, and logon as anonymous ftp, then logoff"]; user(Config) -> Pid = ?config(ftp, Config), - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), % logon + ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS("")),% logon ok = ftp:close(Pid), % logoff {error,eclosed} = ftp:pwd(Pid), % check logoff result ok. @@ -208,7 +225,7 @@ user(Config) -> bad_user(doc) -> ["Open an ftp connection to a host, and logon with bad user."]; bad_user(Config) -> Pid = ?config(ftp, Config), - {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS), + {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS("")), ok. %%------------------------------------------------------------------------- diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf index a7b260282c..4133f8f3b1 100644 --- a/lib/inets/test/ftp_SUITE_data/vsftpd.conf +++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf @@ -2,8 +2,10 @@ listen=YES listen_port=9999 run_as_launching_user=YES -#ssl_enable=YES -#allow_anon_ssl=YES +ssl_enable=YES +allow_anon_ssl=YES + +#background=NO background=YES write_enable=YES @@ -14,5 +16,7 @@ anon_other_write_enable=YES anon_world_readable_only=NO #rsa_cert_file=cert.pem -#rsa_key_file=key.pem +#rsa_private_key_file exists, not rsa_key_file=key.pem +### Shouldn't be necessary.... +require_ssl_reuse=NO -- cgit v1.2.3 From 27a95df2f4caba1f0666e2154b2f27da8f674db2 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Nov 2013 14:24:00 +0100 Subject: ftp: Add timeouts to ssl:connect --- lib/inets/src/ftp/ftp.erl | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index df2ee7d201..bfb4b27b45 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -101,8 +101,8 @@ -type common_reason() :: 'econn' | 'eclosed' | term(). -type file_write_error_reason() :: term(). % See file:write for more info -%%-define(DBG(F,A), 'n/a'). --define(DBG(F,A), io:format(F,A)). +-define(DBG(F,A), 'n/a'). +%%-define(DBG(F,A), io:format(F,A)). %%%========================================================================= %%% API - CLIENT FUNCTIONS @@ -1595,10 +1595,11 @@ handle_user_account(Acc, State) -> %%-------------------------------------------------------------------------- handle_ctrl_result({tls_upgrade, _}, #state{csock = {tcp, Socket}, tls_options = TLSOptions, + timeout = Timeout, caller = open, client = From} = State0) -> ?DBG('<--ctrl ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), - case ssl:connect(Socket, TLSOptions) of + case ssl:connect(Socket, TLSOptions, Timeout) of {ok, TLSSocket} -> State = State0#state{csock = {ssl,TLSSocket}}, send_ctrl_message(State, mk_cmd("PBSZ 0", [])), @@ -2132,7 +2133,7 @@ accept_data_connection(#state{mode = active, {ok, Socket} when is_list(TLSOptions) -> gen_tcp:close(LSock), ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State0]), - case ssl:connect(Socket, TLSOptions) of + case ssl:connect(Socket, TLSOptions, DTimeout) of {ok, TLSSocket} -> {ok, State0#state{dsock={ssl,TLSSocket}}}; {error, Reason} -> @@ -2146,10 +2147,11 @@ accept_data_connection(#state{mode = active, end; accept_data_connection(#state{mode = passive, + dtimeout = DTimeout, dsock = {tcp,Socket}, tls_options = TLSOptions} = State) when is_list(TLSOptions) -> ?DBG('<--data ssl:connect(~p, ~p)~n~p~n',[Socket,TLSOptions,State]), - case ssl:connect(Socket, TLSOptions) of + case ssl:connect(Socket, TLSOptions, DTimeout) of {ok, TLSSocket} -> {ok, State#state{dsock={ssl,TLSSocket}}}; {error, Reason} -> @@ -2159,13 +2161,13 @@ accept_data_connection(#state{mode = passive} = State) -> {ok,State}. -send_ctrl_message(S=#state{csock = Socket, verbose = Verbose}, Message) -> +send_ctrl_message(_S=#state{csock = Socket, verbose = Verbose}, Message) -> verbose(lists:flatten(Message),Verbose,send), - ?DBG('<--ctrl ~p ---- ~s~p~n',[Socket,Message,S]), + ?DBG('<--ctrl ~p ---- ~s~p~n',[Socket,Message,_S]), send_message(Socket, Message). -send_data_message(S=#state{dsock = Socket}, Message) -> - ?DBG('<==data ~p ==== ~s~p~n',[Socket,Message,S]), +send_data_message(_S=#state{dsock = Socket}, Message) -> + ?DBG('<==data ~p ==== ~s~p~n',[Socket,Message,_S]), case send_message(Socket, Message) of ok -> ok; -- cgit v1.2.3 From 787dfe7cdec35d43f5f88311b60b6288e39e7ffb Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 13 Nov 2013 15:05:50 +0100 Subject: ftp: Add ftps documentation --- lib/inets/doc/src/ftp.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml index f8f11ec705..ac14d3f274 100644 --- a/lib/inets/doc/src/ftp.xml +++ b/lib/inets/doc/src/ftp.xml @@ -547,15 +547,14 @@ Opts = options() options() = [option()] option() = start_option() | open_option() - start_option() = {verbose, verbose()} | {debug, debug()} verbose() = boolean() (defaults to false) debug() = disable | debug | trace (defaults to disable) - - open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {timeout, timeout()} | {dtimeout, dtimeout()} | {progress, progress()} + open_option() = {ipfamily, ipfamily()} | {port, port()} | {mode, mode()} | {tls, tls_options()} | {timeout, timeout()} | {dtimeout, dtimeout()} | {progress, progress()} ipfamily() = inet | inet6 | inet6fb4 (defaults to inet) port() = integer() > 0 (defaults to 21) mode() = active | passive (defaults to passive) + tls_options() = [ssl:ssloption()] timeout() = integer() > 0 (defaults to 60000 milliseconds) dtimeout() = integer() > 0 | infinity (defaults to infinity) pogress() = ignore | {module(), function(), initial_data()} (defaults to ignore) @@ -570,6 +569,9 @@ (without the inets service framework) and open a session with the FTP server at Host.

+

If the option {tls, tls_options()} is present, the ftp session will be transported over tls (ftps, see RFC 4217). The list tls_options() may be empty. The function ssl:connect/3 is used for establishing both the control connection and the data sessions. +

+

A session opened in this way, is closed using the close function.

-- cgit v1.2.3 From 5a5c226e35ff3475b9ed0480809d019a135e2532 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 18 Nov 2013 16:37:54 +0100 Subject: ftp: small fixes --- lib/inets/src/ftp/ftp.erl | 27 +++++++++++++++++---- lib/inets/test/ftp_SUITE.erl | 56 +++++++++++++------------------------------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index bfb4b27b45..86ef9280ad 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -39,7 +39,8 @@ send_chunk_start/2, send_chunk/2, send_chunk_end/1, type/2, user/3, user/4, account/2, append/3, append/2, append_bin/3, - append_chunk/2, append_chunk_end/1, append_chunk_start/2, info/1]). + append_chunk/2, append_chunk_end/1, append_chunk_start/2, + info/1, latest_ctrl_response/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, @@ -84,6 +85,7 @@ %% and hence the end of the response is reached! ctrl_data = {<<>>, [], start}, % {binary(), [bytes()], LineStatus} %% pid() - Client pid (note not the same as "From") + latest_ctrl_response = "", owner = undefined, client = undefined, % "From" to be used in gen_server:reply/2 %% Function that activated a connection and maybe some @@ -753,6 +755,18 @@ info(Pid) -> call(Pid, info, list). +%%-------------------------------------------------------------------------- +%% latest_ctrl_response(Pid) -> string() +%% Pid = pid() +%% +%% Description: The latest received response from the server +%%-------------------------------------------------------------------------- + +-spec latest_ctrl_response(Pid :: pid()) -> string(). + +latest_ctrl_response(Pid) -> + call(Pid, latest_ctrl_response, string). + %%%======================================================================== %%% Behavior callbacks %%%======================================================================== @@ -1046,6 +1060,9 @@ handle_call({_, info}, _, #state{verbose = Verbose, {progress, Progress}], {reply, {ok, Options}, State}; +handle_call({_,latest_ctrl_response}, _, #state{latest_ctrl_response=Resp} = State) -> + {reply, {ok,Resp}, State}; + %% But everything else must come from the owner handle_call({Pid, _}, _, #state{owner = Owner} = State) when Owner =/= Pid -> {reply, {error, not_connection_owner}, State}; @@ -1398,13 +1415,15 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket}, gen_server:reply(From, string:tokens(Lines, [?CR, ?LF])), {noreply, State#state{client = undefined, caller = undefined, + latest_ctrl_response = Lines, ctrl_data = {NextMsgData, [], start}}}; _ -> ?DBG(' ...handle_ctrl_result(~p,...) ctrl_data=~p~n',[CtrlResult,{NextMsgData, [], start}]), handle_ctrl_result(CtrlResult, - State#state{ctrl_data = - {NextMsgData, [], start}}) + State#state{latest_ctrl_response = Lines, + ctrl_data = + {NextMsgData, [], start}}) end; {continue, NewCtrlData} -> ?DBG(' ...Continue... ctrl_data=~p~n',[NewCtrlData]), @@ -2167,7 +2186,7 @@ send_ctrl_message(_S=#state{csock = Socket, verbose = Verbose}, Message) -> send_message(Socket, Message). send_data_message(_S=#state{dsock = Socket}, Message) -> - ?DBG('<==data ~p ==== ~s~p~n',[Socket,Message,_S]), + ?DBG('<==data ~p ==== ~s~n~p~n',[Socket,Message,_S]), case send_message(Socket, Message) of ok -> ok; diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl index dea147fb56..28adcf822b 100644 --- a/lib/inets/test/ftp_SUITE.erl +++ b/lib/inets/test/ftp_SUITE.erl @@ -106,15 +106,16 @@ ftp_tests()-> %%% % if the server is running. [] if not running. %%% % The string in string() is suitable for logging. %%% StopCommand, % fun(start_result()) -> void(). The command to stop the daemon with. -%%% Host, % string(). Mostly "localhost" -%%% Port % pos_integer() +%%% AugmentFun, % fun(config()) -> config() Adds two funs for transforming names of files +%%% % and directories to the form they are returned from this server +%%% ServerHost, % string(). Mostly "localhost" +%%% ServerPort % pos_integer() %%% } %%% -define(default_ftp_servers, [{"vsftpd", fun(__CONF__) -> -%% make_config_file(vsftpd, Conf), DataDir = ?config(data_dir,__CONF__), ConfFile = filename:join(DataDir, "vsftpd.conf"), AnonRoot = ?config(priv_dir,__CONF__), @@ -208,7 +209,18 @@ init_per_testcase(Case, Config0) -> end_per_testcase(user, _Config) -> ok; end_per_testcase(bad_user, _Config) -> ok; -end_per_testcase(_Case, Config) -> ftp__close(Config). +end_per_testcase(_Case, Config) -> + case ?config(tc_status,Config) of + ok -> ok; + _ -> + try ftp:latest_ctrl_response(?config(ftp,Config)) + of + {ok,S} -> ct:log("***~n*** Latest ctrl channel response:~n*** ~p~n***",[S]) + catch + _:_ -> ok + end + end, + ftp__close(Config). %%-------------------------------------------------------------------- %% Test Cases -------------------------------------------------------- @@ -235,7 +247,6 @@ pwd(Config0) -> Pid = ?config(ftp, Config), {ok, PWD} = ftp:pwd(Pid), {ok, PathLpwd} = ftp:lpwd(Pid), - ct:log("PWD=~p~nPathLpwd=~p",[PWD,PathLpwd]), PWD = id2ftp_result("", Config), PathLpwd = id2ftp_result("", Config). @@ -249,7 +260,6 @@ cd(Config0) -> ok = ftp:cd(Pid, id2ftp(Dir,Config)), {ok, PWD} = ftp:pwd(Pid), ExpectedPWD = id2ftp_result(Dir, Config), - ct:log("PWD=~p~nExpectedPWD=~p",[PWD,ExpectedPWD]), PWD = ExpectedPWD, {error, epath} = ftp:cd(Pid, ?BAD_DIR). @@ -263,7 +273,6 @@ lcd(Config0) -> ok = ftp:lcd(Pid, id2ftp(Dir,Config)), {ok, PWD} = ftp:lpwd(Pid), ExpectedPWD = id2ftp_result(Dir, Config), - ct:log("PWD=~p~nExpectedPWD=~p",[PWD,ExpectedPWD]), PWD = ExpectedPWD, {error, epath} = ftp:lcd(Pid, ?BAD_DIR). @@ -497,7 +506,6 @@ recv_chunk(Config0) -> {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), ok = ftp:recv_chunk_start(Pid, id2ftp(File,Config)), {ok, ReceivedContents, Nchunks} = recv_chunk(Pid, <<>>), - ct:log("Received ~p chunks",[Nchunks]), find_diff(ReceivedContents, Contents). recv_chunk(Pid, Acc) -> recv_chunk(Pid, Acc, 0). @@ -582,7 +590,6 @@ chk_file(Path=[C|_], ExpectedContents, Config) when 0 chk_file(PathList, ExpectedContents, Config) -> Path = filename:join(PathList), AbsPath = id2abs(Path,Config), -ct:log("chk_file/3 dbg: PathList=~p, Path=~p~nAbsPath=~p",[PathList,Path,AbsPath]), case file:read_file(AbsPath) of {ok,ExpectedContents} -> true; @@ -675,7 +682,6 @@ start_ftpd(Config) -> {Name,StartCmd,ChkUp,_StopCommand,ConfigRewrite,Host,Port} = ?config(ftpd_data, Config), case StartCmd(Config) of {ok,StartResult} -> - ct:log( ChkUp(StartResult) ), [{ftpd_host,Host}, {ftpd_port,Port}, {ftpd_start_result,StartResult} | ConfigRewrite(Config)]; @@ -728,33 +734,6 @@ find_diff(Bin1, Bin2) -> find_diff(A, A, _) -> true; find_diff(<>, <>, Pos) -> find_diff(T1, T2, Pos+1); find_diff(RC, LC, Pos) -> {error, {diff, Pos, RC, LC}}. -%%-------------------------------------------------------------------- -%% -make_config_file(vsftpd, Config) -> - ct:log("Config=~p",[Config]), - DstFileName = filename:join(?config(data_dir,Config), "vsftpd.conf"), - ct:log("DstFileName=~p",[DstFileName]), - SrcFileName = DstFileName ++ ".src", - ct:log("SrcFileName=~p",[SrcFileName]), - Chroot = ?config(priv_dir,Config), - ct:log("Chroot=~p",[Chroot]), - {ok,SrcContents} = file:read_file(SrcFileName), - ct:log("SrcContents=~p",[SrcContents]), - SFN = list_to_binary(SrcFileName), - CHR = list_to_binary(Chroot), - DstContents = - <<"## Generated, do not edit!\n", - "## Source: ",SFN/binary,"\n", - "\n", - "chroot_local_user=YES\n", - "passwd_chroot_enable=",CHR/binary,"\n", - "\n", - SrcContents/binary - >>, - ct:log("DstContents=~p",[DstContents]), - file:write_file(DstFileName, DstContents). - - %%-------------------------------------------------------------------- %% set_state(Ops, Config) when is_list(Ops) -> lists:foldl(fun set_state/2, Config, Ops); @@ -779,7 +758,6 @@ set_state({mkfile,Id,Contents}, Config) -> mk_path(Abs) -> lists:foldl(fun mk_path/2, [], filename:split(filename:dirname(Abs))). mk_path(F, Pfx) -> -io:format('~p~n',[filename:join(Pfx,F)]), case file:read_file_info(AbsName=filename:join(Pfx,F)) of {ok,#file_info{type=directory}} -> AbsName; @@ -793,10 +771,8 @@ io:format('~p~n',[filename:join(Pfx,F)]), rm('*', Pfx) -> {ok,Fs} = file:list_dir(Pfx), - ct:log("Deleting ~p with prefix=~p",[Fs,Pfx]), lists:foreach(fun(F) -> rm(F, Pfx) end, Fs); rm(F, Pfx) -> - ct:log("rm ~p in ~p",[F,Pfx]), case file:read_file_info(AbsName=filename:join(Pfx,F)) of {ok,#file_info{type=directory}} -> {ok,Fs} = file:list_dir(AbsName), -- cgit v1.2.3 From 4fe71f9ca157dceffee16d5f3d70fad088cb5790 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 09:56:40 +0100 Subject: ftp: delete old test files --- lib/inets/test/ftp_freebsd_x86_test.erl | 160 -- lib/inets/test/ftp_linux_ppc_test.erl | 158 -- lib/inets/test/ftp_linux_x86_test.erl | 160 -- lib/inets/test/ftp_macosx_ppc_test.erl | 159 -- lib/inets/test/ftp_macosx_x86_test.erl | 159 -- lib/inets/test/ftp_netbsd_x86_test.erl | 159 -- lib/inets/test/ftp_openbsd_x86_test.erl | 158 -- lib/inets/test/ftp_solaris10_sparc_test.erl | 161 -- lib/inets/test/ftp_solaris10_x86_test.erl | 162 -- lib/inets/test/ftp_solaris8_sparc_test.erl | 159 -- lib/inets/test/ftp_solaris9_sparc_test.erl | 158 -- lib/inets/test/ftp_suite_lib.erl | 1675 --------------------- lib/inets/test/ftp_ticket_test.erl | 61 - lib/inets/test/ftp_windows_2003_server_test.erl | 167 -- lib/inets/test/ftp_windows_xp_test.erl | 157 -- lib/inets/test/old_ftp_SUITE.erl | 127 -- lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel | 18 - 17 files changed, 3958 deletions(-) delete mode 100644 lib/inets/test/ftp_freebsd_x86_test.erl delete mode 100644 lib/inets/test/ftp_linux_ppc_test.erl delete mode 100644 lib/inets/test/ftp_linux_x86_test.erl delete mode 100644 lib/inets/test/ftp_macosx_ppc_test.erl delete mode 100644 lib/inets/test/ftp_macosx_x86_test.erl delete mode 100644 lib/inets/test/ftp_netbsd_x86_test.erl delete mode 100644 lib/inets/test/ftp_openbsd_x86_test.erl delete mode 100644 lib/inets/test/ftp_solaris10_sparc_test.erl delete mode 100644 lib/inets/test/ftp_solaris10_x86_test.erl delete mode 100644 lib/inets/test/ftp_solaris8_sparc_test.erl delete mode 100644 lib/inets/test/ftp_solaris9_sparc_test.erl delete mode 100644 lib/inets/test/ftp_suite_lib.erl delete mode 100644 lib/inets/test/ftp_ticket_test.erl delete mode 100644 lib/inets/test/ftp_windows_2003_server_test.erl delete mode 100644 lib/inets/test/ftp_windows_xp_test.erl delete mode 100644 lib/inets/test/old_ftp_SUITE.erl delete mode 100644 lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel diff --git a/lib/inets/test/ftp_freebsd_x86_test.erl b/lib/inets/test/ftp_freebsd_x86_test.erl deleted file mode 100644 index 1d66779882..0000000000 --- a/lib/inets/test/ftp_freebsd_x86_test.erl +++ /dev/null @@ -1,160 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_freebsd_x86_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Freebsd x86 "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(freebsd_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_linux_ppc_test.erl b/lib/inets/test/ftp_linux_ppc_test.erl deleted file mode 100644 index bba97237f1..0000000000 --- a/lib/inets/test/ftp_linux_ppc_test.erl +++ /dev/null @@ -1,158 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_linux_ppc_test). - -%% Note: This directive should only be used in test suites. --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Linux ppc "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(linux_ppc, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). diff --git a/lib/inets/test/ftp_linux_x86_test.erl b/lib/inets/test/ftp_linux_x86_test.erl deleted file mode 100644 index bbefd8231e..0000000000 --- a/lib/inets/test/ftp_linux_x86_test.erl +++ /dev/null @@ -1,160 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_linux_x86_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Linux x86 "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(linux_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_macosx_ppc_test.erl b/lib/inets/test/ftp_macosx_ppc_test.erl deleted file mode 100644 index c9f33b8beb..0000000000 --- a/lib/inets/test/ftp_macosx_ppc_test.erl +++ /dev/null @@ -1,159 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_macosx_ppc_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Macosx ppc "). - - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(macosx_ppc, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> -[open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%%?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl deleted file mode 100644 index 17b7160b95..0000000000 --- a/lib/inets/test/ftp_macosx_x86_test.erl +++ /dev/null @@ -1,159 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_macosx_x86_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Macosx x86 "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(macosx_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> -[open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist([{wildcard_support, false} | X]). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist([{wildcard_support, false} | X]). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_netbsd_x86_test.erl b/lib/inets/test/ftp_netbsd_x86_test.erl deleted file mode 100644 index bb474852c5..0000000000 --- a/lib/inets/test/ftp_netbsd_x86_test.erl +++ /dev/null @@ -1,159 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_netbsd_x86_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Netbsd x86 "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(netbsd_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_openbsd_x86_test.erl b/lib/inets/test/ftp_openbsd_x86_test.erl deleted file mode 100644 index 54fce702a0..0000000000 --- a/lib/inets/test/ftp_openbsd_x86_test.erl +++ /dev/null @@ -1,158 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_openbsd_x86_test). - -%% Note: This directive should only be used in test suites. --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Openbsd x86 "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(openbsd_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). diff --git a/lib/inets/test/ftp_solaris10_sparc_test.erl b/lib/inets/test/ftp_solaris10_sparc_test.erl deleted file mode 100644 index 0da50dc91b..0000000000 --- a/lib/inets/test/ftp_solaris10_sparc_test.erl +++ /dev/null @@ -1,161 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_solaris10_sparc_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Solaris 10 sparc "). - - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(solaris10_sparc, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_solaris10_x86_test.erl b/lib/inets/test/ftp_solaris10_x86_test.erl deleted file mode 100644 index 3e7045bb4d..0000000000 --- a/lib/inets/test/ftp_solaris10_x86_test.erl +++ /dev/null @@ -1,162 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_solaris10_x86_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD, ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_), ?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM, "Solaris 10 x86 "). - - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(solaris10_x86, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. -%%-------------------------------------------------------------------- - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_solaris8_sparc_test.erl b/lib/inets/test/ftp_solaris8_sparc_test.erl deleted file mode 100644 index 23dbfc8fe3..0000000000 --- a/lib/inets/test/ftp_solaris8_sparc_test.erl +++ /dev/null @@ -1,159 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_solaris8_sparc_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Solaris 8 sparc "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(solaris8_sparc, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_solaris9_sparc_test.erl b/lib/inets/test/ftp_solaris9_sparc_test.erl deleted file mode 100644 index 896e2f497f..0000000000 --- a/lib/inets/test/ftp_solaris9_sparc_test.erl +++ /dev/null @@ -1,158 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_solaris9_sparc_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Solaris 9 sparc "). -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(solaris9_sparc, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl deleted file mode 100644 index 35f21cc74d..0000000000 --- a/lib/inets/test/ftp_suite_lib.erl +++ /dev/null @@ -1,1675 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_suite_lib). - - --include_lib("test_server/include/test_server.hrl"). --include_lib("test_server/include/test_server_line.hrl"). --include("inets_test_lib.hrl"). - -%% Test server specific exports -% -export([init_per_testcase/2, end_per_testcase/2]). - --compile(export_all). - - --record(progress, { - current = 0, - total - }). - - - --define(FTP_USER, "anonymous"). --define(FTP_PASS, passwd()). --define(FTP_PORT, 21). - --define(BAD_HOST, "badhostname"). --define(BAD_USER, "baduser"). --define(BAD_DIR, "baddirectory"). - --ifdef(ftp_debug_client). --define(ftp_open(Host, Flags), - do_ftp_open(Host, [{debug, debug}, - {timeout, timer:seconds(15)} | Flags])). --else. --ifdef(ftp_trace_client). --define(ftp_open(Host, Flags), - do_ftp_open(Host, [{debug, trace}, - {timeout, timer:seconds(15)} | Flags])). --else. --define(ftp_open(Host, Flags), - do_ftp_open(Host, [{verbose, true}, - {timeout, timer:seconds(15)} | Flags])). --endif. --endif. - -%% -- Tickets -- - -tickets(doc) -> - "Test cases for reported bugs"; -tickets(suite) -> - [ticket_6035]. - -%% -- - -ftpd_init(FtpdTag, Config) -> - %% Get the host name(s) of FTP server - Hosts = - case ct:get_config(ftpd_hosts) of - undefined -> - ftpd_hosts(data_dir(Config)); - H -> - H - end, - p("ftpd_init -> " - "~n Hosts: ~p" - "~n Config: ~p" - "~n FtpdTag: ~p", [Hosts, Config, FtpdTag]), - %% Get the first host that actually have a running FTP server - case lists:keysearch(FtpdTag, 1, Hosts) of - {value, {_, TagHosts}} when is_list(TagHosts) -> - inets:start(), - case (catch get_ftpd_host(TagHosts)) of - {ok, Host} -> - inets:stop(), - [{ftp_remote_host, Host}|Config]; - _ -> - inets:stop(), - Reason = lists:flatten( - io_lib:format("Could not find a valid " - "FTP server for ~p (~p)", - [FtpdTag, TagHosts])), - {skip, Reason} - end; - _ -> - Reason = lists:flatten( - io_lib:format("No host(s) running FTPD server " - "for ~p", [FtpdTag])), - {skip, Reason} - end. - -ftpd_fin(Config) -> - lists:keydelete(ftp_remote_host, 1, Config). - -get_ftpd_host([]) -> - {error, no_host}; -get_ftpd_host([Host|Hosts]) -> - p("get_ftpd_host -> entry with" - "~n Host: ~p" - "~n", [Host]), - case (catch ftp:open(Host, [{port, ?FTP_PORT}, {timeout, 20000}])) of - {ok, Pid} -> - (catch ftp:close(Pid)), - {ok, Host}; - _ -> - get_ftpd_host(Hosts) - end. - - -%%-------------------------------------------------------------------- - -dirty_select_ftpd_host(Config) -> - Hosts = - case ct:get_config(ftpd_hosts) of - undefined -> - ftpd_hosts(data_dir(Config)); - H -> - H - end, - dirty_select_ftpd_host2(Hosts). - -dirty_select_ftpd_host2([]) -> - throw({error, not_found}); -dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) -> - case dirty_select_ftpd_host3(Hosts) of - none -> - dirty_select_ftpd_host2(PlatformHosts); - {ok, Host} -> - {PlatformTag, Host} - end. - -dirty_select_ftpd_host3([]) -> - none; -dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) -> - case dirty_select_ftpd_host4(Host) of - true -> - {ok, Host}; - false -> - dirty_select_ftpd_host3(Hosts) - end; -dirty_select_ftpd_host3([_|Hosts]) -> - dirty_select_ftpd_host3(Hosts). - -%% This is a very simple and dirty test that there is a -%% (FTP) deamon on the other end. -dirty_select_ftpd_host4(Host) -> - Port = 21, - IpFam = inet, - Opts = [IpFam, binary, {packet, 0}, {active, false}], - Timeout = ?SECS(5), - case gen_tcp:connect(Host, Port, Opts, Timeout) of - {ok, Sock} -> - gen_tcp:close(Sock), - true; - _Error -> - false - end. - - -%%-------------------------------------------------------------------- - -test_filenames() -> - {ok, Host} = inet:gethostname(), - File = Host ++ "_ftp_test.txt", - NewFile = "new_" ++ File, - {File, NewFile}. - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(Case, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) - when (Case =:= open) orelse - (Case =:= open_port) -> - put(ftp_testcase, Case), - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), - inets:start(), - NewConfig = data_dir(Config), - watch_dog(NewConfig); - -init_per_testcase(Case, Config) -> - put(ftp_testcase, Case), - do_init_per_testcase(Case, Config). - -do_init_per_testcase(Case, Config) - when (Case =:= passive_user) -> - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]), - inets:start(), - NewConfig = close_connection(watch_dog(Config)), - Host = ftp_host(Config), - case (catch ?ftp_open(Host, [{mode, passive}])) of - {ok, Pid} -> - [{ftp, Pid} | data_dir(NewConfig)]; - {skip, _} = SKIP -> - SKIP - end; - -do_init_per_testcase(Case, Config) - when (Case =:= active_user) -> - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), - inets:start(), - NewConfig = close_connection(watch_dog(Config)), - Host = ftp_host(Config), - case (catch ?ftp_open(Host, [{mode, active}])) of - {ok, Pid} -> - [{ftp, Pid} | data_dir(NewConfig)]; - {skip, _} = SKIP -> - SKIP - end; - -do_init_per_testcase(Case, Config) - when (Case =:= progress_report_send) orelse - (Case =:= progress_report_recv) -> - inets:start(), - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), - NewConfig = close_connection(watch_dog(Config)), - Host = ftp_host(Config), - Opts = [{port, ?FTP_PORT}, - {verbose, true}, - {progress, {?MODULE, progress, #progress{}}}], - case ftp:open(Host, Opts) of - {ok, Pid} -> - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), - [{ftp, Pid} | data_dir(NewConfig)]; - {skip, _} = SKIP -> - SKIP - end; - -do_init_per_testcase(Case, Config) -> - io:format(user,"~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), - inets:start(), - NewConfig = close_connection(watch_dog(Config)), - Host = ftp_host(Config), - Opts1 = - if - ((Case =:= passive_ip_v6_disabled) orelse - (Case =:= active_ip_v6_disabled)) -> - [{ipfamily, inet}]; - true -> - [] - end, - Opts2 = - case string:tokens(atom_to_list(Case), [$_]) of - ["active" | _] -> - [{mode, active} | Opts1]; - _ -> - [{mode, passive} | Opts1] - end, - case (catch ?ftp_open(Host, Opts2)) of - {ok, Pid} -> - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), - [{ftp, Pid} | data_dir(NewConfig)]; - {skip, _} = SKIP -> - SKIP - end. - - -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(Case, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(_, Config) -> - NewConfig = close_connection(Config), - Dog = ?config(watchdog, NewConfig), - inets:stop(), - test_server:timetrap_cancel(Dog), - ok. - - -%%------------------------------------------------------------------------- -%% Suites similar for all hosts. -%%------------------------------------------------------------------------- - -passive(suite) -> - [ - passive_user, - passive_pwd, - passive_cd, - passive_lcd, - passive_ls, - passive_nlist, - passive_rename, - passive_delete, - passive_mkdir, - passive_send, - passive_send_bin, - passive_send_chunk, - passive_append, - passive_append_bin, - passive_append_chunk, - passive_recv, - passive_recv_bin, - passive_recv_chunk, - passive_type, - passive_quote, - passive_ip_v6_disabled - ]. - -active(suite) -> - [ - active_user, - active_pwd, - active_cd, - active_lcd, - active_ls, - active_nlist, - active_rename, - active_delete, - active_mkdir, - active_send, - active_send_bin, - active_send_chunk, - active_append, - active_append_bin, - active_append_chunk, - active_recv, - active_recv_bin, - active_recv_chunk, - active_type, - active_quote, - active_ip_v6_disabled - ]. - - - -%%------------------------------------------------------------------------- -%% Test cases starts here. -%%------------------------------------------------------------------------- - -open(doc) -> - ["Open an ftp connection to a host and close the connection." - "Also check that !-messages does not disturbe the connection"]; -open(suite) -> - []; -open(Config) when is_list(Config) -> - Host = ftp_host(Config), - (catch tc_open(Host)). - - -tc_open(Host) -> - p("tc_open -> entry with" - "~n Host: ~p", [Host]), - {ok, Pid} = ?ftp_open(Host, []), - ok = ftp:close(Pid), - p("tc_open -> try (ok) open 1"), - {ok, Pid1} = - ftp:open({option_list, [{host,Host}, - {port, ?FTP_PORT}, - {flags, [verbose]}, - {timeout, 30000}]}), - ok = ftp:close(Pid1), - - p("tc_open -> try (fail) open 2"), - {error, ehost} = - ftp:open({option_list, [{port, ?FTP_PORT}, {flags, [verbose]}]}), - {ok, Pid2} = ftp:open(Host), - ok = ftp:close(Pid2), - - p("tc_open -> try (ok) open 3"), - {ok, NewHost} = inet:getaddr(Host, inet), - {ok, Pid3} = ftp:open(NewHost), - ftp:user(Pid3, ?FTP_USER, ?FTP_PASS), - Pid3 ! foobar, - test_server:sleep(5000), - {message_queue_len, 0} = process_info(self(), message_queue_len), - ["200" ++ _] = ftp:quote(Pid3, "NOOP"), - ok = ftp:close(Pid3), - - %% Bad input that has default values are ignored and the defult - %% is used. - p("tc_open -> try (ok) open 4"), - {ok, Pid4} = - ftp:open({option_list, [{host, Host}, - {port, badarg}, - {flags, [verbose]}, - {timeout, 30000}]}), - test_server:sleep(100), - ok = ftp:close(Pid4), - - p("tc_open -> try (ok) open 5"), - {ok, Pid5} = - ftp:open({option_list, [{host, Host}, - {port, ?FTP_PORT}, - {flags, [verbose]}, - {timeout, -42}]}), - test_server:sleep(100), - ok = ftp:close(Pid5), - - p("tc_open -> try (ok) open 6"), - {ok, Pid6} = - ftp:open({option_list, [{host, Host}, - {port, ?FTP_PORT}, - {flags, [verbose]}, - {mode, cool}]}), - test_server:sleep(100), - ok = ftp:close(Pid6), - - p("tc_open -> try (ok) open 7"), - {ok, Pid7} = - ftp:open(Host, [{port, ?FTP_PORT}, {verbose, true}, {timeout, 30000}]), - ok = ftp:close(Pid7), - - p("tc_open -> try (ok) open 8"), - {ok, Pid8} = - ftp:open(Host, ?FTP_PORT), - ok = ftp:close(Pid8), - - p("tc_open -> try (ok) open 9"), - {ok, Pid9} = - ftp:open(Host, [{port, ?FTP_PORT}, - {verbose, true}, - {timeout, 30000}, - {dtimeout, -99}]), - ok = ftp:close(Pid9), - - p("tc_open -> try (ok) open 10"), - {ok, Pid10} = - ftp:open(Host, [{port, ?FTP_PORT}, - {verbose, true}, - {timeout, 30000}, - {dtimeout, "foobar"}]), - ok = ftp:close(Pid10), - - p("tc_open -> try (ok) open 11"), - {ok, Pid11} = - ftp:open(Host, [{port, ?FTP_PORT}, - {verbose, true}, - {timeout, 30000}, - {dtimeout, 1}]), - ok = ftp:close(Pid11), - - p("tc_open -> done"), - ok. - - -%%------------------------------------------------------------------------- - -open_port(doc) -> - ["Open an ftp connection to a host with given port number " - "and close the connection."]; % See also OTP-3892 -open_port(suite) -> - []; -open_port(Config) when is_list(Config) -> - Host = ftp_host(Config), - {ok, Pid} = ftp:open(Host, [{port, ?FTP_PORT}]), - ok = ftp:close(Pid), - {error, ehost} = ftp:open(?BAD_HOST, []), - ok. - - -%%------------------------------------------------------------------------- - -passive_user(doc) -> - ["Open an ftp connection to a host, and logon as anonymous ftp."]; -passive_user(suite) -> - []; -passive_user(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - p("Pid: ~p",[Pid]), - do_user(Pid). - - -%%------------------------------------------------------------------------- - -passive_pwd(doc) -> - ["Test ftp:pwd/1 & ftp:lpwd/1"]; -passive_pwd(suite) -> - []; -passive_pwd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_pwd(Pid). - - -%%------------------------------------------------------------------------- - -passive_cd(doc) -> - ["Open an ftp connection, log on as anonymous ftp, and cd to the" - "directory \"/pub\" and the to the non-existent directory."]; -passive_cd(suite) -> - []; -passive_cd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_cd(Pid). - - -%%------------------------------------------------------------------------- - -passive_lcd(doc) -> - ["Test api function ftp:lcd/2"]; -passive_lcd(suite) -> - []; -passive_lcd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - PrivDir = ?config(priv_dir, Config), - do_lcd(Pid, PrivDir). - - -%%------------------------------------------------------------------------- - -passive_ls(doc) -> - ["Open an ftp connection; ls the current directory, and the " - "\"incoming\" directory. We assume that ls never fails, since " - "it's output is meant to be read by humans. "]; -passive_ls(suite) -> - []; -passive_ls(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_ls(Pid). - - -%%------------------------------------------------------------------------- - -passive_nlist(doc) -> - ["Open an ftp connection; nlist the current directory, and the " - "\"incoming\" directory. Nlist does not behave consistenly over " - "operating systems. On some it is an error to have an empty " - "directory."]; -passive_nlist(suite) -> - []; -passive_nlist(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - WildcardSupport = ?config(wildcard_support, Config), - do_nlist(Pid, WildcardSupport). - - -%%------------------------------------------------------------------------- - -passive_rename(doc) -> - ["Transfer a file to the server, and rename it; then remove it."]; -passive_rename(suite) -> - []; -passive_rename(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_rename(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_delete(doc) -> - ["Transfer a file to the server, and then delete it"]; -passive_delete(suite) -> - []; -passive_delete(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_delete(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_mkdir(doc) -> - ["Make a remote directory, cd to it, go to parent directory, and " - "remove the directory."]; -passive_mkdir(suite) -> - []; -passive_mkdir(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_mkdir(Pid). - - -%%------------------------------------------------------------------------- - -passive_send(doc) -> - ["Create a local file in priv_dir; open an ftp connection to a host; " - "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to " - "priv_dir; send the file; get a directory listing and check that " - "the file is on the list;, delete the remote file; get another listing " - "and check that the file is not on the list; close the session; " - "delete the local file."]; -passive_send(suite) -> - []; -passive_send(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_append(doc) -> - ["Create a local file in priv_dir; open an ftp connection to a host; " - "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to " - "priv_dir; append the file to a file at the remote side that not exits" - "this will create the file at the remote side. Then it append the file " - "again. When this is done it recive the remote file and control that" - "the content is doubled in it.After that it will remove the files"]; -passive_append(suite) -> - []; -passive_append(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_send_bin(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "send a binary; remove file; close the connection."]; -passive_send_bin(suite) -> - []; -passive_send_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send_bin(Pid, Config). - -%%------------------------------------------------------------------------- - -passive_append_bin(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "append a binary twice; get the file and compare the content" - "remove file; close the connection."]; -passive_append_bin(suite) -> - []; -passive_append_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append_bin(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_send_chunk(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "send chunks; remove file; close the connection."]; -passive_send_chunk(suite) -> - []; -passive_send_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_append_chunk(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "append chunks;control content remove file; close the connection."]; -passive_append_chunk(suite) -> - []; -passive_append_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_recv(doc) -> - ["Create a local file and transfer it to the remote host into the " - "the \"incoming\" directory, remove " - "the local file. Then open a new connection; cd to \"incoming\", " - "lcd to the private directory; receive the file; delete the " - "remote file; close connection; check that received file is in " - "the correct directory; cleanup." ]; -passive_recv(suite) -> - []; -passive_recv(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_recv_bin(doc) -> - ["Send a binary to the remote host; and retreive " - "the file; then remove the file."]; -passive_recv_bin(suite) -> - []; -passive_recv_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv_bin(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_recv_chunk(doc) -> - ["Send a binary to the remote host; Connect again, and retreive " - "the file; then remove the file."]; -passive_recv_chunk(suite) -> - []; -passive_recv_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -passive_type(doc) -> - ["Test that we can change btween ASCCI and binary transfer mode"]; -passive_type(suite) -> - []; -passive_type(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_type(Pid). - - -%%------------------------------------------------------------------------- - -passive_quote(doc) -> - [""]; -passive_quote(suite) -> - []; -passive_quote(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_quote(Pid). - - -%%------------------------------------------------------------------------- - -passive_ip_v6_disabled(doc) -> - ["Test ipv4 command PASV"]; -passive_ip_v6_disabled(suite) -> - []; -passive_ip_v6_disabled(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_user(doc) -> - ["Open an ftp connection to a host, and logon as anonymous ftp."]; -active_user(suite) -> - []; -active_user(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_user(Pid). - - -%%------------------------------------------------------------------------- - -active_pwd(doc) -> - ["Test ftp:pwd/1 & ftp:lpwd/1"]; -active_pwd(suite) -> - []; -active_pwd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_pwd(Pid). - - -%%------------------------------------------------------------------------- - -active_cd(doc) -> - ["Open an ftp connection, log on as anonymous ftp, and cd to the" - "directory \"/pub\" and to a non-existent directory."]; -active_cd(suite) -> - []; -active_cd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_cd(Pid). - - -%%------------------------------------------------------------------------- - -active_lcd(doc) -> - ["Test api function ftp:lcd/2"]; -active_lcd(suite) -> - []; -active_lcd(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - PrivDir = ?config(priv_dir, Config), - do_lcd(Pid, PrivDir). - - -%%------------------------------------------------------------------------- - -active_ls(doc) -> - ["Open an ftp connection; ls the current directory, and the " - "\"incoming\" directory. We assume that ls never fails, since " - "it's output is meant to be read by humans. "]; -active_ls(suite) -> - []; -active_ls(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_ls(Pid). - - -%%------------------------------------------------------------------------- - -active_nlist(doc) -> - ["Open an ftp connection; nlist the current directory, and the " - "\"incoming\" directory. Nlist does not behave consistenly over " - "operating systems. On some it is an error to have an empty " - "directory."]; -active_nlist(suite) -> - []; -active_nlist(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - WildcardSupport = ?config(wildcard_support, Config), - do_nlist(Pid, WildcardSupport). - - -%%------------------------------------------------------------------------- - -active_rename(doc) -> - ["Transfer a file to the server, and rename it; then remove it."]; -active_rename(suite) -> - []; -active_rename(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_rename(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_delete(doc) -> - ["Transfer a file to the server, and then delete it"]; -active_delete(suite) -> - []; -active_delete(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_delete(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_mkdir(doc) -> - ["Make a remote directory, cd to it, go to parent directory, and " - "remove the directory."]; -active_mkdir(suite) -> - []; -active_mkdir(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_mkdir(Pid). - - -%%------------------------------------------------------------------------- - -active_send(doc) -> - ["Create a local file in priv_dir; open an ftp connection to a host; " - "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to " - "priv_dir; send the file; get a directory listing and check that " - "the file is on the list;, delete the remote file; get another listing " - "and check that the file is not on the list; close the session; " - "delete the local file."]; -active_send(suite) -> - []; -active_send(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_append(doc) -> - ["Create a local file in priv_dir; open an ftp connection to a host; " - "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to " - "priv_dir; append the file to a file at the remote side that not exits" - "this will create the file at the remote side. Then it append the file " - "again. When this is done it recive the remote file and control that" - "the content is doubled in it.After that it will remove the files"]; -active_append(suite) -> - []; -active_append(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_send_bin(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "send a binary; remove file; close the connection."]; -active_send_bin(suite) -> - []; -active_send_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send_bin(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_append_bin(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "append a binary twice; get the file and compare the content" - "remove file; close the connection."]; -active_append_bin(suite) -> - []; -active_append_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append_bin(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_send_chunk(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "send chunks; remove file; close the connection."]; -active_send_chunk(suite) -> - []; -active_send_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_append_chunk(doc) -> - ["Open a connection to a host; cd to the directory \"incoming\"; " - "append chunks;control content remove file; close the connection."]; -active_append_chunk(suite) -> - []; -active_append_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_append_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_recv(doc) -> - ["Create a local file and transfer it to the remote host into the " - "the \"incoming\" directory, remove " - "the local file. Then open a new connection; cd to \"incoming\", " - "lcd to the private directory; receive the file; delete the " - "remote file; close connection; check that received file is in " - "the correct directory; cleanup." ]; -active_recv(suite) -> - []; -active_recv(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_recv_bin(doc) -> - ["Send a binary to the remote host; and retreive " - "the file; then remove the file."]; -active_recv_bin(suite) -> - []; -active_recv_bin(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv_bin(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_recv_chunk(doc) -> - ["Send a binary to the remote host; Connect again, and retreive " - "the file; then remove the file."]; -active_recv_chunk(suite) -> - []; -active_recv_chunk(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_recv_chunk(Pid, Config). - - -%%------------------------------------------------------------------------- - -active_type(doc) -> - ["Test that we can change btween ASCCI and binary transfer mode"]; -active_type(suite) -> - []; -active_type(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_type(Pid). - - -%%------------------------------------------------------------------------- - -active_quote(doc) -> - [""]; -active_quote(suite) -> - []; -active_quote(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_quote(Pid). - - -%%------------------------------------------------------------------------- - -active_ip_v6_disabled(doc) -> - ["Test ipv4 command PORT"]; -active_ip_v6_disabled(suite) -> - []; -active_ip_v6_disabled(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - do_send(Pid, Config). - - -%%------------------------------------------------------------------------- - -api_missuse(doc)-> - ["Test that behaviour of the ftp process if the api is abused"]; -api_missuse(suite) -> []; -api_missuse(Config) when is_list(Config) -> - p("api_missuse -> entry"), - Flag = process_flag(trap_exit, true), - Pid = ?config(ftp, Config), - Host = ftp_host(Config), - - %% Serious programming fault, connetion will be shut down - p("api_missuse -> verify bad call termination (~p)", [Pid]), - case (catch gen_server:call(Pid, {self(), foobar, 10}, infinity)) of - {error, {connection_terminated, 'API_violation'}} -> - ok; - Unexpected1 -> - exit({unexpected_result, Unexpected1}) - end, - test_server:sleep(500), - undefined = process_info(Pid, status), - - p("api_missuse -> start new client"), - {ok, Pid2} = ?ftp_open(Host, []), - %% Serious programming fault, connetion will be shut down - p("api_missuse -> verify bad cast termination"), - gen_server:cast(Pid2, {self(), foobar, 10}), - test_server:sleep(500), - undefined = process_info(Pid2, status), - - p("api_missuse -> start new client"), - {ok, Pid3} = ?ftp_open(Host, []), - %% Could be an innocent misstake the connection lives. - p("api_missuse -> verify bad bang"), - Pid3 ! foobar, - test_server:sleep(500), - {status, _} = process_info(Pid3, status), - process_flag(trap_exit, Flag), - p("api_missuse -> done"), - ok. - - -%%------------------------------------------------------------------------- - -not_owner(doc) -> - ["Test what happens if a process that not owns the connection tries " - "to use it"]; -not_owner(suite) -> - []; -not_owner(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - OtherPid = spawn_link(?MODULE, not_owner, [Pid, self()]), - - receive - {OtherPid, ok} -> - {ok, _} = ftp:pwd(Pid) - end, - ok. - -not_owner(FtpPid, Pid) -> - {error, not_connection_owner} = ftp:pwd(FtpPid), - ftp:close(FtpPid), - test_server:sleep(100), - Pid ! {self(), ok}. - - -%%------------------------------------------------------------------------- - - -progress_report(doc) -> - ["Solaris 8 sparc test the option progress."]; -progress_report(suite) -> - [progress_report_send, progress_report_recv]. - - -%% -- - -progress_report_send(doc) -> - ["Test the option progress for ftp:send/[2,3]"]; -progress_report_send(suite) -> - []; -progress_report_send(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - ReportPid = - spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]), - do_send(Pid, Config), - receive - {ReportPid, ok} -> - ok - end. - - -%% -- - -progress_report_recv(doc) -> - ["Test the option progress for ftp:recv/[2,3]"]; -progress_report_recv(suite) -> - []; -progress_report_recv(Config) when is_list(Config) -> - Pid = ?config(ftp, Config), - ReportPid = - spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]), - do_recv(Pid, Config), - receive - {ReportPid, ok} -> - ok - end, - ok. - -progress(#progress{} = Progress , _File, {file_size, Total}) -> - progress_report_receiver ! start, - Progress#progress{total = Total}; -progress(#progress{total = Total, current = Current} - = Progress, _File, {transfer_size, 0}) -> - progress_report_receiver ! finish, - case Total of - unknown -> - ok; - Current -> - ok; - _ -> - test_server:fail({error, {progress, {total, Total}, - {current, Current}}}) - end, - Progress; -progress(#progress{current = Current} = Progress, _File, - {transfer_size, Size}) -> - progress_report_receiver ! update, - Progress#progress{current = Current + Size}. - -progress_report_receiver_init(Pid, N) -> - register(progress_report_receiver, self()), - receive - start -> - ok - end, - progress_report_receiver_loop(Pid, N-1). - -progress_report_receiver_loop(Pid, N) -> - receive - update -> - progress_report_receiver_loop(Pid, N); - finish when N =:= 0 -> - Pid ! {self(), ok}; - finish -> - Pid ! {self(), ok}, - receive - start -> - ok - end, - progress_report_receiver_loop(Pid, N-1) - end. - - -%%------------------------------------------------------------------------- -%% Ticket test cases -%%------------------------------------------------------------------------- - -ticket_6035(doc) -> ["Test that owning process that exits with reason " - "'shutdown' does not cause an error message."]; -ticket_6035(suite) -> []; -ticket_6035(Config) -> - p("ticket_6035 -> entry with" - "~n Config: ~p", [Config]), - PrivDir = ?config(priv_dir, Config), - LogFile = filename:join([PrivDir,"ticket_6035.log"]), - try - begin - p("ticket_6035 -> select ftpd host"), - Host = dirty_select_ftpd_host(Config), - p("ticket_6035 -> ftpd host selected (~p) => now spawn ftp owner", [Host]), - Pid = spawn(?MODULE, open_wait_6035, [Host, self()]), - p("ticket_6035 -> waiter spawned: ~p => now open error logfile (~p)", - [Pid, LogFile]), - error_logger:logfile({open, LogFile}), - p("ticket_6035 -> error logfile open => now kill waiter process"), - true = kill_ftp_proc_6035(Pid, LogFile), - p("ticket_6035 -> waiter process killed => now close error logfile"), - error_logger:logfile(close), - p("ticket_6035 -> done", []), - ok - end - catch - throw:{error, not_found} -> - {skip, "No available FTP servers"} - end. - -kill_ftp_proc_6035(Pid, LogFile) -> - p("kill_ftp_proc_6035 -> entry"), - receive - open -> - p("kill_ftp_proc_6035 -> received open => now issue shutdown"), - exit(Pid, shutdown), - kill_ftp_proc_6035(Pid, LogFile); - {open_failed, Reason} -> - p("kill_ftp_proc_6035 -> received open_failed" - "~n Reason: ~p", [Reason]), - exit({skip, {failed_openening_server_connection, Reason}}) - after - 5000 -> - p("kill_ftp_proc_6035 -> timeout"), - is_error_report_6035(LogFile) - end. - -open_wait_6035({Tag, FtpServer}, From) -> - p("open_wait_6035 -> try connect to [~p] ~s for ~p", [Tag, FtpServer, From]), - case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of - {ok, Pid} -> - p("open_wait_6035 -> connected (~p), now login", [Pid]), - LoginResult = ftp:user(Pid,"anonymous","kldjf"), - p("open_wait_6035 -> login result: ~p", [LoginResult]), - From ! open, - receive - dummy -> - p("open_wait_6035 -> received dummy"), - ok - after - 10000 -> - p("open_wait_6035 -> timeout"), - ok - end, - p("open_wait_6035 -> done(ok)"), - ok; - {error, Reason} -> - p("open_wait_6035 -> open failed" - "~n Reason: ~p", [Reason]), - From ! {open_failed, {Reason, FtpServer}}, - p("open_wait_6035 -> done(error)"), - ok - end. - -is_error_report_6035(LogFile) -> - p("is_error_report_6035 -> entry"), - Res = - case file:read_file(LogFile) of - {ok, Bin} -> - Txt = binary_to_list(Bin), - p("is_error_report_6035 -> logfile read: ~n~p", [Txt]), - read_log_6035(Txt); - _ -> - false - end, - p("is_error_report_6035 -> logfile read result: " - "~n ~p", [Res]), - %% file:delete(LogFile), - Res. - -read_log_6035("=ERROR REPORT===="++_Rest) -> - p("read_log_6035 -> ERROR REPORT detected"), - true; -read_log_6035([H|T]) -> - p("read_log_6035 -> OTHER: " - "~p", [H]), - read_log_6035(T); -read_log_6035([]) -> - p("read_log_6035 -> done"), - false. - - -%%-------------------------------------------------------------------- -%% Internal functions -%%-------------------------------------------------------------------- -do_user(Pid) -> - {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS), - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS), - ok. - -do_pwd(Pid) -> - {ok, "/"} = ftp:pwd(Pid), - {ok, Path} = ftp:lpwd(Pid), - {ok, Path} = file:get_cwd(), - ok. - -do_cd(Pid) -> - ok = ftp:cd(Pid, "/pub"), - {error, epath} = ftp:cd(Pid, ?BAD_DIR), - ok. - -do_lcd(Pid, Dir) -> - ok = ftp:lcd(Pid, Dir), - {error, epath} = ftp:lcd(Pid, ?BAD_DIR), - ok. - - -do_ls(Pid) -> - {ok, _} = ftp:ls(Pid), - {ok, _} = ftp:ls(Pid, "incoming"), - %% neither nlist nor ls operates on a directory - %% they operate on a pathname, which *can* be a - %% directory, but can also be a filename or a group - %% of files (including wildcards). - {ok, _} = ftp:ls(Pid, "incom*"), - ok. - -do_nlist(Pid, WildcardSupport) -> - {ok, _} = ftp:nlist(Pid), - {ok, _} = ftp:nlist(Pid, "incoming"), - %% neither nlist nor ls operates on a directory - %% they operate on a pathname, which *can* be a - %% directory, but can also be a filename or a group - %% of files (including wildcards). - case WildcardSupport of - true -> - {ok, _} = ftp:nlist(Pid, "incom*"), - ok; - _ -> - ok - end. - -do_rename(Pid, Config) -> - PrivDir = ?config(priv_dir, Config), - LFile = ?config(file, Config), - NewLFile = ?config(new_file, Config), - AbsLFile = filename:absname(LFile, PrivDir), - Contents = "ftp_SUITE test ...", - ok = file:write_file(AbsLFile, list_to_binary(Contents)), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:lcd(Pid, PrivDir), - ftp:delete(Pid, LFile), % reset - ftp:delete(Pid, NewLFile), % reset - ok = ftp:send(Pid, LFile), - {error, epath} = ftp:rename(Pid, NewLFile, LFile), - ok = ftp:rename(Pid, LFile, NewLFile), - ftp:delete(Pid, LFile), % cleanup - ftp:delete(Pid, NewLFile), % cleanup - ok. - -do_delete(Pid, Config) -> - PrivDir = ?config(priv_dir, Config), - LFile = ?config(file, Config), - AbsLFile = filename:absname(LFile, PrivDir), - Contents = "ftp_SUITE test ...", - ok = file:write_file(AbsLFile, list_to_binary(Contents)), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:lcd(Pid, PrivDir), - ftp:delete(Pid,LFile), % reset - ok = ftp:send(Pid, LFile), - ok = ftp:delete(Pid,LFile), - ok. - -do_mkdir(Pid) -> - {A, B, C} = erlang:now(), - NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++ - integer_to_list(B) ++ "_" ++ integer_to_list(C), - ok = ftp:cd(Pid, "incoming"), - {ok, CurrDir} = ftp:pwd(Pid), - ok = ftp:mkdir(Pid, NewDir), - ok = ftp:cd(Pid, NewDir), - ok = ftp:cd(Pid, CurrDir), - ok = ftp:rmdir(Pid, NewDir), - ok. - -do_send(Pid, Config) -> - PrivDir = ?config(priv_dir, Config), - LFile = ?config(file, Config), - RFile = LFile ++ ".remote", - AbsLFile = filename:absname(LFile, PrivDir), - Contents = "ftp_SUITE test ...", - ok = file:write_file(AbsLFile, list_to_binary(Contents)), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:lcd(Pid, PrivDir), - ok = ftp:send(Pid, LFile, RFile), - {ok, RFilesString} = ftp:nlist(Pid), - RFiles = split(RFilesString), - true = lists:member(RFile, RFiles), - ok = ftp:delete(Pid, RFile), - case ftp:nlist(Pid) of - {error, epath} -> - ok; % No files - {ok, RFilesString1} -> - RFiles1 = split(RFilesString1), - false = lists:member(RFile, RFiles1) - end, - ok = file:delete(AbsLFile). - -do_append(Pid, Config) -> - PrivDir = ?config(priv_dir, Config), - LFile = ?config(file, Config), - RFile = ?config(new_file, Config), - AbsLFile = filename:absname(LFile, PrivDir), - Contents = "ftp_SUITE test:appending\r\n", - - ok = file:write_file(AbsLFile, list_to_binary(Contents)), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:lcd(Pid, PrivDir), - - %% remove files from earlier failed test case - ftp:delete(Pid, RFile), - ftp:delete(Pid, LFile), - - ok = ftp:append(Pid, LFile, RFile), - ok = ftp:append(Pid, LFile, RFile), - ok = ftp:append(Pid, LFile), - - %% Control the contents of the file - {ok, Bin1} = ftp:recv_bin(Pid, RFile), - ok = ftp:delete(Pid, RFile), - ok = file:delete(AbsLFile), - ok = check_content(binary_to_list(Bin1), Contents, double), - - {ok, Bin2} = ftp:recv_bin(Pid, LFile), - ok = ftp:delete(Pid, LFile), - ok = check_content(binary_to_list(Bin2), Contents, singel), - ok. - -do_send_bin(Pid, Config) -> - File = ?config(file, Config), - Contents = "ftp_SUITE test ...", - Bin = list_to_binary(Contents), - ok = ftp:cd(Pid, "incoming"), - {error, enotbinary} = ftp:send_bin(Pid, Contents, File), - ok = ftp:send_bin(Pid, Bin, File), - {ok, RFilesString} = ftp:nlist(Pid), - RFiles = split(RFilesString), - true = lists:member(File, RFiles), - ok = ftp:delete(Pid, File), - ok. - -do_append_bin(Pid, Config) -> - File = ?config(file, Config), - Contents = "ftp_SUITE test ...", - Bin = list_to_binary(Contents), - ok = ftp:cd(Pid, "incoming"), - {error, enotbinary} = ftp:append_bin(Pid, Contents, File), - ok = ftp:append_bin(Pid, Bin, File), - ok = ftp:append_bin(Pid, Bin, File), - %% Control the contents of the file - {ok, Bin2} = ftp:recv_bin(Pid, File), - ok = ftp:delete(Pid,File), - ok = check_content(binary_to_list(Bin2),binary_to_list(Bin), double). - -do_send_chunk(Pid, Config) -> - File = ?config(file, Config), - Contents = "ftp_SUITE test ...", - Bin = list_to_binary(Contents), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:send_chunk_start(Pid, File), - {error, echunk} = ftp:cd(Pid, "incoming"), - {error, enotbinary} = ftp:send_chunk(Pid, Contents), - ok = ftp:send_chunk(Pid, Bin), - ok = ftp:send_chunk(Pid, Bin), - ok = ftp:send_chunk_end(Pid), - {ok, RFilesString} = ftp:nlist(Pid), - RFiles = split(RFilesString), - true = lists:member(File, RFiles), - ok = ftp:delete(Pid, File), - ok. - -do_append_chunk(Pid, Config) -> - File = ?config(file, Config), - Contents = ["ER","LE","RL"], - ok = ftp:cd(Pid, "incoming"), - ok = ftp:append_chunk_start(Pid, File), - {error, enotbinary} = ftp:append_chunk(Pid, lists:nth(1,Contents)), - ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(1,Contents))), - ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(2,Contents))), - ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(3,Contents))), - ok = ftp:append_chunk_end(Pid), - %%Control the contents of the file - {ok, Bin2} = ftp:recv_bin(Pid, File), - ok = check_content(binary_to_list(Bin2),"ERL", double), - ok = ftp:delete(Pid, File), - ok. - -do_recv(Pid, Config) -> - PrivDir = ?config(priv_dir, Config), - File = ?config(file, Config), - Newfile = ?config(new_file, Config), - AbsFile = filename:absname(File, PrivDir), - Contents = "ftp_SUITE:recv test ...", - ok = file:write_file(AbsFile, list_to_binary(Contents)), - ok = ftp:cd(Pid, "incoming"), - ftp:delete(Pid, File), % reset - ftp:lcd(Pid, PrivDir), - ok = ftp:send(Pid, File), - ok = file:delete(AbsFile), % cleanup - test_server:sleep(100), - ok = ftp:lcd(Pid, PrivDir), - ok = ftp:recv(Pid, File), - {ok, Files} = file:list_dir(PrivDir), - true = lists:member(File, Files), - ok = file:delete(AbsFile), % cleanup - ok = ftp:recv(Pid, File, Newfile), - ok = ftp:delete(Pid, File), % cleanup - ok. - -do_recv_bin(Pid, Config) -> - File = ?config(file, Config), - Contents1 = "ftp_SUITE test ...", - Bin1 = list_to_binary(Contents1), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:send_bin(Pid, Bin1, File), - test_server:sleep(100), - {ok, Bin2} = ftp:recv_bin(Pid, File), - ok = ftp:delete(Pid, File), % cleanup - Contents2 = binary_to_list(Bin2), - Contents1 = Contents2, - ok. - -do_recv_chunk(Pid, Config) -> - File = ?config(file, Config), - Data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" - "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH" - "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII", - - Contents1 = lists:flatten(lists:duplicate(10, Data)), - Bin1 = list_to_binary(Contents1), - ok = ftp:cd(Pid, "incoming"), - ok = ftp:type(Pid, binary), - ok = ftp:send_bin(Pid, Bin1, File), - test_server:sleep(100), - {error, "ftp:recv_chunk_start/2 not called"} = recv_chunk(Pid, <<>>), - ok = ftp:recv_chunk_start(Pid, File), - {ok, Contents2} = recv_chunk(Pid, <<>>), - ok = ftp:delete(Pid, File), % cleanup - ok = find_diff(Contents2, Contents1, 1), - ok. - -do_type(Pid) -> - ok = ftp:type(Pid, ascii), - ok = ftp:type(Pid, binary), - ok = ftp:type(Pid, ascii), - {error, etype} = ftp:type(Pid, foobar), - ok. - -do_quote(Pid) -> - ["257 \"/\""++_Rest] = ftp:quote(Pid, "pwd"), %% 257 - [_| _] = ftp:quote(Pid, "help"), - %% This negativ test causes some ftp servers to hang. This test - %% is not important for the client, so we skip it for now. - %%["425 Can't build data connection: Connection refused."] - %% = ftp:quote(Pid, "list"), - ok. - - watch_dog(Config) -> - Dog = test_server:timetrap(inets_test_lib:minutes(1)), - NewConfig = lists:keydelete(watchdog, 1, Config), - [{watchdog, Dog} | NewConfig]. - - close_connection(Config) -> - case ?config(ftp, Config) of - Pid when is_pid(Pid) -> - ok = ftp:close(Pid), - lists:delete({ftp, Pid}, Config); - _ -> - Config - end. - -ftp_host(Config) -> - case ?config(ftp_remote_host, Config) of - undefined -> - exit({skip, "No host specified"}); - Host -> - Host - end. - -check_content(RContent, LContent, Amount) -> - LContent2 = case Amount of - double -> - LContent ++ LContent; - singel -> - LContent - end, - case string:equal(RContent, LContent2) of - true -> - ok; - false -> - %% Find where the diff is - Where = find_diff(RContent, LContent2, 1), - Where - end. - -find_diff(A, A, _) -> - ok; -find_diff([H|T1], [H|T2], Pos) -> - find_diff(T1, T2, Pos+1); -find_diff(RC, LC, Pos) -> - {error, {diff, Pos, RC, LC}}. - -recv_chunk(Pid, Acc) -> - case ftp:recv_chunk(Pid) of - ok -> - {ok, binary_to_list(Acc)}; - {ok, Bin} -> - recv_chunk(Pid, <>); - Error -> - Error - end. - -split(Cs) -> - split(Cs, [], []). - -split([$\r, $\n| Cs], I, Is) -> - split(Cs, [], [lists:reverse(I)| Is]); -split([C| Cs], I, Is) -> - split(Cs, [C| I], Is); -split([], I, Is) -> - lists:reverse([lists:reverse(I)| Is]). - -do_ftp_open(Host, Opts) -> - p("do_ftp_open -> entry with" - "~n Host: ~p" - "~n Opts: ~p", [Host, Opts]), - case ftp:open(Host, Opts) of - {ok, _} = OK -> - OK; - {error, Reason} -> - Str = - lists:flatten( - io_lib:format("Unable to reach test FTP server ~p (~p)", - [Host, Reason])), - throw({skip, Str}) - end. - - -passwd() -> - Host = - case inet:gethostname() of - {ok, H} -> - H; - _ -> - "localhost" - end, - "ftp_SUITE@" ++ Host. - -ftpd_hosts(Config) -> - DataDir = ?config(data_dir, Config), - FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]), - p("FileName: ~p", [FileName]), - case file:consult(FileName) of - {ok, [Hosts]} when is_list(Hosts) -> - Hosts; - _ -> - [] - end. - -wrapper(Prefix,doc,Func) -> - Prefix++Func(doc); -wrapper(_,X,Func) -> - Func(X). - -data_dir(Config) -> - case ?config(data_dir, Config) of - List when (length(List) > 0) -> - PathList = filename:split(List), - {NewPathList,_} = lists:split((length(PathList)-1), PathList), - DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]), - NewConfig = - lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}), - NewConfig; - _ -> Config - end. - - - -p(F) -> - p(F, []). - -p(F, A) -> - case get(ftp_testcase) of - undefined -> - io:format("~w [~w] " ++ F ++ "~n", [?MODULE, self() | A]); - TC when is_atom(TC) -> - io:format("~w [~w] ~w:" ++ F ++ "~n", [?MODULE, self(), TC | A]) - end. diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl deleted file mode 100644 index fe4ab35728..0000000000 --- a/lib/inets/test/ftp_ticket_test.erl +++ /dev/null @@ -1,61 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_ticket_test). - --compile(export_all). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Solaris 8 sparc "). - - -%% Test server callbacks -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). - -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - - -all() -> - tickets(). - -groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -init_per_suite(Config) -> - ?LIB_MOD:ftpd_init(ticket_test, Config). - -tickets() -> - [ticket_6035]. - - -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -ticket_6035(X) -> ?LIB_MOD:ticket_6035(X). diff --git a/lib/inets/test/ftp_windows_2003_server_test.erl b/lib/inets/test/ftp_windows_2003_server_test.erl deleted file mode 100644 index 32f25713f8..0000000000 --- a/lib/inets/test/ftp_windows_2003_server_test.erl +++ /dev/null @@ -1,167 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_windows_2003_server_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Windows 2003 server "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(windows_2003_server, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [ - open, - open_port, - {group, passive}, - {group, active}, - api_missuse, - not_owner, - {group, progress_report} - ]. - -groups() -> - [ - {passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], ftp_suite_lib:progress_report(suite)} - ]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/ftp_windows_xp_test.erl b/lib/inets/test/ftp_windows_xp_test.erl deleted file mode 100644 index 06d919ba00..0000000000 --- a/lib/inets/test/ftp_windows_xp_test.erl +++ /dev/null @@ -1,157 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(ftp_windows_xp_test). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - --define(LIB_MOD,ftp_suite_lib). --define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)). --define(PLATFORM,"Windows xp "). - -%% Test server callback functions -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - {File, NewFile} = ?LIB_MOD:test_filenames(), - NewConfig = [{file, File}, {new_file, NewFile} | Config], - ?LIB_MOD:ftpd_init(windows_xp, NewConfig). - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(Config) -> - ?LIB_MOD:ftpd_fin(Config). - -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - ftp_suite_lib:init_per_testcase(Case, Config). -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(Case, Config) -> - ftp_suite_lib:end_per_testcase(Case, Config). - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open, open_port, {group, passive}, {group, active}, - api_missuse, not_owner, {group, progress_report}]. - -groups() -> - [{passive, [], ftp_suite_lib:passive(suite)}, - {active, [], ftp_suite_lib:active(suite)}, - {progress_report, [], - ftp_suite_lib:progress_report(suite)}]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1). -open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1). -api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1). -not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1). - -passive_user(X) -> ?LIB_MOD:passive_user(X). -passive_pwd(X) -> ?LIB_MOD:passive_pwd(X). -passive_cd(X) -> ?LIB_MOD:passive_cd(X). -passive_lcd(X) -> ?LIB_MOD:passive_lcd(X). -passive_ls(X) -> ?LIB_MOD:passive_ls(X). -passive_nlist(X) -> ?LIB_MOD:passive_nlist(X). -passive_rename(X) -> ?LIB_MOD:passive_rename(X). -passive_delete(X) -> ?LIB_MOD:passive_delete(X). -passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X). -passive_send(X) -> ?LIB_MOD:passive_send(X). -passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X). -passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X). -passive_append(X) -> ?LIB_MOD:passive_append(X). -passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X). -passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X). -passive_recv(X) -> ?LIB_MOD:passive_recv(X). -passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X). -passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X). -passive_type(X) -> ?LIB_MOD:passive_type(X). -passive_quote(X) -> ?LIB_MOD:passive_quote(X). -passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X). -active_user(X) -> ?LIB_MOD:active_user(X). -active_pwd(X) -> ?LIB_MOD:active_pwd(X). -active_cd(X) -> ?LIB_MOD:active_cd(X). -active_lcd(X) -> ?LIB_MOD:active_lcd(X). -active_ls(X) -> ?LIB_MOD:active_ls(X). -active_nlist(X) -> ?LIB_MOD:active_nlist(X). -active_rename(X) -> ?LIB_MOD:active_rename(X). -active_delete(X) -> ?LIB_MOD:active_delete(X). -active_mkdir(X) -> ?LIB_MOD:active_mkdir(X). -active_send(X) -> ?LIB_MOD:active_send(X). -active_send_bin(X) -> ?LIB_MOD:active_send_bin(X). -active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X). -active_append(X) -> ?LIB_MOD:active_append(X). -active_append_bin(X) -> ?LIB_MOD:active_append_bin(X). -active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X). -active_recv(X) -> ?LIB_MOD:active_recv(X). -active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X). -active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X). -active_type(X) -> ?LIB_MOD:active_type(X). -active_quote(X) -> ?LIB_MOD:active_quote(X). -active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X). -progress_report_send(X) -> ?LIB_MOD:progress_report_send(X). -progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X). - -fin(Config) -> - ?LIB_MOD:ftpd_fin(Config). diff --git a/lib/inets/test/old_ftp_SUITE.erl b/lib/inets/test/old_ftp_SUITE.erl deleted file mode 100644 index 81d8ca6282..0000000000 --- a/lib/inets/test/old_ftp_SUITE.erl +++ /dev/null @@ -1,127 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%% - --module(old_ftp_SUITE). - --include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). - -%% Test server specific exports --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). -% -export([init_per_testcase/2, end_per_testcase/2]). --export([init_per_suite/1, end_per_suite/1]). - --define(FTP_USER, "anonymous"). --define(FTP_PASS, passwd()). --define(FTP_PORT, 21). - --define(BAD_HOST, "badhostname"). --define(BAD_USER, "baduser"). --define(BAD_DIR, "baddirectory"). - --ifdef(ftp_debug_client). --define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)). --else. --ifdef(ftp_trace_client). --define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)). --else. --define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)). --endif. --endif. - - -%%-------------------------------------------------------------------- -%% all(Arg) -> [Doc] | [Case] | {skip, Comment} -%% Arg - doc | suite -%% Doc - string() -%% Case - atom() -%% Name of a test case function. -%% Comment - string() -%% Description: Returns documentation/test cases in this test suite -%% or a skip tuple if the platform is not supported. -%%-------------------------------------------------------------------- -suite() -> [{ct_hooks, [ts_install_cth]}]. - -all() -> - [ - {group, solaris8_test}, - {group, solaris9_test}, - {group, solaris10_test}, - {group, linux_x86_test}, - {group, linux_ppc_test}, - {group, macosx_x86_test}, - {group, macosx_ppc_test}, - {group, openbsd_test}, - {group, freebsd_test}, - {group, netbsd_test}, - {group, windows_xp_test}, - {group, windows_2003_server_test}, - {group, ticket_tests} - ]. - -groups() -> - [ - {solaris8_test, [], [{ftp_solaris8_sparc_test, all}]}, - {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]}, - {solaris10_test, [], [{ftp_solaris10_sparc_test, all}, - {ftp_solaris10_x86_test, all}]}, - {linux_x86_test, [], [{ftp_linux_x86_test, all}]}, - {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]}, - {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]}, - {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]}, - {openbsd_test, [], [{ftp_openbsd_x86_test, all}]}, - {freebsd_test, [], [{ftp_freebsd_x86_test, all}]}, - {netbsd_test, [], [{ftp_netbsd_x86_test, all}]}, - {windows_xp_test, [], [{ftp_windows_xp_test, all}]}, - {windows_2003_server_test, [], [{ftp_windows_2003_server_test, all}]}, - {ticket_tests, [], [{ftp_ticket_test, all}]} - ]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - - - -%%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - inets:start(), - Config. - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(_Config) -> - inets:stop(), - ok. diff --git a/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel deleted file mode 100644 index 75096ce687..0000000000 --- a/lib/inets/test/old_ftp_SUITE_data/ftpd_hosts.skel +++ /dev/null @@ -1,18 +0,0 @@ -%% Add a host name in the appropriate list -%% Each "platform" contains a list of hostnames (a string) that can -%% be used for testing the ftp client. -%% The definition below are an example!! -[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]}, - {solaris9_sparc, ["solaris9_sparc_dummy1"]}, - {solaris10_sparc, ["solaris10_sparc_dummy1"]}, - {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]}, - {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]}, - {linux_ppc, ["linux_ppc_dummy1"]}, - {macosx_ppc, ["macosx_ppc_dummy1"]}, - {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]}, - {openbsd_x86, []}, - {freebsd_x86, ["freebsd_x86_dummy1"]}, - {netbsd_x86, []}, - {windows_xp, []}, - {windows_2003_server, ["win2003_dummy1"]}, - {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}]. -- cgit v1.2.3 From 38a6bfa58009e4106e0f7243a7ec36504fe736f5 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 11:40:56 +0100 Subject: ftp: Add documentation. --- lib/inets/doc/src/ftp.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml index ac14d3f274..c6e37dc539 100644 --- a/lib/inets/doc/src/ftp.xml +++ b/lib/inets/doc/src/ftp.xml @@ -569,7 +569,7 @@ (without the inets service framework) and open a session with the FTP server at Host.

-

If the option {tls, tls_options()} is present, the ftp session will be transported over tls (ftps, see RFC 4217). The list tls_options() may be empty. The function ssl:connect/3 is used for establishing both the control connection and the data sessions. +

If the option {tls, tls_options()} is present, the ftp session will be transported over tls (ftps, see RFC 4217). The list tls_options() may be empty. The function ssl:connect/3 is used for securing both the control connection and the data sessions.

A session opened in this way, is closed using the -- cgit v1.2.3 From 5b10a6c858dc1e311af82f554abebd34108c6cce Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 12:09:05 +0100 Subject: ftp: Linking rfc-refs. --- lib/inets/doc/src/ftp.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml index c6e37dc539..d528c2bb28 100644 --- a/lib/inets/doc/src/ftp.xml +++ b/lib/inets/doc/src/ftp.xml @@ -569,7 +569,8 @@ (without the inets service framework) and open a session with the FTP server at Host.

-

If the option {tls, tls_options()} is present, the ftp session will be transported over tls (ftps, see RFC 4217). The list tls_options() may be empty. The function ssl:connect/3 is used for securing both the control connection and the data sessions. +

If the option {tls, tls_options()} is present, the ftp session will be transported over tls (ftps, see +RFC 4217). The list tls_options() may be empty. The function ssl:connect/3 is used for securing both the control connection and the data sessions.

A session opened in this way, is closed using the @@ -817,8 +818,7 @@

Sets the file transfer type to ascii or binary. When an ftp session is opened, the default transfer type of the server is used, most often ascii, which is the default - according to RFC 959.

- + according to RFC 959.

@@ -945,7 +945,7 @@
SEE ALSO

file, filename, J. Postel and J. Reynolds: File Transfer Protocol - (RFC 959). + (RFC 959).

-- cgit v1.2.3 From d3851f2c91ff0fdafa5ebb7ec8bdd4978c980af7 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 14:29:20 +0100 Subject: ftp: Clean Makefile and conf file --- lib/inets/test/Makefile | 16 ---------------- lib/inets/test/ftp_SUITE_data/vsftpd.conf | 12 ++++++++---- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index f08bb1a15e..73070ac57e 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -150,24 +150,8 @@ INETS_ROOT = ../../inets MODULES = \ inets_test_lib \ erl_make_certs \ - old_ftp_SUITE \ ftp_SUITE \ ftp_format_SUITE \ - ftp_solaris8_sparc_test \ - ftp_solaris9_sparc_test \ - ftp_solaris10_sparc_test \ - ftp_solaris10_x86_test \ - ftp_linux_x86_test \ - ftp_linux_ppc_test \ - ftp_macosx_x86_test \ - ftp_macosx_ppc_test \ - ftp_openbsd_x86_test \ - ftp_freebsd_x86_test \ - ftp_netbsd_x86_test \ - ftp_windows_xp_test \ - ftp_windows_2003_server_test \ - ftp_suite_lib \ - ftp_ticket_test \ http_format_SUITE \ httpc_SUITE \ httpc_cookie_SUITE \ diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf index 4133f8f3b1..a5584f5916 100644 --- a/lib/inets/test/ftp_SUITE_data/vsftpd.conf +++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf @@ -1,11 +1,18 @@ +### +### Some parameters are given in the vsftpd start command. +### +### Typical command-line paramters are such that has a file path +### component like cert files. +### + + listen=YES listen_port=9999 run_as_launching_user=YES ssl_enable=YES allow_anon_ssl=YES -#background=NO background=YES write_enable=YES @@ -15,8 +22,5 @@ anon_mkdir_write_enable=YES anon_other_write_enable=YES anon_world_readable_only=NO -#rsa_cert_file=cert.pem -#rsa_private_key_file exists, not rsa_key_file=key.pem - ### Shouldn't be necessary.... require_ssl_reuse=NO -- cgit v1.2.3 From bc61b755eff38dc06a1b47802f03be66af2f9c7c Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 14:30:12 +0100 Subject: ftp: Adds dynamic cert generation to tests. --- lib/inets/test/ftp_SUITE.erl | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl index 28adcf822b..e39f9f1eb6 100644 --- a/lib/inets/test/ftp_SUITE.erl +++ b/lib/inets/test/ftp_SUITE.erl @@ -118,12 +118,13 @@ ftp_tests()-> fun(__CONF__) -> DataDir = ?config(data_dir,__CONF__), ConfFile = filename:join(DataDir, "vsftpd.conf"), - AnonRoot = ?config(priv_dir,__CONF__), + PrivDir = ?config(priv_dir,__CONF__), + AnonRoot = PrivDir, Cmd = ["vsftpd "++filename:join(DataDir,"vsftpd.conf"), " -oftpd_banner=erlang_otp_testing", " -oanon_root=\"",AnonRoot,"\"", - " -orsa_cert_file=\"",filename:join(DataDir,"cert.pem"),"\"", - " -orsa_private_key_file=\"",filename:join(DataDir,"key.pem"),"\"" + " -orsa_cert_file=\"",filename:join(DataDir,"server-cert.pem"),"\"", + " -orsa_private_key_file=\"",filename:join(DataDir,"server-key.pem"),"\"" ], Result = os:cmd(Cmd), ct:log("Config file:~n~s~n~nServer start command:~n ~s~nResult:~n ~p", @@ -161,6 +162,7 @@ init_per_suite(Config) -> {ok,Data} -> TstDir = filename:join(?config(priv_dir,Config), "test"), file:make_dir(TstDir), + make_cert_files(dsa, rsa, "server-", ?config(data_dir,Config)), start_ftpd([{test_dir,TstDir}, {ftpd_data,Data} | Config]) @@ -505,7 +507,7 @@ recv_chunk(Config0) -> Pid = ?config(ftp, Config), {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), ok = ftp:recv_chunk_start(Pid, id2ftp(File,Config)), - {ok, ReceivedContents, Nchunks} = recv_chunk(Pid, <<>>), + {ok, ReceivedContents, _Ncunks} = recv_chunk(Pid, <<>>), find_diff(ReceivedContents, Contents). recv_chunk(Pid, Acc) -> recv_chunk(Pid, Acc, 0). @@ -584,6 +586,22 @@ ip_v6_disabled(_Config) -> %% Internal functions ----------------------------------------------- %%-------------------------------------------------------------------- +make_cert_files(Alg1, Alg2, Prefix, Dir) -> + CaInfo = {CaCert,_} = erl_make_certs:make_cert([{key,Alg1}]), + {Cert,CertKey} = erl_make_certs:make_cert([{key,Alg2},{issuer,CaInfo}]), + CaCertFile = filename:join(Dir, Prefix++"cacerts.pem"), + CertFile = filename:join(Dir, Prefix++"cert.pem"), + KeyFile = filename:join(Dir, Prefix++"key.pem"), + der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]), + der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]), + der_to_pem(KeyFile, [CertKey]), + ok. + +der_to_pem(File, Entries) -> + PemBin = public_key:pem_encode(Entries), + file:write_file(File, PemBin). + +%%-------------------------------------------------------------------- chk_file(Path=[C|_], ExpectedContents, Config) when 0 chk_file([Path], ExpectedContents, Config); @@ -679,7 +697,7 @@ not_available({Name,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}) -> %% start/stop of ftpd %% start_ftpd(Config) -> - {Name,StartCmd,ChkUp,_StopCommand,ConfigRewrite,Host,Port} = ?config(ftpd_data, Config), + {Name,StartCmd,_ChkUp,_StopCommand,ConfigRewrite,Host,Port} = ?config(ftpd_data, Config), case StartCmd(Config) of {ok,StartResult} -> [{ftpd_host,Host}, -- cgit v1.2.3 From 0d57daec5738447eb033681834146bf31dfd266c Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 19 Nov 2013 16:05:24 +0100 Subject: ftp,ssl: Fixes broken type link (ssloption). --- lib/inets/doc/src/ftp.xml | 2 +- lib/ssl/doc/src/ssl.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml index d528c2bb28..4d559817c4 100644 --- a/lib/inets/doc/src/ftp.xml +++ b/lib/inets/doc/src/ftp.xml @@ -554,7 +554,7 @@ ipfamily() = inet | inet6 | inet6fb4 (defaults to inet) port() = integer() > 0 (defaults to 21) mode() = active | passive (defaults to passive) - tls_options() = [ssl:ssloption()] + tls_options() = [ssl:ssloption()] timeout() = integer() > 0 (defaults to 60000 milliseconds) dtimeout() = integer() > 0 | infinity (defaults to infinity) pogress() = ignore | {module(), function(), initial_data()} (defaults to ignore) diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 19c0c8c9ee..1d74faf1b3 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -76,7 +76,7 @@ gen_tcp(3).

-

ssloption() = {verify, verify_type()} | +

ssloption() = {verify, verify_type()} | {verify_fun, {fun(), term()}} | {fail_if_no_peer_cert, boolean()} {depth, integer()} | -- cgit v1.2.3