Go to the documentation of this file.00001
00002
00003 #ifndef ACE_FTP_SESSION_CPP
00004 #define ACE_FTP_SESSION_CPP
00005
00006 #include "ace/INet/INet_Log.h"
00007 #include "ace/INet/FTP_Session.h"
00008 #include "ace/INet/String_IOStream.h"
00009 #include "ace/INet/IOS_util.h"
00010 #include "ace/INET_Addr.h"
00011 #include "ace/Event_Handler.h"
00012 #include "ace/Connector.h"
00013 #include "ace/String_Base.h"
00014 #include "ace/Truncate.h"
00015 #include <istream>
00016 #include <ostream>
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 namespace ACE
00021 {
00022 namespace FTP
00023 {
00024
00025 template <ACE_SYNCH_DECL>
00026 Session_T<ACE_SYNCH_USE>::Session_T ()
00027 : port_ (FTP_PORT),
00028 reactive_ (false),
00029 connection_ (0),
00030 sock_stream_ (0),
00031 ftp_timeout_ (DEFAULT_TIMEOUT),
00032 cannot_reconnect_ (false),
00033 has_ftp_ext_ (true),
00034 new_connect_ (true)
00035 {
00036 INET_TRACE ("ACE_FTP_Session - ctor");
00037 }
00038
00039 template <ACE_SYNCH_DECL>
00040 Session_T<ACE_SYNCH_USE>::Session_T (const ACE_Time_Value& timeout)
00041 : port_ (FTP_PORT),
00042 reactive_ (false),
00043 connection_ (0),
00044 sock_stream_ (0),
00045 ftp_timeout_ (timeout),
00046 cannot_reconnect_ (false),
00047 has_ftp_ext_ (true),
00048 new_connect_ (true)
00049 {
00050 INET_TRACE ("ACE_FTP_Session - ctor");
00051 }
00052
00053 template <ACE_SYNCH_DECL>
00054 Session_T<ACE_SYNCH_USE>::~Session_T ()
00055 {
00056 INET_TRACE ("ACE_FTP_Session - dtor");
00057 this->close ();
00058 }
00059
00060 template <ACE_SYNCH_DECL>
00061 bool Session_T<ACE_SYNCH_USE>::is_connected () const
00062 {
00063 return this->connection_ && this->connection_->is_connected ();
00064 }
00065
00066 template <ACE_SYNCH_DECL>
00067 bool Session_T<ACE_SYNCH_USE>::is_new_connection () const
00068 {
00069 return this->new_connect_;
00070 }
00071
00072 template <ACE_SYNCH_DECL>
00073 void Session_T<ACE_SYNCH_USE>::set_host (const ACE_CString& host, u_short port)
00074 {
00075 if (!this->is_connected ())
00076 {
00077 this->host_ = host;
00078 this->port_ = port;
00079 }
00080 }
00081
00082 template <ACE_SYNCH_DECL>
00083 void Session_T<ACE_SYNCH_USE>::set_host (const ACE_CString& host)
00084 {
00085 if (!this->is_connected ())
00086 {
00087 this->host_ = host;
00088 }
00089 }
00090
00091 template <ACE_SYNCH_DECL>
00092 void Session_T<ACE_SYNCH_USE>::set_port (u_short port)
00093 {
00094 if (!this->is_connected ())
00095 {
00096 this->port_ = port;
00097 }
00098 }
00099
00100 template <ACE_SYNCH_DECL>
00101 const ACE_CString& Session_T<ACE_SYNCH_USE>::get_host () const
00102 {
00103 return this->host_;
00104 }
00105
00106 template <ACE_SYNCH_DECL>
00107 u_short Session_T<ACE_SYNCH_USE>::get_port () const
00108 {
00109 return this->port_;
00110 }
00111
00112 template <ACE_SYNCH_DECL>
00113 bool Session_T<ACE_SYNCH_USE>::connect (bool use_reactor)
00114 {
00115 INET_TRACE ("ACE_FTP_Session::connect");
00116
00117 typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;
00118
00119 this->close ();
00120
00121 unsigned long f_reactor = use_reactor ? ACE_Synch_Options::USE_REACTOR : 0;
00122 ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor,
00123 this->ftp_timeout_);
00124 connector_type connector;
00125
00126 connection_type* new_connection = 0;
00127 ACE_NEW_RETURN (new_connection,
00128 connection_type(sync_opt),
00129 false);
00130 if (connector.connect (new_connection,
00131 ACE_INET_Addr (this->port_,
00132 this->host_.c_str ()),
00133 ACE_Synch_Options (0,this->ftp_timeout_)) == -1)
00134 {
00135 INET_ERROR (1, (LM_ERROR, DLINFO
00136 ACE_TEXT ("(%d) ACE_FTP_Session::connect - ")
00137 ACE_TEXT ("failed to connect; host=%C, port=%d"),
00138 ACE_OS::last_error (), this->host_.c_str (), this->port_));
00139
00140
00141
00142 return false;
00143 }
00144
00145 this->connection_ = new_connection;
00146 this->connection_->reference_counting_policy ().value (
00147 ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
00148
00149 ACE_NEW_NORETURN (this->sock_stream_,
00150 sock_stream_type (this->connection_));
00151 if (this->sock_stream_)
00152 {
00153 this->new_connect_ = true;
00154 this->cannot_reconnect_ = false;
00155 this->reactive_ = use_reactor;
00156
00157 return true;
00158 }
00159 else
00160 {
00161 this->close ();
00162 return false;
00163 }
00164 }
00165
00166 template <ACE_SYNCH_DECL>
00167 bool Session_T<ACE_SYNCH_USE>::connect (connection_type* connection)
00168 {
00169 INET_TRACE ("ACE_FTP_Session::connect(connection)");
00170
00171 this->close ();
00172
00173 if (connection->is_connected ())
00174 {
00175 ACE_INET_Addr remote;
00176 connection->peer ().get_remote_addr (remote);
00177 this->host_ = remote.get_host_name ();
00178 this->port_ = remote.get_port_number ();
00179 }
00180 else
00181 {
00182 typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type;
00183
00184 connector_type connector;
00185 if (connector.connect (connection,
00186 ACE_INET_Addr (this->host_.c_str (),
00187 this->port_)) == -1)
00188 {
00189 INET_ERROR (1, (LM_ERROR, DLINFO
00190 ACE_TEXT ("(%d) ACE_FTP_Session::connect(connection) - ")
00191 ACE_TEXT ("failed to connect; host=%C, port=%d"),
00192 ACE_OS::last_error (), this->host_.c_str (), this->port_));
00193 return false;
00194 }
00195 }
00196
00197 this->connection_ = connection;
00198 this->connection_->add_reference ();
00199
00200 ACE_NEW_NORETURN (this->sock_stream_,
00201 sock_stream_type (this->connection_));
00202
00203 if (this->sock_stream_)
00204 {
00205 this->new_connect_ = true;
00206 this->cannot_reconnect_ = true;
00207 return true;
00208 }
00209 else
00210 {
00211 this->close ();
00212 return false;
00213 }
00214 }
00215
00216 template <ACE_SYNCH_DECL>
00217 bool Session_T<ACE_SYNCH_USE>::send_request (Request& request)
00218 {
00219 INET_TRACE ("ACE_FTP_Session::send_request");
00220
00221 if (!this->is_connected ())
00222 {
00223 if (this->cannot_reconnect_ || !this->connect(this->reactive_))
00224 {
00225 if (!this->cannot_reconnect_)
00226 INET_ERROR (1, (LM_ERROR, DLINFO
00227 ACE_TEXT ("(%d) FTP_Session::send_request - ")
00228 ACE_TEXT ("reconnect failed\n"),
00229 ACE_OS::last_error ()));
00230 return ACE::IOS::Null::out_stream_;
00231 }
00232 }
00233
00234 this->new_connect_ = false;
00235
00236 request.write (*this->sock_stream_);
00237
00238 return this->is_connected () && this->sock_stream_->good ();
00239 }
00240
00241 template <ACE_SYNCH_DECL>
00242 bool Session_T<ACE_SYNCH_USE>::receive_response (Response& response)
00243 {
00244 INET_TRACE ("ACE_FTP_Session::receive_response");
00245
00246 this->sock_stream_->flush ();
00247
00248 response.reset ();
00249 return response.read (*this->sock_stream_);
00250 }
00251
00252 template <ACE_SYNCH_DECL>
00253 bool Session_T<ACE_SYNCH_USE>::send_interrupt ()
00254 {
00255 INET_TRACE ("ACE_FTP_Session::send_interrupt");
00256
00257 if (this->is_connected ())
00258 {
00259 this->sock_stream_->put (ACE_Utils::truncate_cast<char> (int (INTERRUPT)));
00260 this->sock_stream_->sync ();
00261 return this->sock_stream_->good ();
00262 }
00263
00264 return false;
00265 }
00266
00267 template <ACE_SYNCH_DECL>
00268 void Session_T<ACE_SYNCH_USE>::close ()
00269 {
00270 INET_TRACE ("ACE_FTP_Session::close");
00271
00272 if (this->connection_)
00273 {
00274 if (this->sock_stream_)
00275 {
00276 delete this->sock_stream_;
00277 this->sock_stream_ = 0;
00278 }
00279
00280
00281 this->connection_->remove_reference ();
00282 this->connection_ = 0;
00283 }
00284 }
00285
00286 template <ACE_SYNCH_DECL>
00287 bool Session_T<ACE_SYNCH_USE>::supports_ftp_extensions () const
00288 {
00289 return this->has_ftp_ext_;
00290 }
00291
00292 template <ACE_SYNCH_DECL>
00293 void Session_T<ACE_SYNCH_USE>::set_ftp_extension_support (bool f)
00294 {
00295 this->has_ftp_ext_ = f;
00296 }
00297
00298 template <ACE_SYNCH_DECL>
00299 bool Session_T<ACE_SYNCH_USE>::is_reactive () const
00300 {
00301 return this->reactive_;
00302 }
00303
00304 template <ACE_SYNCH_DECL>
00305 const ACE_Time_Value& Session_T<ACE_SYNCH_USE>::timeout () const
00306 {
00307 return this->ftp_timeout_;
00308 }
00309
00310 template <ACE_SYNCH_DECL>
00311 void Session_T<ACE_SYNCH_USE>::get_local_addr (ACE_INET_Addr& loc_addr) const
00312 {
00313 if (this->is_connected ())
00314 this->connection_->peer ().get_local_addr (loc_addr);
00315 }
00316
00317 }
00318 }
00319
00320 ACE_END_VERSIONED_NAMESPACE_DECL
00321
00322 #endif