/*/////////////////////////////////////////////////////////////////////
FTPclient.cpp (c) GDI 1999
V1.0.0 (10/4/99)
Phil Anderson. philip@gd-ind.com
Simple FTP client functionality. If you have any problems with it,
please tell me about them (or better still e-mail me the fixed
code). Please feel free to use this code however you wish, although
if you make changes please put your name in the source & comment what
you did.
Nothing awesome going on here at all (all sockets are used in
synchronous blocking mode), but it does the following
things WinInet doesn't seem to:
* Supports loads of different firewalls (I think, I don't
have access to all types so they haven't all been fully
tested yet)
* Allows you to execute any command on the FTP server
* Adds 10K to your app install rather than 1Mb #;-)
Functions return TRUE if everything went OK, FALSE if there was an,
error. A message describing the outcome (normally the one returned
from the server) will be in m_retmsg on return from the function.
There are a few error msgs in the app's string table that you'll
need to paste into your app, along with this file & FTPclient.h
If you created your app without checking the "Use Windows Sockets"
checkbox in AppWizard, you'll need to add the following bit of code
to you app's InitInstance()
if(!AfxSocketInit())
{
AfxMessageBox("Could not initialize Windows Sockets!");
return FALSE;
}
To use:
1/ Create an object of CFTPclient.
2/ Use LogOnToServer() to connect to the server. Any arguments
not used (e.g. if you're not using a firewall), pass an empty
string or zero for numeric args. You must pass a server port
number, use the FTP default of 21 if you don't know what it is.
3/ Use MoveFile() to upload/download a file, 1st arg is local file
path, 2nd arg is remote file path, 3rd arg is TRUE for a PASV
connection (required by some firewalls), FALSE otherwise, 4th arg
is TRUE to upload, FALSE to download file. MoveFile only works in
synchronous mode (ie the function will not return 'till the transfer
is finished). File transfers are always of type BINARY.
4/ You can use FTPcommand() to execute FTP commands (eg
FTPcommand("CWD /home/mydir") to change directory on the server),
note that this function will return FALSE unless the server response
is a 200 series code. This should work fine for most FTP commands,
otherwise you can use WriteStr() and ReadStr() to send commands &
interpret the response yourself. Use LogOffServer() to disconnect
when done.
/////////////////////////////////////////////////////////////////////*/
#define _FTP_API_
//#define NOOP_RESET_BUFFER
#include "FTPclient.h"
#include <fstream>
#include <string>
using namespace std;
#ifdef NOOP_RESET_BUFFER
void delay(int us)
{
#if defined (WIN32)
Sleep(us/1000);
#elif defined (__unix)
struct timeval tv;
int ret;
while(TRUE)
{
tv.tv_sec = us / 1000000;
tv.tv_usec = us % 1000000;
ret=select( 0, 0, 0, 0, &tv );
if(ret < 0)
{
if( GetErrNo() == SOCK_EINTR )
{
us = us/2;
if( us >= 50000 ) continue;
}
}
break;
}
#endif
}
#endif //NOOP_RESET_BUFFER
CFTPclient::CFTPclient()
{
m_retmsg = new string;
m_Ctrlsok= 0;
ICP_INIT(2);
} //constructor_method
CFTPclient::~CFTPclient()
{
delete m_retmsg;
CloseControlChannel();
ICP_CLOSE();
} //destructor_method
// function to connect & log on to FTP server
BOOL
CFTPclient::LogOnToServer( char const * hostname,
int hostport,
char const * username,
char const * password,
char const * acct,
char const * fwhost,
char const * fwusername,
char const * fwpassword,
int fwport,
int logontype
)
{
int port,logonpoint=0;
const int LO=-2, ER=-1;
string buf;
char temp[256];
const int NUMLOGIN=9;// currently supports 9 different login sequences
memset(temp,0,sizeof(temp));
int logonseq[NUMLOGIN][100] = {
// this array stores all of the logon sequences for the various firewalls
// in blocks of 3 nums. 1st num is command to send, 2nd num is next point in logon sequence array
// if 200 series response is rec'd from server as the result of the command, 3rd num is next
// point in logon sequence if 300 series rec'd
{0,LO,3, 1,LO,6, 2,LO,ER}, // no firewall
{3,6,3, 4,6,ER, 5,ER,9, 0,LO,12, 1,LO,15, 2,LO,ER}, // SITE hostname
{3,6,3, 4,6,ER, 6,LO,9, 1,LO,12, 2,LO,ER}, // USER after logon
{7,3,3, 0,LO,6, 1,LO,9, 2,LO,ER}, //proxy OPEN
{3,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER}, // Transparent
{6,LO,3, 1,LO,6, 2,LO,ER}, // USER with no logon
{8,6,3, 4,6,ER, 0,LO,9, 1,LO,12, 2,LO,ER}, //USER fireID@remotehost
{9,ER,3, 1,LO,6, 2,LO,ER}, //USER remoteID@remotehost fireID
{10,LO,3, 11,LO,6, 2,LO,ER} // USER remoteID@fireID@remotehost
};
if(logontype<0||logontype>=NUMLOGIN) return FALSE; // illegal connect code
// are we connecting directly to the host (logon type 0) or via a firewall? (logon type>0)
if(!logontype) {
strcpy(temp,hostname);
port=hostport;
}
else {
strcpy(temp,fwhost);
port=fwport;
}
char portstr[16];
memset(portstr,0,sizeof(portstr));
sprintf(portstr,":%d",hostport);
if(hostport!=21)
{
memset(temp,0,sizeof(temp));
sprintf(temp,"%s %s",hostname,portstr); // add port to hostname (only if port is not 21)
}
if(!OpenControlChannel(temp,port)) return false;
if(!FTPcommand("")) return FALSE; // get initial connect msg off server
// go through appropriate logon procedure
for(;;)
{
memset(temp,0,sizeof(temp));
switch(logonseq[logontype][logonpoint]) {
case 0:
sprintf(temp,"USER %s\r\n",username);
break;
case 1:
sprintf(temp,"PASS %s\r\n",password);
break;
case 2:
sprintf(temp,"ACCT %s\r\n",acct);
break;
case 3:
sprintf(temp,"USER %s\r\n",fwusername);
break;
case 4:
sprintf(temp,"PASS %s\r\n",fwpassword);
break;
case 5:
sprintf(temp,"SITE %s\r\n",hostname);
break;
case 6:
sprintf(temp,"USER %s @ %s\r\n",username,hostname);
break;
case 7:
sprintf(temp,"OPEN %s\r\n",hostname);
break;
case 8:
sprintf(temp,"USER %s @ %s\r\n",fwusername,hostname);
break;
case 9:
sprintf(temp,"USER %s @ %s %s\r\n",username,hostname,fwusername);
break;
case 10:
sprintf(temp,"USER %s @ %s @ %s\r\n",username,fwusername,hostname);
break;
case 11:
sprintf(temp,"PASS %s @ %s\r\n",password,fwpassword);
break;
}
// send command, get response
string temp1 = temp;
if(!WriteStr(temp1)) return FALSE;
if(!ReadStr()) return FALSE;
// only these responses are valid
if(m_fc!=2&&m_fc!=3) return FALSE;
logonpoint=logonseq[logontype][logonpoint+m_fc-1]; //get next command from array
switch(logonpoint) {
case ER: // ER means summat has gone wrong
*m_retmsg = Msg_Err_Logon;
return FALSE;
case LO: // LO means we're fully logged on
return TRUE;
}
}
} //LogOnToServer_method
// function to log off & close connection to FTP server
void CFTPclient::LogOffServer()
{
WriteStr("QUIT");
CloseControlChannel();
} //LogOffServer_method
// function to upload/download files
BOOL
CFTPclient::TransmitFile( char const * remotefile,
char const * localfile,
BOOL bPasv,
BOOL bDownload
)
{
string lhost,temp,rhost,substring;
int srvport,i,j;
fstream datafile;
ofstream recvfile;
ifstream sendfile;
int sockSrvr = 0;
int datachannel = -1;
int num,numread,numsent,numsend;
const int BUFSIZE=10240;
char cbuf[BUFSIZE];
int ret;
int local_save_file_open_flag = 0;//下载文件打开标志
//get filename
string fileName = bDownload ? remotefile : localfile;
string::size_type leftSlashPos = fileName.rfind( "/" );
string::size_type rightSlashPos = fileName.rfind( "\\" );
string::size_type dirPos = max( static_cast<int>(leftSlashPos), static_cast<int>(rightSlashPos) );
if( dirPos != string::npos )
fileName.erase( 0, dirPos + 1 );
// open local file
*m_retmsg = Msg_Err_FileOpen;
if( !bDownload )
sendfile.open(localfile,ios::in
小波思基
- 粉丝: 86
- 资源: 1万+
最新资源
- 知攻善防-应急响应靶机-web2.z32
- 还需要改的 只实现13数据
- 基于三菱PLC的温室大棚控制系统的设计塑料大棚温室控制 基于三菱PLC的智能农业温室大棚控制系统设计大棚电气控制组态画面
- Remote Ripple远程桌面允许用户从任何地方、任何设备上远程访问和控制其他计算机 软件的主要特点是其跨平台性,支持Windows、Mac、Linux等多种操作系统,以及iOS和Android
- 基于Unet网络实现对天文图像的降噪处理python源码+说明(高分项目)
- 知攻善防-应急响应靶机-web2.z35
- 知攻善防-应急响应靶机-web2.z36
- python基于Unet网络实现对天文图像的降噪处理源码+说明(高分项目)
- 知攻善防-应急响应靶机-web2.z01
- 知攻善防-应急响应靶机-web2.z02
- 知攻善防-应急响应靶机-web2.z03
- 知攻善防-应急响应靶机-web2.z04
- Oracle JDK1.8最后一个免费版本安装包及安装说明
- 基于STM32F051K8U6的光强传感器数据采集与风扇控制实现-含代码和注释
- 网上调查系统:性能优化与可扩展性分析
- 跨平台教务管理:教务信息平台的开发
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈