cosfiletransfer_filetransfersession_impl.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,040 行 · 第 1/3 页
ERL
1,040 行
%%----------------------------------------------------------------------append(OE_This, State, SrcFile, DestFile) when ?is_ORBER_NATIVE(State) -> case which_FTS_type(OE_This, SrcFile, DestFile) of {source, TargetFTS} -> SrcName = filename:join('CosFileTransfer_File': '_get_complete_file_name'(SrcFile)), check_type(OE_This, State, SrcName), %% The source FTS is supposed to be the active one, set up a connection. Protocols = 'CosFileTransfer_FileTransferSession': '_get_protocols_supported'(TargetFTS), Pid = spawn(?MODULE, invoke_call, [self(), append, [TargetFTS, SrcFile, DestFile]]), send_file(Protocols, ?get_MyType(State), ?get_ConnectionTimeout(State), SrcName), check_reply(Pid), {reply, ok, State}; {target, _SourceFTS} -> DestName = filename:join('CosFileTransfer_File': '_get_complete_file_name'(DestFile)), check_type(OE_This, State, DestName), receive_file(?get_MyType(State), ?get_Connection(State), ?get_ConnectionTimeout(State), DestName, append), {reply, ok, State} end;append(OE_This, State, SrcFile, DestFile) when ?is_NATIVE(State) -> case which_FTS_type(OE_This, SrcFile, DestFile) of {source, TargetFTS} -> source_FTS_operation(State, SrcFile, DestFile, append, 0, TargetFTS); {target, _SourceFTS} -> target_FTS_operation(State, SrcFile, DestFile, append, 0) end;append(_OE_This, _State, _SrcFile, _DestFile) -> corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).%%----------------------------------------------------------------------%% Function : insert%% Arguments : SrcFile eq DestFile eq CosFileTransfer::File%% Offset - long%% Returns : -%% Description: %%----------------------------------------------------------------------insert(OE_This, State, SrcFile, DestFile, Offset) when ?is_NATIVE(State) -> case which_FTS_type(OE_This, SrcFile, DestFile) of {source, TargetFTS} when ?is_ORBER_NATIVE(State) -> SrcName = 'CosFileTransfer_File':'_get_complete_file_name'(SrcFile), check_type(OE_This, State, filename:join(SrcName)), %% The source FTS is supposed to be the active one, set up a connection. Protocols = 'CosFileTransfer_FileTransferSession': '_get_protocols_supported'(TargetFTS), Pid = spawn(?MODULE, invoke_call, [self(), insert, [TargetFTS, SrcFile, DestFile, Offset]]), send_file(Protocols, ?get_MyType(State), ?get_ConnectionTimeout(State), filename:join(SrcName)), check_reply(Pid), {reply, ok, State}; {source, TargetFTS} -> source_FTS_operation(State, SrcFile, DestFile, insert, Offset, TargetFTS); {target, _SourceFTS} -> target_FTS_operation(State, SrcFile, DestFile, insert, Offset) end;insert(_OE_This, _State, _SrcFile, _DestFile, _Offset) -> corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).%%----------------------------------------------------------------------%% Function : logout%% Arguments : -%% Returns : -%% Description: %%----------------------------------------------------------------------logout(_OE_This, State) when ?is_FTP(State); ?is_NATIVE(State) -> Mod = ?get_Module(State), catch Mod:close(?get_Server(State)), {stop, normal, ok, State}.%%======================================================================%% Internal functions%%======================================================================%%----------------------------------------------------------------------%% Function : oe_orber_create_directory_current%% Arguments : -%% Returns : Directory%% Description: Creates a Directory describing the working directory%% of the remote server, e.g., an FTP-server.%%----------------------------------------------------------------------oe_orber_create_directory_current(OE_This, State) when ?is_FTP(State); ?is_NATIVE(State) -> Mod = ?get_Module(State), FileNameList = filename:split(?get_CurrentDir(State)), case Mod:nlist(?get_Server(State), ?get_CurrentDir(State)) of {ok, _Listing} -> {reply, cosFileTransferApp:create_dir(OE_This, FileNameList), State}; {error, epath} -> corba:raise(#'CosFileTransfer_FileNotFoundException' {reason="Directory not found."}); {error, elogin} -> corba:raise(#'CosFileTransfer_SessionException' {reason="User not loggen in."}); {error, econn} -> corba:raise(#'CosFileTransfer_RequestFailureException' {reason="Premature connection ending."}); _ -> corba:raise(#'CosFileTransfer_RequestFailureException' {reason="Unknown error."}) end.%%----------------------------------------------------------------------%% Function : oe_orber_get_content%% Arguments : -%% Returns : string%% Description: %%----------------------------------------------------------------------oe_orber_get_content(OE_This, State, FileNameList, Parent) when ?is_FTP(State); ?is_NATIVE(State) -> Mod = ?get_Module(State), case Mod:nlist(?get_Server(State), filename:join(FileNameList)) of {ok, Listing} -> create_content(Listing, OE_This, State, Parent, FileNameList); {error, epath} -> {reply, [], State}; _ -> corba:raise(#'CosFileTransfer_FileNotFoundException' {reason="Directory not found."}) end.%%----------------------------------------------------------------------%% Function : oe_orber_count_children%% Arguments : -%% Returns : string%% Description: %%----------------------------------------------------------------------oe_orber_count_children(OE_This, State, FileNameList) when ?is_FTP(State); ?is_NATIVE(State) -> case catch check_type(OE_This, State, filename:join(FileNameList)) of {ndirectory, Members} -> {reply, length(Members), State}; {stop, normal, _, _} -> {stop, normal, {'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}, State}; _-> corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) end.%%----------------------------------------------------------------------%% Function : delete_tmp_file%% Arguments : -%% Returns : ok | {'EXCEPTION', E}%% Description: %%----------------------------------------------------------------------delete_tmp_file(TmpFileName, ErrorMsg) -> case file:delete(TmpFileName) of ok -> ok; _ -> corba:raise(#'CosFileTransfer_RequestFailureException'{reason=ErrorMsg}) end.%%----------------------------------------------------------------------%% Function : invoke_call%% Arguments : -%% Returns : ok | {'EXCEPTION', E}%% Description: %%----------------------------------------------------------------------invoke_call(Pid, Op, Args) -> Result = (catch apply('CosFileTransfer_FileTransferSession', Op, Args)), Pid ! {transfer_result, self(), Result}, ok.%%----------------------------------------------------------------------%% Function : check_reply%% Arguments : Pid - the pid of the spawned process.%% Returns : ok | {'EXCEPTION', E}%% Description: %%----------------------------------------------------------------------check_reply(Pid) -> receive {transfer_result, Pid, ok} -> ok; {transfer_result, Pid, {'EXCEPTION', E}} -> orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:check_reply();Raised exception: ", [?LINE, E], ?DEBUG_LEVEL), corba:raise(E); {transfer_result, Pid, {'EXIT', Reason}} -> orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:check_reply();Got EXIT-signal with reason: ", [?LINE, Reason], ?DEBUG_LEVEL), corba:raise(#'INTERNAL'{minor=199, completion_status=?COMPLETED_NO}) after infinity -> %% Should we add an exception here or do we reuse the iiop_timeout? %% For now keep as is. corba:raise(#'INTERNAL'{minor=199, completion_status=?COMPLETED_NO}) end.%%----------------------------------------------------------------------%% Function : which_FTS_type%% Arguments : -%% Returns : {source, FTS} | {target, FTS} | {'EXCEPTION', #'BAD_PARAM'{}}%% Description: Used to determine if the target FTS is supposed to act%% as sender or receiver and also return the counter part FTS. %% An exception is raised if the user supplied incorrect parameters.%%----------------------------------------------------------------------which_FTS_type(OE_This, SrcFile, DestFile) -> TargetFTS = 'CosFileTransfer_File':'_get_associated_session'(DestFile), SourceFTS = 'CosFileTransfer_File':'_get_associated_session'(SrcFile), case corba_object:is_equivalent(OE_This, TargetFTS) of true -> {target, SourceFTS}; false -> case corba_object:is_equivalent(OE_This, SourceFTS) of true -> {source, TargetFTS}; false -> corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) end end.%%----------------------------------------------------------------------%% Function : setup_connection%% Arguments : A list of #'CosFileTransfer_ProtocolSupport'{}%% Returns : %% Description: %%----------------------------------------------------------------------setup_connection([], Protocol, _) -> orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:setup_connection(~p);The Protocols listed are not supported.", [?LINE, Protocol], ?DEBUG_LEVEL), corba:raise(#'CosFileTransfer_TransferException'{reason="Unsupported protocol"});setup_connection([#'CosFileTransfer_ProtocolSupport'{protocol_name="TCP/IP", addresses=Addr}|_], tcp, Timeout) -> setup_connection_helper(Addr, gen_tcp, [], Timeout);setup_connection([#'CosFileTransfer_ProtocolSupport'{protocol_name="SSL", addresses=Addr}|_], ssl, Timeout) -> Options = [{certfile, cosFileTransferApp:ssl_client_certfile()}, {verify, cosFileTransferApp:ssl_client_verify()}, {depth, cosFileTransferApp:ssl_client_depth()}] ++ ssl_client_cacertfile_option(), setup_connection_helper(Addr, ssl, Options, Timeout);setup_connection([_|T], Type, Timeout) -> setup_connection(T, Type, Timeout).setup_connection_helper([], _, _, _) -> corba:raise(#'CosFileTransfer_RequestFailureException' {reason="Unable to contact remote server."});setup_connection_helper([H|T], Driver, Options, Timeout) -> case string:tokens(H, ":") of [Host, Port] when Driver == gen_tcp -> case gen_tcp:connect(Host, list_to_integer(Port), [binary, {packet, raw}, {reuseaddr, true}, {nodelay, true}|Options], Timeout) of {ok, Sock} -> {gen_tcp, Sock}; _-> %% No response. setup_connection_helper(T, Driver, Options, Timeout) end; [Host, Port] when Driver == ssl -> case ssl:connect(Host, list_to_integer(Port), [binary, {packet, 0}, {active, false}|Options], Timeout) of {ok, Sock} -> {ssl, Sock}; _-> %% No response. setup_connection_helper(T, Driver, Options, Timeout) end; _ -> %% Badly configured address. setup_connection_helper(T, Driver, Options, Timeout) end.ssl_client_cacertfile_option() -> case cosFileTransferApp:ssl_client_cacertfile() of [] -> []; X when list(X) -> {cacertfile, X}; _ -> [] end.%%----------------------------------------------------------------------%% Function : create_content%% Arguments : %% Returns : %% Description: %%----------------------------------------------------------------------create_content(Listing, OE_This, State, Parent, PathList) -> create_content(string:tokens(Listing, ?SEPARATOR), OE_This, State, Parent, PathList, []).create_content([], _OE_This, State, _Parent, _PathList, Acc) -> {reply, Acc, State};create_content([H|T], OE_This, State, Parent, PathList, Acc) -> FullPathList = PathList ++[filename:basename(H)], case check_type(OE_This, State, filename:join(FullPathList)) of nfile -> create_content(T, OE_This, State, Parent, PathList, [#'CosFileTransfer_FileWrapper' {the_file = cosFileTransferApp:create_file(OE_This, FullPathList, Parent), file_type = nfile}|Acc]); {ndirectory, _Members} -> create_content(T, OE_This, State, Parent, PathList, [#'CosFileTransfer_FileWrapper' {the_file = cosFileTransferApp:create_dir(OE_This, FullPathList, Parent), file_type = ndirectory}|Acc]); Other -> Other end. %%----------------------------------------------------------------------%% Function : MISC functions%% Arguments : %% Returns : %% Description: %%----------------------------------------------------------------------setup_local(tcp) -> {ok,Socket}=gen_tcp:listen(0, [binary, {packet, 0}, {backlog,1}, {active, false}]), {ok, Port} = inet:port(Socket), {Socket, [#'CosFileTransfer_ProtocolSupport'{protocol_name="TCP/IP", addresses = [local_address(Port)]}]};setup_local(ssl) -> Options = [{certfile, cosFileTransferApp:ssl_server_certfile()}, {verify, cosFileTransferApp:ssl_server_verify()}, {depth, cosFileTransferApp:ssl_server_depth()}] ++ ssl_server_cacertfile_option(), {ok,Socket}=ssl:listen(0, [binary, {packet, 0}, {backlog,1},
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?