|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifndef FTPCLASS_H
|
|
Packit |
8f70b4 |
#define FTPCLASS_H
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "trio.h"
|
|
Packit |
8f70b4 |
#include <time.h>
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "NetAccess.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#if USE_SSL
|
|
Packit |
8f70b4 |
# include "lftp_ssl.h"
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class TelnetEncode : public DataTranslator {
|
|
Packit |
8f70b4 |
void PutTranslated(Buffer *target,const char *buf,int size);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class TelnetDecode : public DataTranslator {
|
|
Packit |
8f70b4 |
void PutTranslated(Buffer *target,const char *buf,int size);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class IOBufferTelnet : public IOBufferStacked
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
IOBufferTelnet(IOBuffer *b) : IOBufferStacked(b) {
|
|
Packit |
8f70b4 |
if(mode==PUT)
|
|
Packit |
8f70b4 |
SetTranslator(new TelnetEncode());
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
SetTranslator(new TelnetDecode());
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class Ftp : public NetAccess
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enum automate_state
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
EOF_STATE, // control connection is open, idle state
|
|
Packit |
8f70b4 |
INITIAL_STATE, // all connections are closed
|
|
Packit |
8f70b4 |
CONNECTING_STATE, // we are connecting the control socket
|
|
Packit |
8f70b4 |
HTTP_PROXY_CONNECTED,// connected to http proxy, but have no reply yet
|
|
Packit |
8f70b4 |
CONNECTED_STATE, // just after connect
|
|
Packit |
8f70b4 |
WAITING_STATE, // we're waiting for a response with data
|
|
Packit |
8f70b4 |
ACCEPTING_STATE, // we're waiting for an incoming data connection
|
|
Packit |
8f70b4 |
DATA_OPEN_STATE, // data connection is open, for read or write
|
|
Packit |
8f70b4 |
CWD_CWD_WAITING_STATE, // waiting until 'CWD $cwd' finishes
|
|
Packit |
8f70b4 |
USER_RESP_WAITING_STATE,// waiting until 'USER $user' finishes
|
|
Packit |
8f70b4 |
DATASOCKET_CONNECTING_STATE, // waiting for data_sock to connect
|
|
Packit |
8f70b4 |
WAITING_150_STATE, // waiting for 150 message
|
|
Packit |
8f70b4 |
WAITING_CCC_SHUTDOWN // waiting for the server to shutdown SSL connection
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class Connection
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring_c closure;
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
int control_sock;
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> control_recv;
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> control_send;
|
|
Packit |
8f70b4 |
IOBufferTelnet *telnet_layer_send;
|
|
Packit |
8f70b4 |
DirectedBuffer send_cmd_buffer; // holds unsent commands.
|
|
Packit |
8f70b4 |
int data_sock;
|
|
Packit |
8f70b4 |
SMTaskRef<IOBuffer> data_iobuf;
|
|
Packit |
8f70b4 |
int aborted_data_sock;
|
|
Packit |
8f70b4 |
sockaddr_u peer_sa;
|
|
Packit |
8f70b4 |
sockaddr_u data_sa; // address for data accepting
|
|
Packit |
8f70b4 |
bool quit_sent;
|
|
Packit |
8f70b4 |
bool fixed_pasv; // had to fix PASV address.
|
|
Packit |
8f70b4 |
bool translation_activated;
|
|
Packit |
8f70b4 |
bool proxy_is_http; // true when connection was established via http proxy.
|
|
Packit |
8f70b4 |
bool may_show_password;
|
|
Packit |
8f70b4 |
bool can_do_pasv;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int multiline_code; // the code of multiline response.
|
|
Packit |
8f70b4 |
int sync_wait; // number of commands in flight.
|
|
Packit |
8f70b4 |
bool ignore_pass; // logged in just with user
|
|
Packit |
8f70b4 |
bool try_feat_after_login;
|
|
Packit |
8f70b4 |
bool tune_after_login;
|
|
Packit |
8f70b4 |
bool utf8_activated; // server is switched to UTF8 mode.
|
|
Packit |
8f70b4 |
bool received_150;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char type; // type of transfer: 'A'scii or 'I'mage
|
|
Packit |
8f70b4 |
char t_mode; // transfer mode: 'S'tream, 'Z'ipped
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool dos_path;
|
|
Packit |
8f70b4 |
bool vms_path;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool have_feat_info;
|
|
Packit |
8f70b4 |
bool mdtm_supported;
|
|
Packit |
8f70b4 |
bool size_supported;
|
|
Packit |
8f70b4 |
bool rest_supported;
|
|
Packit |
8f70b4 |
bool site_chmod_supported;
|
|
Packit |
8f70b4 |
bool site_utime_supported;
|
|
Packit |
8f70b4 |
bool site_utime2_supported; // two-argument SITE UTIME
|
|
Packit |
8f70b4 |
bool site_symlink_supported;
|
|
Packit |
8f70b4 |
bool site_mkdir_supported;
|
|
Packit |
8f70b4 |
bool pret_supported;
|
|
Packit |
8f70b4 |
bool utf8_supported;
|
|
Packit |
8f70b4 |
bool lang_supported;
|
|
Packit |
8f70b4 |
bool mlst_supported;
|
|
Packit |
8f70b4 |
bool clnt_supported;
|
|
Packit |
8f70b4 |
bool host_supported;
|
|
Packit |
8f70b4 |
bool mfmt_supported;
|
|
Packit |
8f70b4 |
bool mff_supported;
|
|
Packit |
8f70b4 |
bool epsv_supported;
|
|
Packit |
8f70b4 |
bool tvfs_supported;
|
|
Packit |
8f70b4 |
bool mode_z_supported;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool ssl_after_proxy;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
off_t last_rest; // last successful REST position.
|
|
Packit |
8f70b4 |
off_t rest_pos; // the number sent with REST command.
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Timer abor_close_timer; // timer for closing aborted connection.
|
|
Packit |
8f70b4 |
Timer stat_timer; // timer for sending periodic STAT commands.
|
|
Packit |
8f70b4 |
Timer waiting_150_timer; // limit time to wait for 150 reply.
|
|
Packit |
8f70b4 |
Timer waiting_ssl_timer; // limit time to wait for ssl shutdown
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
time_t nop_time;
|
|
Packit |
8f70b4 |
off_t nop_offset;
|
|
Packit |
8f70b4 |
int nop_count;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#if USE_SSL
|
|
Packit |
8f70b4 |
Ref<lftp_ssl> control_ssl;
|
|
Packit |
8f70b4 |
char prot; // current data protection scheme 'C'lear or 'P'rivate
|
|
Packit |
8f70b4 |
bool auth_sent;
|
|
Packit |
8f70b4 |
bool auth_supported;
|
|
Packit |
8f70b4 |
bool cpsv_supported;
|
|
Packit |
8f70b4 |
bool sscn_supported;
|
|
Packit |
8f70b4 |
bool sscn_on;
|
|
Packit |
8f70b4 |
xstring auth_args_supported;
|
|
Packit |
8f70b4 |
bool ssl_is_activated() { return control_ssl!=0; }
|
|
Packit |
8f70b4 |
Timer waiting_ssl_shutdown;
|
|
Packit |
8f70b4 |
#else
|
|
Packit |
8f70b4 |
bool ssl_is_activated() { return false; }
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring_c mlst_attr_supported;
|
|
Packit |
8f70b4 |
xstring_c mode_z_opts_supported;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Connection(const char *c);
|
|
Packit |
8f70b4 |
~Connection();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool data_address_ok(const sockaddr_u *d,bool verify_address,bool verify_port);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void MakeBuffers();
|
|
Packit |
8f70b4 |
void MakeSSLBuffers(const char *h);
|
|
Packit |
8f70b4 |
void InitTelnetLayer();
|
|
Packit |
8f70b4 |
void SetControlConnectionTranslation(const char *cs);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void CloseDataSocket(); // only closes socket, does not delete iobuf.
|
|
Packit |
8f70b4 |
void CloseDataConnection();
|
|
Packit |
8f70b4 |
void AbortDataConnection();
|
|
Packit |
8f70b4 |
void CloseAbortedDataConnection();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Send(const char *cmd);
|
|
Packit |
8f70b4 |
void SendURI(const char *u,const char *home);
|
|
Packit |
8f70b4 |
void SendCRNL();
|
|
Packit |
8f70b4 |
void SendEncoded(const char *url);
|
|
Packit |
8f70b4 |
void SendCmd(const char *cmd);
|
|
Packit |
8f70b4 |
void SendCmd2(const char *cmd,const char *f,const char *u=0,const char *home=0);
|
|
Packit |
8f70b4 |
void SendCmd2(const char *cmd,int v);
|
|
Packit |
8f70b4 |
void SendCmdF(const char *fmt,...) PRINTF_LIKE(2,3);
|
|
Packit |
8f70b4 |
int FlushSendQueueOneCmd(); // sends single command from send_cmd_buffer
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void AddDataTranslator(DataTranslator *t);
|
|
Packit |
8f70b4 |
void AddDataTranslation(const char *charset,bool translit);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SuspendInternal()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(control_send) control_send->SuspendSlave();
|
|
Packit |
8f70b4 |
if(control_recv && !data_iobuf) control_recv->SuspendSlave();
|
|
Packit |
8f70b4 |
if(data_iobuf) data_iobuf->SuspendSlave();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void ResumeInternal()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(control_send) control_send->ResumeSlave();
|
|
Packit |
8f70b4 |
if(control_recv) control_recv->ResumeSlave();
|
|
Packit |
8f70b4 |
if(data_iobuf) data_iobuf->ResumeSlave();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void CheckFEAT(char *reply,const char *line,bool trust);
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<Connection> conn;
|
|
Packit |
8f70b4 |
bool last_connection_failed;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct Expect
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
enum expect_t
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
NONE, // no special check, reconnect if reply>=400.
|
|
Packit |
8f70b4 |
IGNORE, // ignore response
|
|
Packit |
8f70b4 |
READY, // check response after connect
|
|
Packit |
8f70b4 |
REST, // check response for REST
|
|
Packit |
8f70b4 |
TYPE, // check response for TYPE
|
|
Packit |
8f70b4 |
MODE,
|
|
Packit |
8f70b4 |
CWD, // check response for CWD
|
|
Packit |
8f70b4 |
CWD_CURR, // check response for CWD into current directory
|
|
Packit |
8f70b4 |
CWD_STALE, // check response for CWD when it's not critical
|
|
Packit |
8f70b4 |
ABOR, // check response for ABOR
|
|
Packit |
8f70b4 |
SIZE, // check response for SIZE
|
|
Packit |
8f70b4 |
SIZE_OPT, // check response for SIZE and save size to *opt_size
|
|
Packit |
8f70b4 |
MDTM, // check response for MDTM
|
|
Packit |
8f70b4 |
MDTM_OPT, // check response for MDTM and save size to *opt_date
|
|
Packit |
8f70b4 |
PRET,
|
|
Packit |
8f70b4 |
PASV, // check response for PASV and save address
|
|
Packit |
8f70b4 |
EPSV, // check response for EPSV and save address
|
|
Packit |
8f70b4 |
PORT, // check response for PORT or EPRT
|
|
Packit |
8f70b4 |
FILE_ACCESS, // generic check for file access
|
|
Packit |
8f70b4 |
PWD, // check response for PWD and save it to home
|
|
Packit |
8f70b4 |
RNFR,
|
|
Packit |
8f70b4 |
USER, // check response for USER
|
|
Packit |
8f70b4 |
USER_PROXY, // check response for USER sent to proxy
|
|
Packit |
8f70b4 |
PASS, // check response for PASS
|
|
Packit |
8f70b4 |
PASS_PROXY, // check response for PASS sent to proxy
|
|
Packit |
8f70b4 |
OPEN_PROXY, // special UserGate proxy command
|
|
Packit |
8f70b4 |
ACCT_PROXY, // special ACCT with proxy password
|
|
Packit |
8f70b4 |
TRANSFER, // generic check for transfer
|
|
Packit |
8f70b4 |
TRANSFER_CLOSED, // check for transfer complete when Close()d.
|
|
Packit |
8f70b4 |
FEAT,
|
|
Packit |
8f70b4 |
OPTS_UTF8,
|
|
Packit |
8f70b4 |
LANG,
|
|
Packit |
8f70b4 |
SITE_UTIME,
|
|
Packit |
8f70b4 |
SITE_UTIME2,
|
|
Packit |
8f70b4 |
ALLO,
|
|
Packit |
8f70b4 |
QUOTED // check response for any command submitted by QUOTE_CMD
|
|
Packit |
8f70b4 |
#if USE_SSL
|
|
Packit |
8f70b4 |
,AUTH_TLS,PROT,SSCN,CCC
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
expect_t check_case;
|
|
Packit |
8f70b4 |
xstring_c cmd;
|
|
Packit |
8f70b4 |
xstring_c arg;
|
|
Packit |
8f70b4 |
Expect *next;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Expect(expect_t e,const char *a=0,const char *c=0) : check_case(e), cmd(c), arg(a) {}
|
|
Packit |
8f70b4 |
Expect(expect_t e,char c) : check_case(e)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
char cc[2]={c,0};
|
|
Packit |
8f70b4 |
arg.set(cc);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
class ExpectQueue;
|
|
Packit |
8f70b4 |
friend class Ftp::ExpectQueue; // grant access to Expect
|
|
Packit |
8f70b4 |
class ExpectQueue
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Expect *first; // next to expect
|
|
Packit |
8f70b4 |
Expect **last; // for appending
|
|
Packit |
8f70b4 |
int count;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
ExpectQueue();
|
|
Packit |
8f70b4 |
~ExpectQueue();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Push(Expect *e);
|
|
Packit |
8f70b4 |
void Push(Expect::expect_t e);
|
|
Packit |
8f70b4 |
Expect *Pop();
|
|
Packit |
8f70b4 |
Expect *FindLastCWD() const;
|
|
Packit |
8f70b4 |
int Count() const { return count; }
|
|
Packit |
8f70b4 |
bool IsEmpty() const { return count==0; }
|
|
Packit |
8f70b4 |
bool Has(Expect::expect_t) const;
|
|
Packit |
8f70b4 |
bool FirstIs(Expect::expect_t) const;
|
|
Packit |
8f70b4 |
void Close();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ref<ExpectQueue> expect;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void CheckResp(int resp);
|
|
Packit |
8f70b4 |
int ReplyLogPriority(int code) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void RestCheck(int);
|
|
Packit |
8f70b4 |
void NoFileCheck(int);
|
|
Packit |
8f70b4 |
void TransferCheck(int);
|
|
Packit |
8f70b4 |
bool Retry530() const;
|
|
Packit |
8f70b4 |
void LoginCheck(int);
|
|
Packit |
8f70b4 |
void NoPassReqCheck(int);
|
|
Packit |
8f70b4 |
void proxy_LoginCheck(int);
|
|
Packit |
8f70b4 |
void proxy_NoPassReqCheck(int);
|
|
Packit |
8f70b4 |
char *ExtractPWD();
|
|
Packit |
8f70b4 |
int SendCWD(const char *path,const char *path_url,Expect::expect_t c);
|
|
Packit |
8f70b4 |
void CatchDATE(int);
|
|
Packit |
8f70b4 |
void CatchDATE_opt(int);
|
|
Packit |
8f70b4 |
void CatchSIZE(int);
|
|
Packit |
8f70b4 |
void CatchSIZE_opt(int);
|
|
Packit |
8f70b4 |
void TurnOffStatForList();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum pasv_state_t
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
PASV_NO_ADDRESS_YET,
|
|
Packit |
8f70b4 |
PASV_HAVE_ADDRESS,
|
|
Packit |
8f70b4 |
PASV_DATASOCKET_CONNECTING,
|
|
Packit |
8f70b4 |
PASV_HTTP_PROXY_CONNECTED
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
pasv_state_t pasv_state; // state of PASV, when state==DATASOCKET_CONNECTING_STATE
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
pasv_state_t Handle_PASV();
|
|
Packit |
8f70b4 |
pasv_state_t Handle_EPSV();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool ServerSaid(const char *) const;
|
|
Packit |
8f70b4 |
bool NonError5XX(int act) const;
|
|
Packit |
8f70b4 |
bool Transient5XX(int act) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void InitFtp();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void HandleTimeout();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#if USE_SSL
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
bool ftps; // ssl and prot='P' by default (port 990)
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
#else
|
|
Packit |
8f70b4 |
static const bool ftps; // for convenience
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void DataAbort();
|
|
Packit |
8f70b4 |
void DataClose();
|
|
Packit |
8f70b4 |
void ControlClose();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SendUrgentCmd(const char *cmd);
|
|
Packit |
8f70b4 |
int FlushSendQueueOneCmd();
|
|
Packit |
8f70b4 |
int FlushSendQueue(bool all=false);
|
|
Packit |
8f70b4 |
void SendArrayInfoRequests();
|
|
Packit |
8f70b4 |
void SendSiteIdle();
|
|
Packit |
8f70b4 |
void SendAcct();
|
|
Packit |
8f70b4 |
void SendSiteGroup();
|
|
Packit |
8f70b4 |
void SendSiteCommands();
|
|
Packit |
8f70b4 |
void SendUTimeRequest();
|
|
Packit |
8f70b4 |
void SendAuth(const char *auth);
|
|
Packit |
8f70b4 |
void TuneConnectionAfterFEAT();
|
|
Packit |
8f70b4 |
void SendOPTS_MLST();
|
|
Packit |
8f70b4 |
void SendPROT(char want_prot);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *QueryStringWithUserAtHost(const char *);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int ReceiveOneLine();
|
|
Packit |
8f70b4 |
// If a response is received, it checks it for accordance with
|
|
Packit |
8f70b4 |
// response_queue and switch to a state if necessary
|
|
Packit |
8f70b4 |
int ReceiveResp();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool ProxyIsHttp();
|
|
Packit |
8f70b4 |
int http_proxy_status_code;
|
|
Packit |
8f70b4 |
// Send CONNECT method to http proxy.
|
|
Packit |
8f70b4 |
void HttpProxySendConnect();
|
|
Packit |
8f70b4 |
void HttpProxySendConnectData();
|
|
Packit |
8f70b4 |
// Send http proxy auth.
|
|
Packit |
8f70b4 |
void HttpProxySendAuth(const SMTaskRef<IOBuffer>&);
|
|
Packit |
8f70b4 |
// Check if proxy returned a reply, returns true if reply is ok.
|
|
Packit |
8f70b4 |
// May disconnect.
|
|
Packit |
8f70b4 |
bool HttpProxyReplyCheck(const SMTaskRef<IOBuffer>&);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool AbsolutePath(const char *p) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void MoveConnectionHere(Ftp *o);
|
|
Packit |
8f70b4 |
bool GetBetterConnection(int level,bool limit_reached);
|
|
Packit |
8f70b4 |
bool SameConnection(const Ftp *o) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// state
|
|
Packit |
8f70b4 |
automate_state state;
|
|
Packit |
8f70b4 |
int flags;
|
|
Packit |
8f70b4 |
bool eof;
|
|
Packit |
8f70b4 |
Timer retry_timer;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring line; // last line of last server reply
|
|
Packit |
8f70b4 |
xstring all_lines; // all lines of last server reply
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetError(int code,const char *mess=0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// settings
|
|
Packit |
8f70b4 |
xstring_c anon_user;
|
|
Packit |
8f70b4 |
xstring_c anon_pass;
|
|
Packit |
8f70b4 |
xstring_c charset;
|
|
Packit |
8f70b4 |
xstring_c list_options;
|
|
Packit |
8f70b4 |
int nop_interval;
|
|
Packit |
8f70b4 |
bool verify_data_address;
|
|
Packit |
8f70b4 |
bool verify_data_port;
|
|
Packit |
8f70b4 |
bool rest_list;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring_c skey_pass;
|
|
Packit |
8f70b4 |
bool allow_skey;
|
|
Packit |
8f70b4 |
bool force_skey;
|
|
Packit |
8f70b4 |
const char *make_skey_reply();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring netkey_pass;
|
|
Packit |
8f70b4 |
bool allow_netkey;
|
|
Packit |
8f70b4 |
const char *make_netkey_reply();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool disconnect_on_close;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
enum copy_mode_t { COPY_NONE, COPY_SOURCE, COPY_DEST };
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
copy_mode_t copy_mode;
|
|
Packit |
8f70b4 |
sockaddr_u copy_addr;
|
|
Packit |
8f70b4 |
bool copy_addr_valid;
|
|
Packit |
8f70b4 |
bool copy_passive;
|
|
Packit |
8f70b4 |
bool copy_protect;
|
|
Packit |
8f70b4 |
bool copy_ssl_connect;
|
|
Packit |
8f70b4 |
bool copy_done;
|
|
Packit |
8f70b4 |
bool copy_connection_open;
|
|
Packit |
8f70b4 |
bool copy_allow_store;
|
|
Packit |
8f70b4 |
bool copy_failed;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool use_stat;
|
|
Packit |
8f70b4 |
bool use_stat_for_list;
|
|
Packit |
8f70b4 |
bool use_mdtm;
|
|
Packit |
8f70b4 |
bool use_size;
|
|
Packit |
8f70b4 |
bool use_pret;
|
|
Packit |
8f70b4 |
bool use_feat;
|
|
Packit |
8f70b4 |
bool use_mlsd;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool use_telnet_iac;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int max_buf;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *get_protect_res();
|
|
Packit |
8f70b4 |
const char *encode_eprt(const sockaddr_u *);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
typedef FileInfo *(*FtpLineParser)(char *line,int *err,const char *tz);
|
|
Packit |
8f70b4 |
static FtpLineParser line_parsers[];
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int CanRead();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *path_to_send();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
protected:
|
|
Packit |
8f70b4 |
void PrepareToDie();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
static void ClassInit();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ftp();
|
|
Packit |
8f70b4 |
Ftp(const Ftp *);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *GetProto() const { return "ftp"; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileAccess *Clone() const { return new Ftp(this); }
|
|
Packit |
8f70b4 |
static FileAccess *New();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *ProtocolSubstitution(const char *host);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool SameLocationAs(const FileAccess *) const;
|
|
Packit |
8f70b4 |
bool SameSiteAs(const FileAccess *) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void ResetLocationData();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum ConnectLevel
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
CL_NOT_CONNECTED,
|
|
Packit |
8f70b4 |
CL_CONNECTING,
|
|
Packit |
8f70b4 |
CL_JUST_CONNECTED,
|
|
Packit |
8f70b4 |
CL_NOT_LOGGED_IN,
|
|
Packit |
8f70b4 |
CL_LOGGED_IN,
|
|
Packit |
8f70b4 |
CL_JUST_BEFORE_DISCONNECT
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
ConnectLevel GetConnectLevel() const;
|
|
Packit |
8f70b4 |
int IsConnected() const
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return GetConnectLevel()!=CL_NOT_CONNECTED;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int Read(Buffer *buf,int size);
|
|
Packit |
8f70b4 |
int Write(const void *buf,int size);
|
|
Packit |
8f70b4 |
int Buffered();
|
|
Packit |
8f70b4 |
void Close();
|
|
Packit |
8f70b4 |
bool IOReady();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// When you are putting a file, call SendEOT to terminate
|
|
Packit |
8f70b4 |
// transfer and then call StoreStatus until OK or error.
|
|
Packit |
8f70b4 |
int SendEOT();
|
|
Packit |
8f70b4 |
int StoreStatus();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int Do();
|
|
Packit |
8f70b4 |
void DisconnectLL();
|
|
Packit |
8f70b4 |
void DisconnectNow();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetFlag(int flag,bool val);
|
|
Packit |
8f70b4 |
int GetFlag(int flag) const { return flags&flag; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static time_t ConvertFtpDate(const char *);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *CurrentStatus();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int Done();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum flag_mask
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
SYNC_MODE=1,
|
|
Packit |
8f70b4 |
NOREST_MODE=4,
|
|
Packit |
8f70b4 |
IO_FLAG=8,
|
|
Packit |
8f70b4 |
PASSIVE_MODE=32,
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
MODES_MASK=SYNC_MODE|PASSIVE_MODE
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Reconfig(const char *name=0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ListInfo *MakeListInfo(const char *path);
|
|
Packit |
8f70b4 |
Glob *MakeGlob(const char *pattern);
|
|
Packit |
8f70b4 |
DirList *MakeDirList(ArgV *args);
|
|
Packit |
8f70b4 |
FileSet *ParseLongList(const char *buf,int len,int *err=0) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetCopyMode(copy_mode_t cm,bool rp,bool prot,bool sscn,int rnum,time_t tt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
copy_mode=cm;
|
|
Packit |
8f70b4 |
copy_passive=rp;
|
|
Packit |
8f70b4 |
copy_protect=prot;
|
|
Packit |
8f70b4 |
copy_ssl_connect=sscn;
|
|
Packit |
8f70b4 |
retries=rnum;
|
|
Packit |
8f70b4 |
SetTryTime(tt);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool SetCopyAddress(const Ftp *o)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(copy_addr_valid || !o->copy_addr_valid)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
memcpy(©_addr,&o->copy_addr,sizeof(copy_addr));
|
|
Packit |
8f70b4 |
copy_addr_valid=true;
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool CopyFailed() const { return copy_failed; }
|
|
Packit |
8f70b4 |
bool RestartFailed() const { return flags&NOREST_MODE; }
|
|
Packit |
8f70b4 |
bool IsPassive() const { return flags&PASSIVE_MODE; }
|
|
Packit |
8f70b4 |
bool IsCopyPassive() const { return copy_passive; }
|
|
Packit |
8f70b4 |
void CopyAllowStore()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
conn->SendCmd2("STOR",file);
|
|
Packit |
8f70b4 |
expect->Push(new Expect(Expect::TRANSFER));
|
|
Packit |
8f70b4 |
copy_allow_store=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool CopyStoreAllowed() const { return copy_allow_store; }
|
|
Packit |
8f70b4 |
bool CopyIsReadyForStore()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!expect)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
if(copy_mode==COPY_SOURCE)
|
|
Packit |
8f70b4 |
return copy_addr_valid && expect->FirstIs(Expect::TRANSFER);
|
|
Packit |
8f70b4 |
return state==WAITING_STATE && expect->IsEmpty();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void CopyCheckTimeout(const Ftp *o)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
timeout_timer.Reset(o->timeout_timer);
|
|
Packit |
8f70b4 |
CheckTimeout();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
bool AnonymousQuietMode();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SuspendInternal();
|
|
Packit |
8f70b4 |
void ResumeInternal();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class FtpS : public Ftp
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
FtpS();
|
|
Packit |
8f70b4 |
FtpS(const FtpS *);
|
|
Packit |
8f70b4 |
~FtpS();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *GetProto() const { return "ftps"; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileAccess *Clone() const { return new FtpS(this); }
|
|
Packit |
8f70b4 |
static FileAccess *New();
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#endif /* FTPCLASS_H */
|