/*/////////////////////////////////////////////////////////////////////
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
小波思基
- 粉丝: 85
- 资源: 1万+
最新资源
- JAVA基于SSM的java智能制造系统源码数据库 MySQL源码类型 WebForm
- matlab求解热传导实例 matlab求解热传导问题的几个例子.pdf
- 数字人软件安装包.apk
- 偏微分方程数值解法的MATLAB源码 一阶双曲型方程数值解法及其MATLAB实现.docx
- 基于MATLAB一维热传导方程的模拟程序.docx
- 基于matlab的一维偏微分方程的pdepe函数解法 MATLAB环境中利用pdepe函数求解一维偏微分方程的技术.docx
- JAVA的Springboot+vue在线考试系统源码数据库 MySQL源码类型 WebForm
- 机器学习2.ipynb
- 传热学大作业-利用matlab程序解决热传导问题 传热学MATLAB数值模拟-热传导问题与高斯-赛德尔迭代法.docx
- PDE求三维的数值 热传导方程.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈