aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl')
-rw-r--r--lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl1061
1 files changed, 0 insertions, 1061 deletions
diff --git a/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
deleted file mode 100644
index 3a8285f092..0000000000
--- a/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl
+++ /dev/null
@@ -1,1061 +0,0 @@
-%%----------------------------------------------------------------------
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% File : CosFileTransfer_FileTransferSession_impl.erl
-%% Description :
-%%
-%% Created : 12 Sept 2000
-%%----------------------------------------------------------------------
--module('CosFileTransfer_FileTransferSession_impl').
-
-
-%%----------------------------------------------------------------------
-%% Include files
-%%----------------------------------------------------------------------
--include_lib("orber/include/corba.hrl").
--include_lib("orber/src/orber_iiop.hrl").
-
--include("cosFileTransferApp.hrl").
-
-%%----------------------------------------------------------------------
-%% External exports
-%%----------------------------------------------------------------------
--export([init/1,
- terminate/2,
- code_change/3,
- handle_info/2]).
-
-%% Interface functions
--export(['_get_protocols_supported'/2,
- set_directory/3,
- create_file/3,
- create_directory/3,
- get_file/3,
- delete/3,
- transfer/4,
- append/4,
- insert/5,
- logout/2]).
-
-%%----------------------------------------------------------------------
-%% Internal exports
-%%----------------------------------------------------------------------
--export([oe_orber_create_directory_current/2, oe_orber_get_content/4,
- oe_orber_count_children/3]).
--export([invoke_call/3]).
-
-%%----------------------------------------------------------------------
-%% Records
-%%----------------------------------------------------------------------
--record(state, {protocols, server, type, current, module, connection, mytype,
- connection_timeout}).
-
-%%----------------------------------------------------------------------
-%% Macros
-%%----------------------------------------------------------------------
--define(create_InitState(P, S, T, C, M, Co, Ty, CT),
- #state{protocols=P, server=S, type=T, current=C, module=M, connection=Co,
- mytype=Ty, connection_timeout=CT}).
-
--define(get_Protocols(S), S#state.protocols).
--define(get_Server(S), S#state.server).
--define(get_CurrentDir(S), S#state.current).
--define(get_Module(S), S#state.module).
--define(get_Connection(S), S#state.connection).
--define(get_MyType(S), S#state.mytype).
--define(get_ConnectionTimeout(S), S#state.connection_timeout).
--define(set_CurrentDir(S, C), S#state{current=C}).
-
--define(is_FTP(S), S#state.type=='FTP').
--define(is_FTAM(S), S#state.type=='FTAM').
--define(is_NATIVE(S), S#state.type=='NATIVE').
--define(is_ORBER_NATIVE(S), S#state.module==cosFileTransferNATIVE_file).
-
-
-%%======================================================================
-%% External functions
-%%======================================================================
-%%----------------------------------------------------------------------
-%% Function : init/1
-%% Returns : {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% Description: Initiates the server
-%%----------------------------------------------------------------------
-init(['FTP', Host, Port, User, Password, _Account, Protocol, Timeout]) ->
- {ok, Pid} = inets:start(ftpc, [{host, Host}, {port, Port}], stand_alone),
- ok = ftp:user(Pid, User, Password),
- {ok, PWD} = ftp:pwd(Pid),
- {Connection, ProtocolSupport} = setup_local(Protocol),
- {ok, ?create_InitState(ProtocolSupport, Pid, 'FTP',
- PWD, ftp, Connection, Protocol, Timeout)};
-init([{'NATIVE', Mod}, Host, Port, User, Password, _Account, Protocol, Timeout]) ->
- {ok, Pid} = Mod:open(Host, Port),
- ok = Mod:user(Pid, User, Password),
- {ok, PWD} = Mod:pwd(Pid),
- {Connection, ProtocolSupport} = setup_local(Protocol),
- {ok, ?create_InitState(ProtocolSupport, Pid, 'NATIVE',
- PWD, Mod, Connection, Protocol, Timeout)}.
-
-
-%%----------------------------------------------------------------------
-%% Function : terminate/2
-%% Returns : any (ignored by gen_server)
-%% Description: Shutdown the server
-%%----------------------------------------------------------------------
-terminate(_Reason, #state{type = Type, server = Server, module = Mod} = State) ->
- case ?get_MyType(State) of
- ssl ->
- catch ssl:close(?get_Connection(State));
- _ ->
- catch gen_tcp:close(?get_Connection(State))
- end,
- case Type of
- 'FTP' ->
- inets:stop(ftpc, Server);
- 'NATIVE' ->
- Mod:close(Server);
- _ ->
- ok
- end,
- ok.
-
-%%----------------------------------------------------------------------
-%% Function : code_change/3
-%% Returns : {ok, NewState}
-%% Description: Convert process state when code is changed
-%%----------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%---------------------------------------------------------------------%
-%% function : handle_info/2
-%% Arguments:
-%% Returns :
-%% Effect :
-%%----------------------------------------------------------------------
-handle_info(Info, State) ->
- case Info of
- {'EXIT', _Pid, Reason} ->
- {stop, Reason, State};
- _Other ->
- {noreply, State}
- end.
-
-%%======================================================================
-%% CosFileTransfer::FileTransferSession
-%%======================================================================
-%%---------------------------------------------------------------------%
-%% Function : _get_protocols_supported
-%% Arguments :
-%% Returns : A list of CosFileTransfer::ProtocolSupport, i.e.,
-%% struct ProtocolSupport {
-%% Istring protocol_name;
-%% ProtocolAddressList addresses; %% eq a list of strings.
-%% };
-%% Description:
-%%----------------------------------------------------------------------
-'_get_protocols_supported'(_OE_This, State) ->
- {reply, ?get_Protocols(State), State}.
-
-%%----------------------------------------------------------------------
-%% Function : set_directory
-%% Arguments : Directory - CosFileTransfer::Directory
-%% Returns :
-%% Description:
-%%----------------------------------------------------------------------
-set_directory(_OE_This, State, Directory) when ?is_FTP(State); ?is_NATIVE(State) ->
- Mod = ?get_Module(State),
- Path = filename:join('CosFileTransfer_Directory':
- '_get_complete_file_name'(Directory)),
- case catch Mod:cd(?get_Server(State), Path) of
- ok ->
- {reply, ok, ?set_CurrentDir(State, Path)};
- {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 = "Unexpected error."})
- end.
-
-%%----------------------------------------------------------------------
-%% Function : create_file
-%% Arguments : FileNameList
-%% Returns : File
-%% Description: This operation creates a File Object representing a
-%% file which may or may not exist. Typically used as
-%% argument when invoking transfer/3. See also get_file/2.
-%%----------------------------------------------------------------------
-create_file(OE_This, State, FileNameList) ->
- {reply, cosFileTransferApp:create_file(OE_This, FileNameList), State}.
-
-%%----------------------------------------------------------------------
-%% Function : create_directory
-%% Arguments : FileNameList - full path name.
-%% Returns : Directory
-%% Description:
-%%----------------------------------------------------------------------
-create_directory(OE_This, State, FileNameList) when ?is_FTP(State);
- ?is_NATIVE(State) ->
- Mod = ?get_Module(State),
- case Mod:mkdir(?get_Server(State), filename:join(FileNameList)) of
- ok ->
- {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 : get_file
-%% Arguments : FileNameList
-%% Returns : FileWrapper
-%% Description: This operation should be independent of the working Directory,
-%% i.e., a full path name must be supplied. The file or
-%% directory the returned object is supposed to represent
-%% MUST(!!!!) exist.
-%%----------------------------------------------------------------------
-get_file(OE_This, State, FileNameList) when ?is_FTP(State);
- ?is_NATIVE(State) ->
- case check_type(OE_This, State, filename:join(FileNameList)) of
- {ndirectory, _Listing} ->
- {reply,
- #'CosFileTransfer_FileWrapper'{the_file =
- cosFileTransferApp:
- create_dir(OE_This,
- FileNameList),
- file_type = ndirectory},
- State};
- nfile ->
- {reply,
- #'CosFileTransfer_FileWrapper'{the_file =
- cosFileTransferApp:
- create_file(OE_This,
- FileNameList),
- file_type = nfile},
- State};
- Other ->
- %% If we want to return {stop, ....}
- Other
- end.
-
-%%----------------------------------------------------------------------
-%% Function : delete
-%% Arguments : File
-%% Returns : -
-%% Description:
-%%----------------------------------------------------------------------
-delete(_OE_This, State, File) when ?is_FTP(State); ?is_NATIVE(State) ->
- Mod = ?get_Module(State),
- Result =
- case 'CosPropertyService_PropertySet':
- get_property_value(File, "is_directory") of
- #any{value=false} ->
- Mod:delete(?get_Server(State),
- filename:join('CosFileTransfer_File':
- '_get_complete_file_name'(File)));
- #any{value=true} ->
- Mod:rmdir(?get_Server(State),
- filename:join('CosFileTransfer_File':
- '_get_complete_file_name'(File)));
- Other ->
- Other
- end,
- case Result of
- ok ->
- {reply, ok, State};
- {error, epath} ->
- corba:raise(#'CosFileTransfer_FileNotFoundException'
- {reason="File or 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 : transfer
-%% Arguments : SrcFile eq DestFile eq CosFileTransfer::File
-%% Returns : -
-%% Description: DestFile must be a newly created File object, using create_file()
-%% on the Target FileTransferSession, prior to calling transfer().
-%%----------------------------------------------------------------------
-transfer(OE_This, State, SrcFile, DestFile) when ?is_ORBER_NATIVE(State) ->
- case which_FTS_type(OE_This, SrcFile, DestFile) of
- {source, TargetFTS} ->
- %% The source FTS is supposed to be the active one, set up a connection.
- Protocols = 'CosFileTransfer_FileTransferSession':
- '_get_protocols_supported'(TargetFTS),
- SrcName = 'CosFileTransfer_File':'_get_complete_file_name'(SrcFile),
- Pid = spawn(?MODULE, invoke_call, [self(), transfer,
- [TargetFTS, SrcFile, DestFile]]),
- send_file(Protocols, ?get_MyType(State), ?get_ConnectionTimeout(State),
- filename:join(SrcName)),
- check_reply(Pid),
- {reply, ok, State};
- {target, _SourceFTS} ->
- DestName = 'CosFileTransfer_File':'_get_complete_file_name'(DestFile),
- receive_file(?get_MyType(State), ?get_Connection(State),
- ?get_ConnectionTimeout(State),
- filename:join(DestName), write),
- {reply, ok, State}
- end;
-transfer(OE_This, State, SrcFile, DestFile) when ?is_FTP(State); ?is_NATIVE(State) ->
- case which_FTS_type(OE_This, SrcFile, DestFile) of
- {source, TargetFTS} ->
- source_FTS_operation(State, SrcFile, DestFile, transfer, 0, TargetFTS);
- {target, _SourceFTS} ->
- target_FTS_operation(State, SrcFile, DestFile, send, 0)
- end.
-
-
-%%----------------------------------------------------------------------
-%% Function : append
-%% Arguments : SrcFile eq DestFile eq CosFileTransfer::File
-%% Returns : -
-%% Description:
-%%----------------------------------------------------------------------
-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 is_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},
- {active, false}|Options]),
- {ok, {_Address, Port}} = ssl:sockname(Socket),
- {Socket, [#'CosFileTransfer_ProtocolSupport'{protocol_name="SSL",
- addresses = [local_address(Port)]}]}.
-
-local_address(Port) ->
- {ok, Hostname} = inet:gethostname(),
- {ok, {A1, A2, A3, A4}} = inet:getaddr(Hostname, inet),
- integer_to_list(A1) ++ "." ++ integer_to_list(A2) ++ "." ++ integer_to_list(A3)
- ++ "." ++ integer_to_list(A4)++":"++integer_to_list(Port).
-
-ssl_server_cacertfile_option() ->
- case cosFileTransferApp:ssl_server_cacertfile() of
- [] ->
- [];
- X when is_list(X) ->
- [{cacertfile, X}];
- _ ->
- []
- end.
-
-%%----------------------------------------------------------------------
-%% Function : source_file_operation
-%% Arguments :
-%% Returns :
-%% Description:
-%%----------------------------------------------------------------------
-source_FTS_operation(State, SrcFile, DestFile, Op, Offset, FTS) ->
- Mod = ?get_Module(State),
- %% The source FTS is supposed to be the active one, set up a connection.
- Protocols = 'CosFileTransfer_FileTransferSession':'_get_protocols_supported'(FTS),
- SrcName = 'CosFileTransfer_File':'_get_complete_file_name'(SrcFile),
- TempName = cosFileTransferApp:create_name("TemporarySrcFile"),
- case Mod:recv(?get_Server(State), filename:join(SrcName), TempName) of
- ok when Op == insert ->
- %% Downloaded the File, we are now ready to transmit.
- Pid = spawn(?MODULE, invoke_call, [self(), insert,
- [FTS, SrcFile, DestFile, Offset]]),
- send_file(Protocols, ?get_MyType(State), ?get_ConnectionTimeout(State),
- TempName),
- %% Delete the temporary local copy.
- delete_tmp_file(TempName,
- "Transfer completed but failed to remove temporary local copy."),
- check_reply(Pid),
- {reply, ok, State};
- ok ->
- %% Downloaded the File, we are now ready to transmit.
- Pid = spawn(?MODULE, invoke_call, [self(), Op, [FTS, SrcFile, DestFile]]),
- send_file(Protocols, ?get_MyType(State), ?get_ConnectionTimeout(State),
- TempName),
- %% Delete the temporary local copy.
- delete_tmp_file(TempName,
- "Transfer completed but failed to remove temporary local copy."),
- check_reply(Pid),
- {reply, ok, State};
- {error, epath} ->
- corba:raise(#'CosFileTransfer_FileNotFoundException'
- {reason="File not found."});
- {error, elogin} ->
- corba:raise(#'CosFileTransfer_SessionException'
- {reason="User not loggen in."});
- {error, econn} ->
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="Premature connection ending."})
- end.
-
-%%----------------------------------------------------------------------
-%% Function : target_file_operation
-%% Arguments :
-%% Returns :
-%% Description:
-%%----------------------------------------------------------------------
-target_FTS_operation(State, _SrcFile, DestFile, Op, Offset) ->
- Mod = ?get_Module(State),
- DestName = 'CosFileTransfer_File':'_get_complete_file_name'(DestFile),
- TempName = cosFileTransferApp:create_name("TemporaryDestFile"),
- receive_file(?get_MyType(State), ?get_Connection(State),
- ?get_ConnectionTimeout(State), TempName, write),
- Result =
- if
- Op == insert ->
- Mod:insert(?get_Server(State), TempName, filename:join(DestName), Offset);
- true ->
- Mod:Op(?get_Server(State), TempName, filename:join(DestName))
- end,
- case Result of
- ok ->
- %% Delete the temporary local copy.
- delete_tmp_file(TempName,
- "Transfer completed but failed to remove temporary local copy."),
- %% Completed the transfer successfully.
- {reply, ok, State};
- {error, epath} ->
- delete_tmp_file(TempName,
- "IllegalOperationException and not able to remove temporary local copy."),
- corba:raise(#'CosFileTransfer_IllegalOperationException'
- {reason="Not allowed by destination."});
- {error, elogin} ->
- delete_tmp_file(TempName,
- "SessionException and not able to remove temporary local copy."),
- corba:raise(#'CosFileTransfer_SessionException'
- {reason="User not logged in."});
- {error, econn} ->
- delete_tmp_file(TempName,
- "TransferException and not able to remove temporary local copy."),
- corba:raise(#'CosFileTransfer_TransferException'
- {reason="Premature connection ending."});
- {error, etnospc} ->
- delete_tmp_file(TempName,
- "RequestFailureException and not able to remove temporary local copy."),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="Premature connection ending."});
- {error, efnamena} ->
- delete_tmp_file(TempName,
- "IllegalOperationException and not able to remove temporary local copy."),
- corba:raise(#'CosFileTransfer_IllegalOperationException'
- {reason="Not allowed by destination."})
- end.
-
-%%----------------------------------------------------------------------
-%% Function : receive_file
-%% Arguments : Driver - currently only gen_tcp supported.
-%% LSocket - which socket to use.
-%% FileName - an absolute file name representing the
-%% file we want to create or append to.
-%% Type - 'read', 'write', 'append'.
-%% Returns :
-%% Description:
-%%----------------------------------------------------------------------
-receive_file(tcp, LSock, Timeout, FileName, Type) ->
- %% The Type can be the ones allowed by the file-module, i.e.,
- %% 'read', 'write' or 'append'
- FD = file_open(FileName, Type),
- case gen_tcp:accept(LSock, Timeout) of
- {ok, Sock} ->
- receive_file_helper(gen_tcp, Sock, FD);
- {error, timeout} ->
- orber:dbg("[~p] CosFileTransfer_FileTransferSession:receive_file();~n"
- "gen_tcp:accept(~p) timed out", [?LINE, Timeout], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="TCP accept timed out.."});
- {error, Why} ->
- orber:dbg("[~p] CosFileTransfer_FileTransferSession:receive_file();~n"
- "gen_tcp:accept(~p) failed: ~p", [?LINE, Timeout, Why], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="TCP accept failed."})
- end;
-receive_file(ssl, LSock, Timeout, FileName, Type) ->
- %% The Type can be the ones allowed by the file-module, i.e.,
- %% 'read', 'write' or 'append'
- FD = file_open(FileName, Type),
- case ssl:transport_accept(LSock, Timeout) of
- {ok, Sock} ->
- case ssl:ssl_accept(Sock, Timeout) of
- ok ->
- receive_file_helper(ssl, Sock, FD);
- {error, Error} ->
- orber:dbg("[~p] CosFileTransfer_FileTransferSession:receive_file();~n"
- "ssl:ssl_accept(~p) failed: ~p",
- [?LINE, Timeout, Error], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="TCP accept failed."})
- end;
- {error, timeout} ->
- orber:dbg("[~p] CosFileTransfer_FileTransferSession:receive_file();~n"
- "ssl:transport_accept(~p) timed out",
- [?LINE, Timeout], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="TCP accept timed out.."});
- {error, Why} ->
- orber:dbg("[~p] CosFileTransfer_FileTransferSession:receive_file();~n"
- "ssl:transport_accept(~p) failed: ~p",
- [?LINE, Timeout, Why], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="TCP accept failed."})
- end.
-
-receive_file_helper(Driver, Sock, FD) ->
- case Driver:recv(Sock, 0) of
- {ok, Bin} ->
- file:write(FD, Bin),
- receive_file_helper(Driver, Sock, FD);
- {error, closed} ->
- file:close(FD);
- What ->
- orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:receive_file(~p);
-Error occured when receiving data: ~p", [?LINE, Driver, What], ?DEBUG_LEVEL),
- corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
- end.
-
-%%----------------------------------------------------------------------
-%% Function : send_file
-%% Arguments : Driver - currently only gen_tcp supported.
-%% Sock - which socket to use.
-%% FileName - an absolute file name representing the
-%% file we want to send.
-%% Returns :
-%% Description:
-%%----------------------------------------------------------------------
-send_file(Protocols, Type, Timeout, FileName) ->
- {Driver, Sock} = setup_connection(Protocols, Type, Timeout),
- FD = file_open(FileName, read),
- BuffSize = cosFileTransferApp:get_buffert_size(),
- send_file_helper(Driver, Sock, FD, BuffSize).
-
-send_file_helper(Driver, Sock, FD, BuffSize) ->
- case file:read(FD, BuffSize) of
- eof ->
- file:close(FD),
- Driver:close(Sock);
- {ok, Bin} ->
- case Driver:send(Sock, Bin) of
- ok ->
- send_file_helper(Driver, Sock, FD, BuffSize);
- What ->
- orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:send_file_helper(~p);
-Error occured when sending data: ~p", [?LINE, Driver, What], ?DEBUG_LEVEL),
- corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
- end
- end.
-
-
-file_open(File, Type) ->
- case file:open(File, [raw, binary, Type]) of
- {ok, FD} ->
- FD;
- {error, What} ->
- orber:debug_level_print("[~p] CosFileTransfer_FileTransferSession:file_open(~p);
-Failed to open the file due to: ~p", [?LINE, File, What], ?DEBUG_LEVEL),
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="Unable to open given file."})
- end.
-
-%%----------------------------------------------------------------------
-%% Function : check_type
-%% Arguments : FullName - an absolute file name representing the
-%% file or directory we want to evaluate.
-%% Returns :
-%% Description:
-%% When communcating with FTP-servers on different platforms a variety of
-%% answers can be returned. A few examples:
-%%
-%% ### ftp:nlist on an empty directory ###
-%% {ok, ""}, {error, epath}
-%%
-%% ### ftp:nlist on a non-existing directory or file ###
-%% {ok, "XXX: No such file or directory}, {error, epath}
-%%
-%% ### ftp:nlist on an existing directory with one contained item ###
-%% {ok, "Item"}
-%%
-%% Comparing the above we see that it's virtually impossible to tell apart
-%% {ok, "XXX: No such file or directory} and {ok, "Item"}.
-%% Hence, it's easier to test if it's possible to do ftp:cd instead.
-%% Ugly, but rather effective. If we look at the bright side, it's only
-%% necessary when we try to lookup:
-%% * non-existing item
-%% * A directory with one member only.
-%% * An empty directory.
-%%
-%% Furthermore, no need for traversing Listings etc.
-%%----------------------------------------------------------------------
-check_type(_OE_This, State, FullName) when ?is_FTP(State); ?is_NATIVE(State) ->
- Mod = ?get_Module(State),
- Result =
- case Mod:nlist(?get_Server(State), FullName) of
- {ok, Listing} when length(Listing) > 0->
- case string:tokens(Listing, ?SEPARATOR) of
- [FullName] ->
- nfile;
- Members when length(Members) > 1 ->
- %% Must test if more than one member since sometimes
- %% this operation returns for example:
- %% {ok, "XXX No such file or drectory"}
- {ndirectory, Members};
- Member ->
- case Mod:cd(?get_Server(State), FullName) of
- ok ->
- case Mod:cd(?get_Server(State),
- ?get_CurrentDir(State)) of
- ok ->
- {ndirectory, Member};
- _ ->
- %% Failed, we cannot continue since the
- %% FTS now pointso an incorrect Directory.
- %% Hence, we must terminate.
- {stop, normal,
- {'EXCEPTION',
- #'CosFileTransfer_RequestFailureException'
- {reason="Unknown error."}}, State}
- end;
- {error, E} ->
- {error, E};
- _ ->
- nfile
- end
- end;
- {error, epath} ->
- %% Might be a file.
- DirName = filename:dirname(FullName),
- case Mod:nlist(?get_Server(State), DirName) of
- {ok, Listing} when length(Listing) > 0->
- Members = string:tokens(Listing, ?SEPARATOR),
- case lists:member(FullName, Members) of
- true ->
- nfile;
- _ ->
- BName = filename:basename(FullName),
- case lists:member(BName, Members) of
- true ->
- nfile;
- _ ->
- {error, epath}
- end
- end;
- _ ->
- {error, epath}
- end;
- _ ->
- case Mod:cd(?get_Server(State), FullName) of
- ok ->
- case Mod:cd(?get_Server(State), ?get_CurrentDir(State)) of
- ok ->
- {ndirectory, []};
- _ ->
- %% Failed, we cannot continue since the
- %% FTS now pointso an incorrect Directory.
- %% Hence, we must terminate.
- {stop, normal,
- {'EXCEPTION',
- #'CosFileTransfer_RequestFailureException'
- {reason="Unknown error."}}, State}
- end;
- _ ->
- {error, epath}
- end
- end,
- case Result of
- {error, epath} ->
- corba:raise(#'CosFileTransfer_FileNotFoundException'
- {reason="File or Directory not found."});
- {error, elogin} ->
- corba:raise(#'CosFileTransfer_SessionException'
- {reason="User not logged in."});
- {error, econn} ->
- corba:raise(#'CosFileTransfer_RequestFailureException'
- {reason="Premature connection ending."});
- Other ->
- Other
- end.
-
-
-
-%%======================================================================
-%% END OF MODULE
-%%======================================================================