diff options
author | Erlang/OTP <otp@erlang.org> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosFileTransfer/src | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosFileTransfer/src')
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer.cfg | 10 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer.idl | 157 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl | 452 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl | 157 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl | 1060 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl | 384 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl | 216 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/Makefile | 182 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/cosFileTransfer.app.src | 41 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/cosFileTransfer.appup.src | 7 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/cosFileTransferApp.erl | 469 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/cosFileTransferApp.hrl | 68 | ||||
-rw-r--r-- | lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl | 358 |
13 files changed, 3561 insertions, 0 deletions
diff --git a/lib/cosFileTransfer/src/CosFileTransfer.cfg b/lib/cosFileTransfer/src/CosFileTransfer.cfg new file mode 100644 index 0000000000..a98f102e73 --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer.cfg @@ -0,0 +1,10 @@ +{this, "CosFileTransfer::Directory"}. +{{handle_info, "CosFileTransfer::Directory"}, true}. +{this, "CosFileTransfer::File"}. +{{handle_info, "CosFileTransfer::File"}, true}. +{this, "CosFileTransfer::VirtualFileSystem"}. +{{handle_info, "CosFileTransfer::VirtualFileSystem"}, true}. +{this, "CosFileTransfer::FileTransferSession"}. +{{handle_info, "CosFileTransfer::FileTransferSession"}, true}. +{this, "CosFileTransfer::FileIterator"}. +{{handle_info, "CosFileTransfer::FileIterator"}, true}. diff --git a/lib/cosFileTransfer/src/CosFileTransfer.idl b/lib/cosFileTransfer/src/CosFileTransfer.idl new file mode 100644 index 0000000000..2eb310478a --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer.idl @@ -0,0 +1,157 @@ +//File: CosFileTransfer.idl +#ifndef _COS_FILE_TRANSFER_IDL_ +#define _COS_FILE_TRANSFER_IDL_ + +#include <CosProperty.idl> +#pragma prefix "omg.org" + +module CosFileTransfer { + + typedef string Istring; + typedef Istring ProtocolAddress; + typedef long ContentType; + + const ContentType FTAM_1 = 1; + const ContentType FTAM_2 = 2; + const ContentType FTAM_3 = 3; + const ContentType FTAM_4 = 4; + const ContentType FTAM_5 = 5; + const ContentType NBS_9 = 6; + const ContentType INTAP_1 = 7; + + exception CommandNotImplementedException { Istring reason; }; + exception SessionException { Istring reason; }; + exception TransferException { Istring reason; }; + exception FileNotFoundException { Istring reason; }; + exception RequestFailureException { Istring reason; }; + exception IllegalOperationException { Istring reason; }; + + interface VirtualFileSystem; + + struct AccessLevel { + boolean read; + boolean insert; + boolean replace; + boolean extend; + boolean erase; + boolean read_attr; + boolean change_attr; + boolean delete; + }; + + typedef sequence<ProtocolAddress> ProtocolAddressList; + + struct ProtocolSupport { + Istring protocol_name; + ProtocolAddressList addresses; + }; + + typedef sequence<ProtocolSupport> SupportedProtocolAddresses; + + interface Directory; + interface FileTransferSession; + + typedef Istring FileName; + typedef sequence<FileName> FileNameList; + + interface File:CosPropertyService::PropertySetDef { + + readonly attribute FileName name; + readonly attribute FileNameList complete_file_name; + readonly attribute Directory parent; + readonly attribute FileTransferSession associated_session; + + }; + + enum FileType {nfile, ndirectory}; + + struct FileWrapper { + File the_file; + FileType file_type; + }; + + typedef sequence<FileWrapper> FileList; + + interface FileIterator; + interface Directory : File { + + void list(in unsigned long how_many, out FileList fl, out FileIterator fi); + + }; + + interface FileIterator { + + boolean next_one(out FileWrapper f); + boolean next_n(in unsigned long how_many, out FileList fl); + + void destroy(); + }; + + interface FileTransferSession { + + readonly attribute SupportedProtocolAddresses protocols_supported; + + void set_directory(in Directory new_directory) + raises(SessionException, FileNotFoundException, RequestFailureException, + IllegalOperationException); + + File create_file(in FileNameList name) + raises(SessionException, FileNotFoundException, RequestFailureException, + IllegalOperationException); + + Directory create_directory(in FileNameList name) + raises(SessionException, FileNotFoundException, RequestFailureException, + IllegalOperationException); + + FileWrapper get_file(in FileNameList complete_file_name) + raises(SessionException, FileNotFoundException, RequestFailureException, + IllegalOperationException); + + void delete(in File file) + raises(SessionException, FileNotFoundException, RequestFailureException, + IllegalOperationException); + + void transfer(in File src, in File dest) + raises(SessionException, TransferException, FileNotFoundException, + RequestFailureException, IllegalOperationException); + + void append(in File src, in File dest) + raises(CommandNotImplementedException, SessionException, TransferException, + FileNotFoundException, RequestFailureException, + IllegalOperationException); + + void insert(in File src, in File dest, in long offset) + raises(CommandNotImplementedException, SessionException, TransferException, + FileNotFoundException, RequestFailureException, + IllegalOperationException); + + void logout(); + + // WARNING!!! + // Theses are Orber specific operations and may only be used internally!! + // Maybe removed, altered and changed in any way without warning!! + Directory oe_orber_create_directory_current() + raises(SessionException, FileNotFoundException, IllegalOperationException); + FileList oe_orber_get_content(in FileNameList complete_file_name, + in Directory parent); + long oe_orber_count_children(in FileNameList complete_file_name); + + }; + + interface VirtualFileSystem { + + enum NativeFileSystemType { FTAM, FTP, NATIVE }; + + readonly attribute NativeFileSystemType file_system_type; + + typedef sequence<ContentType> ContentList; + + readonly attribute ContentList supported_content_types; + + FileTransferSession login(in Istring username, in Istring password, + in Istring account, out Directory root) + raises(SessionException, FileNotFoundException, IllegalOperationException); + }; +}; + +#endif //_COS_FILE_TRANSFER_IDL_ diff --git a/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl new file mode 100644 index 0000000000..cecc42ecc1 --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer_Directory_impl.erl @@ -0,0 +1,452 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosFileTransfer_Directory_impl +%% Description : +%% +%% Created : 12 Sept 2000 +%%---------------------------------------------------------------------- +-module('CosFileTransfer_Directory_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-include_lib("cosProperty/include/CosPropertyService.hrl"). + +-include("cosFileTransferApp.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2]). + +%% Interface functions +-export([list/3]). + +%% Inherited CosFileTransfer::File +-export(['_get_name'/2, + '_get_complete_file_name'/2, + '_get_parent'/2, + '_get_associated_session'/2]). + +%% Inherited CosPropertyService::PropertySetDef +-export([get_allowed_property_types/2, + get_allowed_properties/2, + define_property_with_mode/5, + define_properties_with_modes/3, + get_property_mode/3, + get_property_modes/3, + set_property_mode/4, + set_property_modes/3]). + +%% Inherited CosPropertyService::PropertySet +-export([define_property/4, + define_properties/3, + get_number_of_properties/2, + get_all_property_names/3, + get_property_value/3, + get_properties/3, + get_all_properties/3, + delete_property/3, + delete_properties/3, + delete_all_properties/2, + is_property_defined/3]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {property, + name, + completeName, + parent, + assocSession}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(create_InitState(Pr, N, C, Pa, A), + #state{property = Pr, + name = N, + completeName = C, + parent = Pa, + assocSession = A}). + +-define(get_PropertyRef(S), S#state.property). +-define(get_Name(S), S#state.name). +-define(get_CompleteName(S), S#state.completeName). +-define(get_Parent(S), S#state.parent). +-define(get_AssocSession(S), S#state.assocSession). + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([Name, CompleteName, Parent, AssocSession]) -> + PropTypes = [tk_long, tk_boolean], + %% WARNING if the order of the properties is changed so must + %% get_all_properties/3 in this module be as well! + PropDefs = [#'CosPropertyService_PropertyDef' + {property_name = "num_children", + property_value = #any{typecode=tk_long, value=0}, + property_mode = fixed_readonly}, + #'CosPropertyService_PropertyDef' + {property_name = "is_directory", + property_value = #any{typecode=tk_boolean, value=true}, + property_mode = fixed_readonly}], + Prop = cosProperty:create_static_SetDef(PropTypes, PropDefs), + {ok, ?create_InitState(Prop, Name, CompleteName, Parent, AssocSession)}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%====================================================================== +%% CosFileTransfer::Directory +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : list +%% Arguments : Max - ulong() +%% Returns : {ok, FileList, FileIterator} +%% Description: +%%---------------------------------------------------------------------- +list(OE_This, State, Max) -> + case 'CosFileTransfer_FileTransferSession': + oe_orber_get_content(?get_AssocSession(State), ?get_CompleteName(State), + OE_This) of + [] -> + {reply, {ok, [], corba:create_nil_objref()}, State}; + FileList when length(FileList) > Max -> + {reply, + {ok, lists:sublist(FileList, Max), + 'CosFileTransfer_FileIterator':oe_create([lists:nthtail(Max, + FileList)])}, + State}; + FileList -> + {reply, {ok, FileList, corba:create_nil_objref()}, State} + end. + +%%====================================================================== +%% CosFileTransfer::File +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : '_get_name' +%% Arguments : - +%% Returns : CosFileTransfer::FileName - string +%% Description: +%%---------------------------------------------------------------------- +'_get_name'(_OE_This, State) -> + {reply, ?get_Name(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_complete_file_name' +%% Arguments : - +%% Returns : CosFileTransfer::FileNameList - a list of strings's +%% Description: +%%---------------------------------------------------------------------- +'_get_complete_file_name'(_OE_This, State) -> + {reply, ?get_CompleteName(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_parent' +%% Arguments : - +%% Returns : CosFileTransfer::Directory +%% Description: +%%---------------------------------------------------------------------- +'_get_parent'(_OE_This, State) -> + {reply, ?get_Parent(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_associated_session' +%% Arguments : - +%% Returns : CosFileTransfer::FileTransferSession +%% Description: +%%---------------------------------------------------------------------- +'_get_associated_session'(_OE_This, State) -> + {reply, ?get_AssocSession(State), State}. + +%%====================================================================== +%% CosPropertyService::PropertySetDef +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : get_allowed_property_types +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_allowed_property_types(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySetDef': + get_allowed_property_types(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : get_allowed_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_allowed_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySetDef': + get_allowed_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : define_property_with_mode +%% Arguments : Name - string() +%% Value - #any{} +%% Mode - normal | read_only | fixed_normal | fixed_readonly +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_property_with_mode(_OE_This, State, Name, Value, Mode) -> + {reply, 'CosPropertyService_PropertySetDef': + define_property_with_mode(?get_PropertyRef(State), Name, Value, Mode), State}. + +%%---------------------------------------------------------------------% +%% Function : define_properties_with_modes +%% Arguments : PropertyDefs - list of #'CosPropertyService_PropertyDef'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_properties_with_modes(_OE_This, State, PropertyDefs) -> + {reply, 'CosPropertyService_PropertySetDef': + define_properties_with_modes(?get_PropertyRef(State), PropertyDefs), State}. + +%%---------------------------------------------------------------------% +%% Function : get_property_mode +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_mode(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySetDef': + get_property_mode(?get_PropertyRef(State), Name), State}. + + +%%---------------------------------------------------------------------% +%% Function : get_property_modes +%% Arguments : Names - a list of Name (i.e. string()'s). +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_modes(_OE_This, State, Names) -> + {reply, 'CosPropertyService_PropertySetDef': + get_property_modes(?get_PropertyRef(State), Names), State}. + +%%---------------------------------------------------------------------% +%% Function : set_property_mode +%% Arguments : Name - string() +%% Mode - normal | read_only | fixed_normal | fixed_readonly +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +set_property_mode(_OE_This, State, Name, Mode) -> + {reply, 'CosPropertyService_PropertySetDef': + set_property_mode(?get_PropertyRef(State), Name, Mode), State}. + + +%%---------------------------------------------------------------------% +%% Function : set_property_modes +%% Arguments : Modes - a list of #'CosPropertyService_PropertyModes'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +set_property_modes(_OE_This, State, PropertyModes) -> + {reply, 'CosPropertyService_PropertySetDef': + set_property_modes(?get_PropertyRef(State), PropertyModes), State}. + +%%====================================================================== +%% CosPropertyService::PropertySet +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : define_property +%% Arguments : Name - string() +%% Value - #any{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_property(_OE_This, State, Name, Value) -> + {reply, 'CosPropertyService_PropertySet': + define_property(?get_PropertyRef(State), Name, Value), State}. + +%%---------------------------------------------------------------------% +%% Function : define_properties +%% Arguments : Properties - a list of #'CosPropertyService_Property'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_properties(_OE_This, State, Properties) -> + {reply, 'CosPropertyService_PropertySet': + define_properties(?get_PropertyRef(State), Properties), State}. + + +%%---------------------------------------------------------------------% +%% Function : get_number_of_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_number_of_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySet': + get_number_of_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : get_all_property_names +%% Arguments : Max - ulong() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_all_property_names(_OE_This, State, Max) -> + {reply, 'CosPropertyService_PropertySet': + get_all_property_names(?get_PropertyRef(State), Max), State}. + +%%---------------------------------------------------------------------% +%% Function : get_property_value +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_value(_OE_This, State, "num_children") -> + Count = 'CosFileTransfer_FileTransferSession': + oe_orber_count_children(?get_AssocSession(State), ?get_CompleteName(State)), + {reply, #any{typecode=tk_long, value=Count}, State}; +get_property_value(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + get_property_value(?get_PropertyRef(State), Name), State}. + +%%---------------------------------------------------------------------% +%% Function : get_properties +%% Arguments : Names - a list of Name (i.e. string()'s) +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_properties(_OE_This, State, Names) -> + {Bool, Props} = + 'CosPropertyService_PropertySet':get_properties(?get_PropertyRef(State), + Names), + NewProps = change_property(Props, [], State), + {reply, {Bool, NewProps}, State}. + +change_property([], Acc, _State) -> + Acc; +change_property([H|T], Acc, State) -> + NewAcc = + case H of + #'CosPropertyService_Property'{property_name = "num_children"} -> + Count = 'CosFileTransfer_FileTransferSession': + oe_orber_count_children(?get_AssocSession(State), + ?get_CompleteName(State)), + [H#'CosPropertyService_Property' + {property_value = #any{typecode=tk_long, value=Count}}|Acc]; + _ -> + [H|Acc] + end, + change_property(T, NewAcc, State). + +%%---------------------------------------------------------------------% +%% Function : get_all_properties +%% Arguments : Max - ulong() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_all_properties(_OE_This, State, 0) -> + %% WARNING if we start supporting more than 10 Properties the next line must + %% be updated! + {ok, Props, _Iterator} = + 'CosPropertyService_PropertySet':get_all_properties(?get_PropertyRef(State), + 10), + NewProps = change_property(Props, [], State), + %% WARNING if the cosProperty:start_PropertiesIterator/1 is updated + %% it must be done hear as well. + {reply, {ok, [], cosProperty:start_PropertiesIterator(NewProps)}, State}; +get_all_properties(_OE_This, State, Max) -> + {ok, Props, Iterator} = + 'CosPropertyService_PropertySet':get_all_properties(?get_PropertyRef(State), + Max), + NewProps = change_property(Props, [], State), + {reply, {ok, NewProps, Iterator}, State}. + +%%---------------------------------------------------------------------% +%% Function : delete_property +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_property(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + delete_property(?get_PropertyRef(State), Name), State}. + + +%%---------------------------------------------------------------------% +%% Function : delete_properties +%% Arguments : Names - a list of Name (i.e. string()'s) +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_properties(_OE_This, State, Names) -> + {reply, 'CosPropertyService_PropertySet': + delete_properties(?get_PropertyRef(State), Names), State}. + + +%%---------------------------------------------------------------------% +%% Function : delete_all_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_all_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySet': + delete_all_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : is_property_defined +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +is_property_defined(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + is_property_defined(?get_PropertyRef(State), Name), State}. + +%%====================================================================== +%% Internal functions +%%====================================================================== + +%%====================================================================== +%% END OF MODULE +%%====================================================================== + diff --git a/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl new file mode 100644 index 0000000000..2800c19d46 --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer_FileIterator_impl.erl @@ -0,0 +1,157 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosFileTransfer_FileIterator_impl.erl +%% Description : +%% +%% Created : 12 Sept 2000 +%%---------------------------------------------------------------------- +-module('CosFileTransfer_FileIterator_impl'). + + + + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include("cosFileTransferApp.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2, + code_change/3, + handle_info/2]). + +%% Interface functions +-export([next_one/2, + next_n/3, + destroy/2]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([FileList]) -> + {ok, FileList}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + 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::FileIterator +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : next_one +%% Arguments : +%% Returns : {boolean(), FileWrapper} +%% Description: +%%---------------------------------------------------------------------- +next_one(_OE_This, []) -> + {reply, {false, + #'CosFileTransfer_FileWrapper'{the_file = corba:create_nil_objref(), + file_type = nfile}}, []}; +next_one(_OE_This, [FileWrapper]) -> + {reply, {true, FileWrapper}, []}; +next_one(_OE_This, [FileWrapper|Rest]) -> + {reply, {true, FileWrapper}, Rest}. + +%%---------------------------------------------------------------------% +%% Function : next_n +%% Arguments : HowMany - ulong() +%% Returns : {boolean(), FileWrapperList} +%% Description: +%%---------------------------------------------------------------------- +next_n(_OE_This, [], _) -> + {reply, {false, []}, []}; +next_n(_OE_This, FileWrapperList, HowMany) when HowMany > length(FileWrapperList) -> + {reply, {true, FileWrapperList}, []}; +next_n(_OE_This, FileWrapperList, HowMany) -> + {reply, {true, lists:sublist(FileWrapperList, HowMany)}, + lists:nthtail(HowMany, FileWrapperList)}. + +%%---------------------------------------------------------------------% +%% Function : destroy +%% Arguments : - +%% Returns : - +%% Description: +%%---------------------------------------------------------------------- +destroy(_OE_This, State) -> + {stop, normal, ok, State}. + + +%%====================================================================== +%% Internal functions +%%====================================================================== + + + +%%====================================================================== +%% END OF MODULE +%%====================================================================== diff --git a/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl new file mode 100644 index 0000000000..e222c5b92b --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer_FileTransferSession_impl.erl @@ -0,0 +1,1060 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% 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 succesfully. + {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 +%%====================================================================== diff --git a/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl new file mode 100644 index 0000000000..7ee189f05b --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer_File_impl.erl @@ -0,0 +1,384 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosFileTransfer_File_impl.erl +%% Description : +%% +%% Created : 5 Feb 2001 +%%---------------------------------------------------------------------- +-module('CosFileTransfer_File_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-include_lib("cosProperty/include/CosPropertyService.hrl"). + +-include("cosFileTransferApp.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2]). + +%% Interface functions +-export(['_get_name'/2, + '_get_complete_file_name'/2, + '_get_parent'/2, + '_get_associated_session'/2]). + +%% Inherited CosPropertyService::PropertySetDef +-export([get_allowed_property_types/2, + get_allowed_properties/2, + define_property_with_mode/5, + define_properties_with_modes/3, + get_property_mode/3, + get_property_modes/3, + set_property_mode/4, + set_property_modes/3]). + +%% Inherited CosPropertyService::PropertySet +-export([define_property/4, + define_properties/3, + get_number_of_properties/2, + get_all_property_names/3, + get_property_value/3, + get_properties/3, + get_all_properties/3, + delete_property/3, + delete_properties/3, + delete_all_properties/2, + is_property_defined/3]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {property, + name, + completeName, + parent, + assocSession}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(create_InitState(Pr, N, C, Pa, A), + #state{property = Pr, + name = N, + completeName = C, + parent = Pa, + assocSession = A}). + +-define(get_PropertyRef(S), S#state.property). +-define(get_Name(S), S#state.name). +-define(get_CompleteName(S), S#state.completeName). +-define(get_Parent(S), S#state.parent). +-define(get_AssocSession(S), S#state.assocSession). + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([Name, CompleteName, Parent, AssocSession]) -> + PropTypes = [tk_boolean], + PropDefs = [#'CosPropertyService_PropertyDef' + {property_name = "is_directory", + property_value = #any{typecode=tk_boolean, value=false}, + property_mode = fixed_readonly}], + Prop = cosProperty:create_static_SetDef(PropTypes, PropDefs), + {ok, ?create_InitState(Prop, Name, CompleteName, Parent, AssocSession)}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%====================================================================== +%% CosFileTransfer::File +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : '_get_name' +%% Arguments : - +%% Returns : CosFileTransfer::FileName - string +%% Description: +%%---------------------------------------------------------------------- +'_get_name'(_OE_This, State) -> + {reply, ?get_Name(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_complete_file_name' +%% Arguments : - +%% Returns : CosFileTransfer::FileNameList - a list of strings's +%% Description: +%%---------------------------------------------------------------------- +'_get_complete_file_name'(_OE_This, State) -> + {reply, ?get_CompleteName(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_parent' +%% Arguments : - +%% Returns : CosFileTransfer::Directory +%% Description: +%%---------------------------------------------------------------------- +'_get_parent'(_OE_This, State) -> + {reply, ?get_Parent(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_associated_session' +%% Arguments : - +%% Returns : CosFileTransfer::FileTransferSession +%% Description: +%%---------------------------------------------------------------------- +'_get_associated_session'(_OE_This, State) -> + {reply, ?get_AssocSession(State), State}. + +%%====================================================================== +%% CosPropertyService::PropertySetDef +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : get_allowed_property_types +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_allowed_property_types(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySetDef': + get_allowed_property_types(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : get_allowed_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_allowed_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySetDef': + get_allowed_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : define_property_with_mode +%% Arguments : Name - string() +%% Value - #any{} +%% Mode - normal | read_only | fixed_normal | fixed_readonly +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_property_with_mode(_OE_This, State, Name, Value, Mode) -> + {reply, 'CosPropertyService_PropertySetDef': + define_property_with_mode(?get_PropertyRef(State), Name, Value, Mode), State}. + +%%---------------------------------------------------------------------% +%% Function : define_properties_with_modes +%% Arguments : PropertyDefs - list of #'CosPropertyService_PropertyDef'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_properties_with_modes(_OE_This, State, PropertyDefs) -> + {reply, 'CosPropertyService_PropertySetDef': + define_properties_with_modes(?get_PropertyRef(State), PropertyDefs), State}. + +%%---------------------------------------------------------------------% +%% Function : get_property_mode +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_mode(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySetDef': + get_property_mode(?get_PropertyRef(State), Name), State}. + + +%%---------------------------------------------------------------------% +%% Function : get_property_modes +%% Arguments : Names - a list of Name (i.e. string()'s). +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_modes(_OE_This, State, Names) -> + {reply, 'CosPropertyService_PropertySetDef': + get_property_modes(?get_PropertyRef(State), Names), State}. + +%%---------------------------------------------------------------------% +%% Function : set_property_mode +%% Arguments : Name - string() +%% Mode - normal | read_only | fixed_normal | fixed_readonly +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +set_property_mode(_OE_This, State, Name, Mode) -> + {reply, 'CosPropertyService_PropertySetDef': + set_property_mode(?get_PropertyRef(State), Name, Mode), State}. + + +%%---------------------------------------------------------------------% +%% Function : set_property_modes +%% Arguments : Modes - a list of #'CosPropertyService_PropertyModes'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +set_property_modes(_OE_This, State, PropertyModes) -> + {reply, 'CosPropertyService_PropertySetDef': + set_property_modes(?get_PropertyRef(State), PropertyModes), State}. + +%%====================================================================== +%% CosPropertyService::PropertySet +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : define_property +%% Arguments : Name - string() +%% Value - #any{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_property(_OE_This, State, Name, Value) -> + {reply, 'CosPropertyService_PropertySet': + define_property(?get_PropertyRef(State), Name, Value), State}. + +%%---------------------------------------------------------------------% +%% Function : define_properties +%% Arguments : Properties - a list of #'CosPropertyService_Property'{} +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +define_properties(_OE_This, State, Properties) -> + {reply, 'CosPropertyService_PropertySet': + define_properties(?get_PropertyRef(State), Properties), State}. + + +%%---------------------------------------------------------------------% +%% Function : get_number_of_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_number_of_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySet': + get_number_of_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : get_all_property_names +%% Arguments : Max - ulong() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_all_property_names(_OE_This, State, Max) -> + {reply, 'CosPropertyService_PropertySet': + get_all_property_names(?get_PropertyRef(State), Max), State}. + +%%---------------------------------------------------------------------% +%% Function : get_property_value +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_property_value(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + get_property_value(?get_PropertyRef(State), Name), State}. + +%%---------------------------------------------------------------------% +%% Function : get_properties +%% Arguments : Names - a list of Name (i.e. string()'s) +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_properties(_OE_This, State, Names) -> + {reply, 'CosPropertyService_PropertySet': + get_properties(?get_PropertyRef(State), Names), State}. + + +%%---------------------------------------------------------------------% +%% Function : get_all_properties +%% Arguments : Max - ulong() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +get_all_properties(_OE_This, State, Max) -> + {reply, 'CosPropertyService_PropertySet': + get_all_properties(?get_PropertyRef(State), Max), State}. + + +%%---------------------------------------------------------------------% +%% Function : delete_property +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_property(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + delete_property(?get_PropertyRef(State), Name), State}. + + +%%---------------------------------------------------------------------% +%% Function : delete_properties +%% Arguments : Names - a list of Name (i.e. string()'s) +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_properties(_OE_This, State, Names) -> + {reply, 'CosPropertyService_PropertySet': + delete_properties(?get_PropertyRef(State), Names), State}. + + +%%---------------------------------------------------------------------% +%% Function : delete_all_properties +%% Arguments : - +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +delete_all_properties(_OE_This, State) -> + {reply, 'CosPropertyService_PropertySet': + delete_all_properties(?get_PropertyRef(State)), State}. + +%%---------------------------------------------------------------------% +%% Function : is_property_defined +%% Arguments : Name - string() +%% Returns : See cosProperty application. +%% Description: +%%---------------------------------------------------------------------- +is_property_defined(_OE_This, State, Name) -> + {reply, 'CosPropertyService_PropertySet': + is_property_defined(?get_PropertyRef(State), Name), State}. + +%%====================================================================== +%% Internal functions +%%====================================================================== + +%%====================================================================== +%% END OF MODULE +%%====================================================================== + diff --git a/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl b/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl new file mode 100644 index 0000000000..7a775f2b13 --- /dev/null +++ b/lib/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_impl.erl @@ -0,0 +1,216 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosFileTransfer_VirtualFileSystem_impl.erl +%% Description : +%% +%% Created : 12 Sept 2000 +%%---------------------------------------------------------------------- +-module('CosFileTransfer_VirtualFileSystem_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). + +-include_lib("cosFileTransfer/include/CosFileTransfer.hrl"). +-include("cosFileTransferApp.hrl"). + + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2, + code_change/3, + handle_info/2]). + +%% Interface functions +-export(['_get_file_system_type'/2, + '_get_supported_content_types'/2, + login/5]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {type, content, host, port, protocol, timeout, module}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(create_InitState(T, C, H, P, Pr, TO), + #state{type=T, + content=C, + host=H, + port=P, + protocol=Pr, + timeout=TO}). +-define(create_NativeInitState(T, C, H, P, Pr, TO, M), + #state{type=T, + content=C, + host=H, + port=P, + protocol=Pr, + timeout=TO, + module=M}). + +-define(get_Type(S), S#state.type). +-define(get_Content(S), S#state.content). +-define(get_Host(S), S#state.host). +-define(get_Port(S), S#state.port). +-define(get_StartDir(S), S#state.startdir). +-define(get_Module(S), S#state.module). +-define(get_Protocol(S), S#state.protocol). +-define(get_Timeout(S), S#state.timeout). + +-define(is_FTP(S), S#state.type == 'FTP'). +-define(is_FTAM(S), S#state.type == 'FTAM'). +-define(is_NATIVE(S), S#state.type == 'NATIVE'). + + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([{Type, Mod}, Content, Host, Port, Options]) -> + Prot = cosFileTransferApp:get_option(protocol, Options, ?DEFAULT_CONFIG), + Time = timer:seconds(cosFileTransferApp:get_option(connect_timeout, Options, + ?DEFAULT_CONFIG)), + {ok, ?create_NativeInitState(Type, Content, Host, Port, Prot, Time, Mod)}; +init([Type, Content, Host, Port, Options]) -> + Prot = cosFileTransferApp:get_option(protocol, Options, ?DEFAULT_CONFIG), + Time = timer:seconds(cosFileTransferApp:get_option(connect_timeout, Options, + ?DEFAULT_CONFIG)), + {ok, ?create_InitState(Type, Content, Host, Port, Prot, Time)}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + 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) -> + {noreply, State}. + +%%====================================================================== +%% CosFileTransfer::VirtualFileSystem +%%====================================================================== +%%---------------------------------------------------------------------% +%% Function : '_get_file_system_type' +%% Arguments : - +%% Returns : CosFileTransfer::NativeFileSystemType, i.e., 'FTP', 'FTAM', +%% or 'NATIVE'. Currently only 'FTP' is allowed. +%% Description: +%%---------------------------------------------------------------------- +'_get_file_system_type'(_OE_This, State) -> + {reply, ?get_Type(State), State}. + +%%---------------------------------------------------------------------% +%% Function : '_get_supported_content_types' +%% Arguments : +%% Returns : +%% Description: +%%---------------------------------------------------------------------- +'_get_supported_content_types'(_OE_This, State) -> + {reply, ?get_Content(State), State}. + +%%---------------------------------------------------------------------- +%% Function : login +%% Arguments : User - string() +%% Password - string() +%% Account - string() +%% Returns : FileTransferSession object and Directory object (out-type). +%% Description: +%%---------------------------------------------------------------------- +login(_OE_This, State, User, Password, Account) when ?is_FTP(State) -> + case catch 'CosFileTransfer_FileTransferSession': + oe_create(['FTP', ?get_Host(State), ?get_Port(State), User, Password, Account, + ?get_Protocol(State), ?get_Timeout(State)], + [{sup_child, true}]) of + {ok, _Pid, FTS} -> + Dir = 'CosFileTransfer_FileTransferSession': + oe_orber_create_directory_current(FTS), + {reply, {FTS, Dir}, State}; + What -> + orber:debug_level_print("[~p] CosFileTransfer_VirtualFileSystem:login(~p ~p ~p ~p); +Unable to create a FileTransferSession: ~p", + [?LINE, ?get_Host(State), ?get_Port(State), User, + ?get_Protocol(State), What], + ?DEBUG_LEVEL), + corba:raise(#'CosFileTransfer_SessionException'{reason="Failed creating a FTS"}) + end; +login(_OE_This, State, User, Password, Account) when ?is_NATIVE(State) -> + case catch 'CosFileTransfer_FileTransferSession': + oe_create([{'NATIVE', ?get_Module(State)}, ?get_Host(State), + ?get_Port(State), User, Password, Account, + ?get_Protocol(State), ?get_Timeout(State)], + [{sup_child, true}]) of + {ok, _Pid, FTS} -> + Dir = 'CosFileTransfer_FileTransferSession': + oe_orber_create_directory_current(FTS), + {reply, {FTS, Dir}, State}; + What -> + orber:debug_level_print("[~p] CosFileTransfer_VirtualFileSystem:login(~p ~p ~p ~p); +Unable to create a FileTransferSession: ~p", + [?LINE, ?get_Host(State), ?get_Port(State), User, + ?get_Protocol(State), What], + ?DEBUG_LEVEL), + corba:raise(#'CosFileTransfer_SessionException'{reason="Failed creating a FTS"}) + end. + +%%====================================================================== +%% Internal functions +%%====================================================================== + + + +%%====================================================================== +%% END OF MODULE +%%====================================================================== diff --git a/lib/cosFileTransfer/src/Makefile b/lib/cosFileTransfer/src/Makefile new file mode 100644 index 0000000000..773ed7f6b7 --- /dev/null +++ b/lib/cosFileTransfer/src/Makefile @@ -0,0 +1,182 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2000-2009. 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% +# +# +include $(ERL_TOP)/make/target.mk + +ifeq ($(TYPE),debug) +ERL_COMPILE_FLAGS += -Ddebug -W +endif + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSFILETRANSFER_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/cosFileTransfer-$(VSN) + +EXTERNAL_INC_PATH = ../include + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES = \ + cosFileTransferApp \ + CosFileTransfer_Directory_impl \ + CosFileTransfer_File_impl \ + CosFileTransfer_VirtualFileSystem_impl \ + CosFileTransfer_FileTransferSession_impl \ + CosFileTransfer_FileIterator_impl \ + cosFileTransferNATIVE_file \ + +ERL_FILES = $(MODULES:%=%.erl) +HRL_FILES = \ + cosFileTransferApp.hrl \ + +GEN_ERL_FILES = \ + oe_CosFileTransfer.erl \ + CosFileTransfer.erl \ + CosFileTransfer_AccessLevel.erl \ + CosFileTransfer_CommandNotImplementedException.erl \ + CosFileTransfer_Directory.erl \ + CosFileTransfer_File.erl \ + CosFileTransfer_FileIterator.erl \ + CosFileTransfer_FileList.erl \ + CosFileTransfer_FileNameList.erl \ + CosFileTransfer_FileNotFoundException.erl \ + CosFileTransfer_FileTransferSession.erl \ + CosFileTransfer_FileWrapper.erl \ + CosFileTransfer_IllegalOperationException.erl \ + CosFileTransfer_ProtocolAddressList.erl \ + CosFileTransfer_ProtocolSupport.erl \ + CosFileTransfer_RequestFailureException.erl \ + CosFileTransfer_SessionException.erl \ + CosFileTransfer_SupportedProtocolAddresses.erl \ + CosFileTransfer_TransferException.erl \ + CosFileTransfer_VirtualFileSystem.erl \ + CosFileTransfer_VirtualFileSystem_ContentList.erl \ + +LOCAL_HRL_FILES = \ + oe_CosFileTransfer.hrl \ + CosFileTransfer.hrl \ + CosFileTransfer_Directory.hrl \ + CosFileTransfer_File.hrl \ + CosFileTransfer_FileIterator.hrl \ + CosFileTransfer_FileTransferSession.hrl \ + CosFileTransfer_VirtualFileSystem.hrl \ + +GEN_HRL_FILES = $(LOCAL_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%) + +GEN_FILES = \ + $(GEN_HRL_FILES) \ + $(GEN_ERL_FILES) + +TARGET_FILES = \ + $(GEN_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \ + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +IDL_FILES = \ + CosFileTransfer.idl + +APPUP_FILE = cosFileTransfer.appup +APPUP_SRC = $(APPUP_FILE).src +APPUP_TARGET = $(EBIN)/$(APPUP_FILE) + +APP_FILE = cosFileTransfer.app +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/src \ + -I$(ERL_TOP)/lib/cosProperty/src \ + -pa $(ERL_TOP)/lib/ic/ebin \ + -pa $(ERL_TOP)/lib/orber/ebin + +# The -pa option is just used temporary until erlc can handle +# includes from other directories than ../include . +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosFileTransfer/include \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -pa $(ERL_TOP)/lib/cosProperty/src \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosFileTransfer/include \ + -I$(ERL_TOP)/lib/cosProperty/include \ + -I$(ERL_TOP)/lib/cosProperty/src \ + +'{parse_transform,sys_pre_attributes}' \ + +'{attribute,insert,app_vsn,"cosFileTransfer_$(COSFILETRANSFER_VSN)"}' + + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + +debug: + @${MAKE} TYPE=debug opt + +cleanb: + rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +clean: + rm -f $(TARGET_FILES) $(GEN_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +$(APP_TARGET): $(APP_SRC) + sed -e 's;%VSN%;$(VSN);' $< > $@ + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +docs: + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- +$(GEN_ERL_FILES) $(GEN_HRL_FILES): CosFileTransfer.idl + erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosFileTransfer.cfg"}' CosFileTransfer.idl + mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH) + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/include + $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + +release_docs_spec: diff --git a/lib/cosFileTransfer/src/cosFileTransfer.app.src b/lib/cosFileTransfer/src/cosFileTransfer.app.src new file mode 100644 index 0000000000..31d94b6f0d --- /dev/null +++ b/lib/cosFileTransfer/src/cosFileTransfer.app.src @@ -0,0 +1,41 @@ +{application, cosFileTransfer, + [{description, "The Erlang CosFileTransfer application"}, + {vsn, "%VSN%"}, + {modules, + [ + 'cosFileTransferApp', + 'CosFileTransfer_Directory_impl', + 'CosFileTransfer_File_impl', + 'CosFileTransfer_VirtualFileSystem_impl', + 'CosFileTransfer_FileTransferSession_impl', + 'CosFileTransfer_FileIterator_impl', + 'cosFileTransferNATIVE_file', + 'oe_CosFileTransfer', + 'CosFileTransfer', + 'CosFileTransfer_AccessLevel', + 'CosFileTransfer_CommandNotImplementedException', + 'CosFileTransfer_Directory', + 'CosFileTransfer_File', + 'CosFileTransfer_FileIterator', + 'CosFileTransfer_FileList', + 'CosFileTransfer_FileNameList', + 'CosFileTransfer_FileNotFoundException', + 'CosFileTransfer_FileTransferSession', + 'CosFileTransfer_FileWrapper', + 'CosFileTransfer_IllegalOperationException', + 'CosFileTransfer_ProtocolAddressList', + 'CosFileTransfer_ProtocolSupport', + 'CosFileTransfer_RequestFailureException', + 'CosFileTransfer_SessionException', + 'CosFileTransfer_SupportedProtocolAddresses', + 'CosFileTransfer_TransferException', + 'CosFileTransfer_VirtualFileSystem', + 'CosFileTransfer_VirtualFileSystem_ContentList' + ] + }, + {registered, []}, + {applications, [orber, stdlib, kernel]}, + {env, []}, + {mod, {cosFileTransferApp, []}} +]}. + diff --git a/lib/cosFileTransfer/src/cosFileTransfer.appup.src b/lib/cosFileTransfer/src/cosFileTransfer.appup.src new file mode 100644 index 0000000000..6c3b2833b7 --- /dev/null +++ b/lib/cosFileTransfer/src/cosFileTransfer.appup.src @@ -0,0 +1,7 @@ +{"%VSN%", + [ + ], + [ + ] +}. + diff --git a/lib/cosFileTransfer/src/cosFileTransferApp.erl b/lib/cosFileTransfer/src/cosFileTransferApp.erl new file mode 100644 index 0000000000..443c917a97 --- /dev/null +++ b/lib/cosFileTransfer/src/cosFileTransferApp.erl @@ -0,0 +1,469 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosFileTransferApp.erl +%% Purpose : +%% Created : 25 Aug 2000 +%%---------------------------------------------------------------------- +-module(cosFileTransferApp). + + +%%--------------- INCLUDES ----------------------------------- +-include("cosFileTransferApp.hrl"). + +%%--------------- EXPORTS------------------------------------- +%% cosFileTransferApp API external +-export([start/0, stop/0, install/0, uninstall/0, create_VFS/4, create_VFS/5, + get_buffert_size/0]). + +%% cosFileTransferApp API internal +-export([create_link/3, get_option/3, type_check/2, configure/2]). + +%% Application callbacks +-export([start/2, init/1, stop/1]). + +%% INTERNAL EXPORTS!! DO NOT USE THESE!! +-export([create_dir/2, create_dir/3, create_file/2, create_file/3, split_paths/1, + create_name/1]). + +-export([ssl_server_certfile/0, ssl_client_certfile/0, ssl_port/0, + ssl_server_verify/0, + ssl_client_verify/0, + ssl_server_depth/0, ssl_client_depth/0, + ssl_server_cacertfile/0, + ssl_client_cacertfile/0]). + + +%%--------------- DEFINES ------------------------------------ +-define(SUPERVISOR_NAME, oe_cosFileTransferSup). +-define(SUP_FLAG, {simple_one_for_one,50,10}). +-define(SUP_DIRECTORY_SPEC(Name, Args), + ['CosFileTransfer_Directory',Args, + [{sup_child, true}, {regname, {global, Name}}]]). +-define(SUP_CHILD, + {"oe_FileTransferChild", + {cosFileTransfer,create_link, []}, + transient,100000,worker, + []}). + +%%------------------------------------------------------------ +%% function : install +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Install necessary data in the IFR DB +%%------------------------------------------------------------ +install() -> + oe_CosFileTransfer:oe_register(). + +%%------------------------------------------------------------ +%% function : uninstall +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Remove data related to cosFileTransfer from the IFR DB +%%------------------------------------------------------------ +uninstall() -> + oe_CosFileTransfer:oe_unregister(). + + +%%------------------------------------------------------------ +%% function : start/stop +%% Arguments: +%% Returns : +%% Effect : Starts or stops the cosFileTransfer application. +%%------------------------------------------------------------ +start() -> + application:start(cosFileTransfer). +stop() -> + application:stop(cosFileTransfer). + +%%------------------------------------------------------------ +%% function : start +%% Arguments: Type - see module application +%% Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ +start(_, _) -> + supervisor:start_link({local, ?SUPERVISOR_NAME}, cosFileTransferApp, app_init). + + +%%------------------------------------------------------------ +%% function : stop +%% Arguments: Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ +stop(_) -> + ok. + +%%-----------------------------------------------------------% +%% function : init +%% Arguments: +%% Returns : +%% Effect : +%%------------------------------------------------------------ +%% Starting using create_factory/X +init(own_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}; +%% When starting as an application. +init(app_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}. + +%%------------------------------------------------------------ +%% function : create_VFS +%% Arguments: +%% Returns : +%% Effect : +%%------------------------------------------------------------ +create_VFS(Type, Content, Host, Port) -> + create_VFS(Type, Content, Host, Port, []). + +create_VFS('FTP', Content, Host, Port, Options) + when is_list(Host) andalso is_integer(Port) andalso is_list(Options) -> + 'CosFileTransfer_VirtualFileSystem':oe_create(['FTP', Content, Host, Port, + Options], + [{pseudo, true}]); +create_VFS({'NATIVE', Mod}, Content, Host, Port, Options) + when is_list(Host) andalso is_integer(Port) andalso is_list(Options) -> + 'CosFileTransfer_VirtualFileSystem':oe_create([{'NATIVE', Mod}, Content, + Host, Port, Options], + [{pseudo, true}]); +create_VFS(_, _, _, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%-----------------------------------------------------------% +%% function : create_link +%% Arguments: Module - which Module to call +%% Env/ArgList - ordinary oe_create arguments. +%% Returns : +%% Exception: +%% Effect : Necessary since we want the supervisor to be a +%% 'simple_one_for_one'. Otherwise, using for example, +%% 'one_for_one', we have to call supervisor:delete_child +%% to remove the childs startspecification from the +%% supervisors internal state. +%%------------------------------------------------------------ +create_link(Module, Env, ArgList) -> + Module:oe_create_link(Env, ArgList). + +%%-----------------------------------------------------------% +%% function : get_option +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +get_option(Key, OptionList, DefaultList) -> + case lists:keysearch(Key, 1, OptionList) of + {value,{Key,Value}} -> + Value; + _ -> + case lists:keysearch(Key, 1, DefaultList) of + {value,{Key,Value}} -> + Value; + _-> + {error, "Invalid option"} + end + end. + +%%-----------------------------------------------------------% +%% function : type_check +%% Arguments: Obj - objectrefernce to test. +%% Mod - Module which contains typeID/0. +%% Returns : 'ok' or raises exception. +%% Effect : +%%------------------------------------------------------------ +type_check(Obj, Mod) -> + case catch corba_object:is_a(Obj,Mod:typeID()) of + true -> + ok; + _ -> + corba:raise(#'BAD_PARAM'{minor=700, completion_status=?COMPLETED_NO}) + end. + + +%%-----------------------------------------------------------% +%% function : create_name/1 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +create_name(Type) -> + {MSec, Sec, USec} = erlang:now(), + lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]). + + +%%-----------------------------------------------------------% +%% function : get_buffert_size/0 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : Lookup the configuration variable 'buffert_size' +%%------------------------------------------------------------ +get_buffert_size() -> + case application:get_env(cosFileTransfer, buffert_size) of + {ok, Size} when is_integer(Size) -> + Size; + _ -> + ?DEFAULT_BUFSIZE + end. + +%%-----------------------------------------------------------% +%% function : configure/1 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +configure(buffert_size, Value) when is_integer(Value) -> + do_configure(buffert_size, Value); +configure(ssl_port, Value) when is_integer(Value) -> + do_safe_configure(ssl_port, Value); +configure(ssl_server_certfile, Value) when is_list(Value) -> + do_safe_configure(ssl_server_certfile, Value); +configure(ssl_server_certfile, Value) when is_atom(Value) -> + do_safe_configure(ssl_server_certfile, atom_to_list(Value)); +configure(ssl_client_certfile, Value) when is_list(Value) -> + do_safe_configure(ssl_client_certfile, Value); +configure(ssl_client_certfile, Value) when is_atom(Value) -> + do_safe_configure(ssl_client_certfile, atom_to_list(Value)); +configure(ssl_server_verify, Value) when is_integer(Value) -> + do_safe_configure(ssl_server_verify, Value); +configure(ssl_client_verify, Value) when is_integer(Value) -> + do_safe_configure(ssl_client_verify, Value); +configure(ssl_server_depth, Value) when is_integer(Value) -> + do_safe_configure(ssl_server_depth, Value); +configure(ssl_client_depth, Value) when is_integer(Value) -> + do_safe_configure(ssl_client_depth, Value); +configure(ssl_server_cacertfile, Value) when is_list(Value) -> + do_safe_configure(ssl_server_cacertfile, Value); +configure(ssl_server_cacertfile, Value) when is_atom(Value) -> + do_safe_configure(ssl_server_cacertfile, atom_to_list(Value)); +configure(ssl_client_cacertfile, Value) when is_list(Value) -> + do_safe_configure(ssl_client_cacertfile, Value); +configure(ssl_client_cacertfile, Value) when is_atom(Value) -> + do_safe_configure(ssl_client_cacertfile, atom_to_list(Value)); +configure(_, _) -> + exit({error, "Bad configure parameter(s)"}). + +%% This function may be used as long as it is safe to change a value at any time. +do_configure(Key, Value) -> + case is_loaded() of + false -> + application:load(cosFileTransfer), + application_controller:set_env(cosFileTransfer, Key, Value); + true -> + application_controller:set_env(cosFileTransfer, Key, Value) + end. + + +%% This function MUST(!!) be used when we cannot change a value if cosFileTransfer +%% is running. +do_safe_configure(Key, Value) -> + case is_loaded() of + false -> + application:load(cosFileTransfer), + application_controller:set_env(cosFileTransfer, Key, Value); + true -> + case is_running() of + false -> + application_controller:set_env(cosFileTransfer, Key, Value); + true -> + exit("cosFileTransfer already running, the given key may not be updated!") + end + end. + +%%-----------------------------------------------------------% +%% function : SSL parameter access functions +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +ssl_port() -> + case application:get_env(cosFileTransfer, ssl_port) of + {ok, Port} when is_integer(Port) -> + Port; + _ -> + -1 + end. + +ssl_server_certfile() -> + case application:get_env(cosFileTransfer, ssl_server_certfile) of + {ok, V1} when is_list(V1) -> + V1; + {ok, V2} when is_atom(V2) -> + atom_to_list(V2); + _What -> + {ok, Cwd} = file:get_cwd(), + filename:join(Cwd,"ssl_server_cert.pem") + end. + + +ssl_client_certfile() -> + case application:get_env(cosFileTransfer, ssl_client_certfile) of + {ok, V1} when is_list(V1) -> + V1; + {ok, V2} when is_atom(V2) -> + atom_to_list(V2); + _ -> + {ok, Cwd} = file:get_cwd(), + filename:join(Cwd,"ssl_client_cert.pem") + end. + +ssl_server_verify() -> + Verify = case application:get_env(cosFileTransfer, ssl_server_verify) of + {ok, V} when is_integer(V) -> + V; + _ -> + 0 + end, + if + Verify =< 2, Verify >= 0 -> + Verify; + true -> + 0 + end. + +ssl_client_verify() -> + Verify = case application:get_env(cosFileTransfer, ssl_client_verify) of + {ok, V1} when is_integer(V1) -> + V1; + _ -> + 0 + end, + if + Verify =< 2, Verify >= 0 -> + Verify; + true -> + 0 + end. + +ssl_server_depth() -> + case application:get_env(cosFileTransfer, ssl_server_depth) of + {ok, V1} when is_integer(V1) -> + V1; + _ -> + 1 + end. + +ssl_client_depth() -> + case application:get_env(cosFileTransfer, ssl_client_depth) of + {ok, V1} when is_integer(V1) -> + V1; + _ -> + 1 + end. + + +ssl_server_cacertfile() -> + case application:get_env(cosFileTransfer, ssl_server_cacertfile) of + {ok, V1} when is_list(V1) -> + V1; + {ok, V2} when is_atom(V2) -> + atom_to_list(V2); + _ -> + [] + end. + +ssl_client_cacertfile() -> + case application:get_env(cosFileTransfer, ssl_client_cacertfile) of + {ok, V1} when is_list(V1) -> + V1; + {ok, V2} when is_atom(V2) -> + atom_to_list(V2); + _ -> + [] + end. + + +%%============================================================ +%% Internal functions +%%============================================================ +%%-----------------------------------------------------------% +%% function : is_loaded/0 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : Check if the application is loaded +%%------------------------------------------------------------ +is_loaded() -> + is_loaded(application:loaded_applications()). + +is_running() -> + is_loaded(application:which_applications()). + +is_loaded([]) -> + false; +is_loaded([{cosFileTransfer, _, _} |_As]) -> + true; +is_loaded([_ |As]) -> + is_loaded(As). + + + + +%%-----------------------------------------------------------% +%% function : create_dir/3/4 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +create_dir(Session, FileNameList) -> + create_dir(Session, FileNameList, corba:create_nil_objref()). +create_dir(Session, FileNameList, Parent) -> + 'CosFileTransfer_Directory':oe_create([lists:last(FileNameList), FileNameList, + Parent, Session], + [{pseudo, true}]). + +%%-----------------------------------------------------------% +%% function : create_file/2/3 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +create_file(Session, FileNameList) -> + create_file(Session, FileNameList, corba:create_nil_objref()). +create_file(Session, FileNameList, Parent) -> + 'CosFileTransfer_File':oe_create([lists:last(FileNameList), FileNameList, + Parent, Session], [{pseudo, true}]). + +%%-----------------------------------------------------------% +%% function : split_paths +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +split_paths(Listing) -> + split_paths(string:tokens(Listing, ?SEPARATOR), []). +split_paths([], Acc) -> + Acc; +split_paths([H|T], Acc) -> + split_paths(T, [filename:split(H)|Acc]). + + +%%--------------- END OF MODULE ------------------------------ + + diff --git a/lib/cosFileTransfer/src/cosFileTransferApp.hrl b/lib/cosFileTransfer/src/cosFileTransferApp.hrl new file mode 100644 index 0000000000..36700a6e97 --- /dev/null +++ b/lib/cosFileTransfer/src/cosFileTransferApp.hrl @@ -0,0 +1,68 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosFileTransferApp.hrl +%% Purpose : +%% Created : 10 Feb 2000 +%%---------------------------------------------------------------------- + + +%%--------------- INCLUDES ----------------------------------- +%% External +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +-include_lib("cosProperty/include/CosPropertyService.hrl"). + +%% Local +-include_lib("cosFileTransfer/include/CosFileTransfer.hrl"). + +-define(write_ErrorMsg(Txt, Arg), +error_logger:error_msg("============= CosFileTransfer =============~n" + Txt + "===========================================~n", + Arg)). + +-define(FTP_PORT_INT, 21). +-define(FTP_PORT_STR, "21"). +-define(TCP_ID, "TCP"). +-define(FTP_ID, "FTP"). +-define(FTAM_ID, "FTAM"). +-define(NATIVE_ID, "NATIVE"). +-define(SUPPURTED_PROTOCOLS, ["TCP/IP", "SSL"]). + +-define(DEFAULT_CONFIG, [{protocol, tcp}, {connect_timeout, 60}]). + +-define(SEPARATOR, "\r\n"). + +-define(DEFAULT_BUFSIZE, 64000). + +-define(DEBUG_LEVEL, 3). + +-ifdef(debug). +-define(debug_print(F,A), + io:format("[LINE: ~p MODULE: ~p] "++F,[?LINE, ?MODULE]++A)). +-define(ft_TypeCheck(O,M), 'cosFileTransferApp':type_check(O,M)). +-else. +-define(debug_print(F,A), ok). +-define(ft_TypeCheck(O,I), ok). +-endif. + +%%--------------- END OF MODULE ------------------------------ diff --git a/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl b/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl new file mode 100644 index 0000000000..634dfd4b8a --- /dev/null +++ b/lib/cosFileTransfer/src/cosFileTransferNATIVE_file.erl @@ -0,0 +1,358 @@ +%%---------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosFileTransferNATIVE_file.erl +%% Description : +%% +%% Created : 9 Nov 2000 +%%---------------------------------------------------------------------- +-module('cosFileTransferNATIVE_file'). + + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include("cosFileTransferApp.hrl"). +-include_lib("kernel/include/file.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([open/1, + open/2, + open/3, + user/3, + pwd/1, + cd/2, + mkdir/2, + rmdir/2, + nlist/1, + nlist/2, + delete/2, + recv/2, + recv/3, + send/2, + send/3, + close/1, + insert/4]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% function : open +%% Arguments: +%% Returns : {ok, Ref} | {error, ehost} for future use +%% Effect : +%%---------------------------------------------------------------------- +open(_Host) -> + {ok, 'NATIVE'}. +open(_Host, _Port) -> + {ok, 'NATIVE'}. +open(_Host, _Port, _Flags) -> + {ok, 'NATIVE'}. + +%%---------------------------------------------------------------------- +%% function : user +%% Arguments: Ref - what's returned by open/1/2 +%% User = Password = string() +%% Returns : ok | {error, euser | econn} for future use +%% Effect : +%%---------------------------------------------------------------------- +user(_Ref, _User, _Password) -> + ok. + +%%---------------------------------------------------------------------- +%% function : pwd +%% Arguments: Ref - what's returned by open/1/2 +%% Returns : {ok, string()} | {error, elogin | econn} +%% Effect : +%%---------------------------------------------------------------------- +pwd(_Ref) -> + case file:get_cwd() of + {ok, Cwd} -> + {ok, Cwd}; + _ -> + {error, econn} + end. + +%%---------------------------------------------------------------------- +%% function : cd +%% Arguments: Ref - what's returned by open/1/2 +%% Dir - string() +%% Returns : ok | {error, epath | elogin | econn} +%% Effect : +%%---------------------------------------------------------------------- +cd(_Ref, Dir) -> + case file:set_cwd(Dir) of + ok -> + ok; + {error, _} -> + {error, epath} + end. + +%%---------------------------------------------------------------------- +%% function : mkdir +%% Arguments: Ref - what's returned by open/1/2 +%% Dir - string() +%% Returns : ok | {error, epath} +%% Effect : +%%---------------------------------------------------------------------- +mkdir(_Ref, Dir) -> + case file:make_dir(Dir) of + ok -> + ok; + {error, _Reason} -> + {error, epath} + end. + +%%---------------------------------------------------------------------- +%% function : rmdir +%% Arguments: Ref - what's returned by open/1/2 +%% Dir - string() +%% Returns : ok | {error, epath} +%% Effect : +%%---------------------------------------------------------------------- +rmdir(_Ref, Dir) -> + case file:del_dir(Dir) of + ok -> + ok; + {error, _Reason} -> + {error, epath} + end. + +%%---------------------------------------------------------------------- +%% function : nlist +%% Arguments: Ref - what's returned by open/1/2 +%% Dir - string() +%% Returns : {ok, Listing} | {error, epath | elogin | econn} +%% Effect : +%%---------------------------------------------------------------------- +nlist(_Ref) -> + case file:get_cwd() of + {ok, Cwd} -> + %% Here we can assume that it's a Directory is tested. + convert_to_nlist(file:list_dir(Cwd)); + _ -> + {error, epath} + end. +nlist(_Ref, Dir) -> + case file:list_dir(Dir) of + {error, _} -> + %% Might be a File + case file:read_file_info(Dir) of + {ok, _} -> + convert_to_nlist_helper([Dir], []); + _ -> + {error, epath} + end; + {ok, Content} -> + convert_to_nlist_helper(Content, []) + end. + +convert_to_nlist({error, _}) -> + {error, epath}; +convert_to_nlist({ok, Content}) -> + convert_to_nlist_helper(Content, []). + +convert_to_nlist_helper([], Acc) -> + {ok, lists:concat(Acc)}; +convert_to_nlist_helper([H|T], Acc) -> + convert_to_nlist_helper(T, [H, "\r\n"|Acc]). + +%%---------------------------------------------------------------------- +%% function : delete +%% Arguments: Ref - what's returned by open/1/2 +%% File - string() +%% Returns : ok | {error, epath} +%% Effect : +%%---------------------------------------------------------------------- +delete(_Ref, File) -> + case file:delete(File) of + ok -> + ok; + {error, _Reason} -> + {error, epath} + end. + +%%---------------------------------------------------------------------- +%% function : recv +%% Arguments: Ref - what's returned by open/1/2 +%% Returns : ok | {error, epath | elogin | econn} +%% Effect : +%%---------------------------------------------------------------------- +recv(_Ref, _Remote) -> + ok. +recv(_Ref, Remote, Local) -> + copy_file(Remote, Local). + +%%---------------------------------------------------------------------- +%% function : send +%% Arguments: Ref - what's returned by open/1/2 +%% Returns : ok | {error, epath | elogin | econn | etnospc | epnospc | efnamena} +%% Effect : +%%---------------------------------------------------------------------- +send(_Ref, _Local) -> + ok. +send(_Ref, Local, Remote) -> + copy_file(Local, Remote). + +%%---------------------------------------------------------------------- +%% function : close +%% Arguments: Ref - what's returned by open/1/2 +%% Returns : ok +%% Effect : Currently none. +%%---------------------------------------------------------------------- +close(_) -> + ok. + + +%%---------------------------------------------------------------------- +%% function : insert +%% Arguments: Ref - what's returned by open/1/2 +%% Local - absolute file name +%% Remote - absolute file name +%% Offset - long() +%% Returns : ok +%% Effect : +%%---------------------------------------------------------------------- +insert(_Ref, Source, Target, Offset) -> + case file:open(Source, [raw, binary, read]) of + {ok, SourceDev} -> + case file:open(Target, [raw, binary, read, write]) of + {ok, TargetDev} -> + {ok, #file_info{size=SSize}} = + file:read_file_info(Source), + {ok, #file_info{size=TSize}} = + file:read_file_info(Target), + insert_file_helper(SourceDev, TargetDev, SSize, TSize, Offset); + Reason -> + file:close(SourceDev), + convert_error(Reason) + end; + Reason -> + convert_error(Reason) + end. + + +insert_file_helper(SourceDev, TargetDev, SSize, TSize, Offset) -> + BuffSize = cosFileTransferApp:get_buffert_size(), + move_data(TargetDev, TSize, SSize+TSize, TSize-Offset, BuffSize), + insert_data(SourceDev, TargetDev, 0, Offset, BuffSize), + file:close(SourceDev), + file:close(TargetDev). +move_data(_F, _RLocation, _WLocation, Counter, _BuffSize) when Counter == 0 -> + ok; +move_data(F, RLocation, WLocation, Counter, BuffSize) when Counter =< BuffSize -> + case file:pread(F, RLocation-Counter, Counter) of + {ok, Bin} -> + file:pwrite(F, WLocation-Counter, Bin); + eof -> + ok + end; +move_data(F, RLocation, WLocation, Counter, BuffSize) -> + NewRLC = RLocation-BuffSize, + NewWLC = WLocation-BuffSize, + case file:pread(F, NewRLC, BuffSize) of + {ok, Bin} -> + file:pwrite(F, NewWLC, Bin), + move_data(F, NewRLC, NewWLC, Counter-BuffSize, BuffSize); + eof -> + ok + end. + +insert_data(FSRC, FTGT, RLocation, WLocation, BuffSize) -> + case file:pread(FSRC, RLocation, BuffSize) of + {ok, Bin} -> + file:pwrite(FTGT, WLocation, Bin), + insert_data(FSRC, FTGT, RLocation+BuffSize, WLocation+BuffSize, BuffSize); + eof -> + ok + end. + + +%%====================================================================== +%% Internal functions +%%====================================================================== +copy_file(Source, Target) -> + case file:open(Source, [raw, binary, read]) of + {ok, SourceDev} -> + case file:open(Target, [raw, binary, append]) of + {ok, TargetDev} -> + BuffSize = cosFileTransferApp:get_buffert_size(), + copy_file_helper(SourceDev, TargetDev, BuffSize); + Reason -> + file:close(SourceDev), + convert_error(Reason) + end; + Reason -> + convert_error(Reason) + end. + +copy_file_helper(SourceDev, TargetDev, BuffSize) -> + case file:read(SourceDev, BuffSize) of + eof -> + file:close(SourceDev), + file:close(TargetDev); + {ok, Bin} -> + case file:write(TargetDev, Bin) of + ok -> + copy_file_helper(SourceDev, TargetDev, BuffSize); + Reason -> + file:close(SourceDev), + file:close(TargetDev), + convert_error(Reason) + end; + {error, Reason} -> + file:close(SourceDev), + file:close(TargetDev), + convert_error(Reason) + end. + +convert_error({error, eacces}) -> + {error, elogin}; +convert_error({error, enoent}) -> + {error, epath}; +convert_error({error, enotdir}) -> + {error, epath}; +convert_error({error, eidir}) -> + {error, epath}; +convert_error({error, enospc}) -> + {error, etnospc}; +convert_error(_) -> + {error, epath}. + +%%====================================================================== +%% END OF MODULE +%%====================================================================== |