⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpcli.cpp

📁 dget是一个基于Linux平台的多线程下载工具, 采用C++开发。主要支持FTP, HTTP, MMS, RTSP协议下载, 目前为止主要实现了FTP, HTTP, MMS,RTSP协议的多线程下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * by balancesli * balancesli@gmail.com *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/utsname.h>#include <netinet/in.h>#include <linux/ip.h>#include <errno.h>#include <netdb.h>#include <fcntl.h>#include <unistd.h>#include <fcntl.h>#include <assert.h>#include <ctype.h>#include <sys/time.h>#include <time.h>#include <linux/ip.h>#include <pthread.h>#include "Utils.h"#include "Socket.h"#include "Url.h"#include "Task.h"#include "FtpCli.h"#include "dget.h"/**************** class TFtpCli ******************************/#define UNIMPLEMENTED_CMD(a)  ((a == 500) || (a == 502) || (a == 504))#define MAX_MSG_SIZE 1024TFtpCli :: TFtpCli(TUrl * up) : CtrlSkp(NULL), DataSkp(NULL), ListenSkp(NULL){	HostName = up->HostName;	UserName = up->UserName;	PassWord = up->PassWord;	HostDirName = up->HostDirName;	HostFileName = up->HostFileName;	IsPasv = true;	IsBinary = true;	IsAscii = false;}TFtpCli :: ~TFtpCli(void){		if(CtrlSkp != NULL) 	{		close(CtrlSkp->GetSockfd());		delete CtrlSkp;	}		if(DataSkp != NULL) 	{		close(DataSkp->GetSockfd());		delete DataSkp;	}				if(ListenSkp != NULL) 	{		close(ListenSkp->GetSockfd());		delete ListenSkp;	}}	void TFtpCli :: Disconnect(void){	if(CtrlSkp == NULL)	{		ShowMsg("Failed to Disconnect");		return; 	}		close(CtrlSkp->GetSockfd());	ShowMsg("Logout Ok");}uerr_t TFtpCli :: Connect(void){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;		if(CtrlSkp != NULL) 	{		Disconnect();		delete CtrlSkp;	}		CtrlSkp = new TSocketCli(HostName);	err = CtrlSkp->Connect(21);    	if (err != NOCONERROR)		return err;	CtrlSock = CtrlSkp->GetSockfd();    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;	    if (*szBuffer != '2')		return FTPCONREFUSED;	    return FTPOK;}/* * return the numeric response of the ftp server by reading the first 3 * characters in the buffer  */int TFtpCli :: GetReturn(const char * szBuffer){    char Code[3];    strncpy(Code, szBuffer, 3);    return atoi(Code);}int TFtpCli :: CheckMsg(int Sock, char * szBuffer, int Len){    int retval;    if ((retval = Recv(Sock, szBuffer, Len, MSG_PEEK)) == -1)    {		ShowMsg("Error checking for ftp data-: %s", strerror(errno));		return retval;    }    return retval;}int TFtpCli :: ReadMsg(int Sock, char * szBuffer, int Len){    int retval; //   Cancelation-point    pthread_testcancel();    if ((retval = Recv(Sock, szBuffer, Len, 0)) == -1)    {		ShowMsg("Error Receiving ftp  data-: %s", strerror(errno));		return retval;    }    pthread_testcancel();    return retval;}uerr_t TFtpCli :: SendMsg(int Sock, char * szBuffer, int Len){    if (Send(Sock, szBuffer, Len, 0) == -1)    {		ShowMsg("Error Sending ftp  data-: %s", strerror(errno));		return FTPERR;    }    return FTPOK;}uerr_t TFtpCli :: GetLine(int Sock, char * szBuffer){    int iLen, iBuffLen = 0, ret = 0;    char *szPtr = szBuffer, ch = 0;	ret = CheckMsg(Sock, &ch, 1);	    while (iBuffLen < FTP_BUF_SIZE && ret > 0)    {		iLen = ReadMsg(Sock, &ch, 1);				if (iLen != 1)	    	return FTPERR;				iBuffLen += iLen;		*szPtr = ch;		szPtr += iLen;		if (ch == '\n')	    	break;		    }		if (ret == -1)		return FTPERR;   	*(szPtr + 1) = '\0';    	return FTPOK;}uerr_t TFtpCli :: GetReply(int Sock, char * szBuffer){    int done = 0;	    memset(szBuffer, 0, FTP_BUF_SIZE);    while (!done)    {		if (GetLine(Sock, szBuffer) != FTPOK)	    	return FTPERR;				(void)strtok(szBuffer, "\r\n");				if (szBuffer[3] != '-' && GetReturn(szBuffer) > 0)	    	done = 1;    }    return FTPOK;}uerr_t TFtpCli :: Ascii(void){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;	CtrlSock = CtrlSkp->GetSockfd();	    sprintf(szBuffer, "TYPE A\r\n");    	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);    if (err != FTPOK)		return err;    if (*szBuffer != '2')		return FTPUNKNOWNTYPE;    return FTPOK;}uerr_t TFtpCli :: Binary(void){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;		CtrlSock = CtrlSkp->GetSockfd();	    sprintf(szBuffer, "TYPE I\r\n");    	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));	    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;    if (*szBuffer != '2')		return FTPUNKNOWNTYPE;    return FTPOK;}uerr_t TFtpCli :: Port(const char * Cmd){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;		CtrlSock = CtrlSkp->GetSockfd();    strcpy(szBuffer, Cmd);	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));	    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);    if (err != FTPOK)		return err;    if (*szBuffer != '2')		return FTPPORTERR;    return FTPOK;}uerr_t TFtpCli :: List(const char * FileName){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;		CtrlSock = CtrlSkp->GetSockfd();	    sprintf(szBuffer, "LIST %s\r\n", FileName);	    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);    if (err != FTPOK)		return err;    if (*szBuffer == '5')		return FTPNSFOD;    if (*szBuffer != '1')		return FTPERR;    return FTPOK;}uerr_t TFtpCli :: Retr(const char * FileName){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;	CtrlSock = CtrlSkp->GetSockfd();		sprintf(szBuffer, "RETR %s\r\n", FileName);	    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));	    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);    if (err != FTPOK)		return err;    if (*szBuffer == '5')		return FTPNSFOD;    if (*szBuffer != '1')		return FTPERR;    	return FTPOK;}/* PASV command */uerr_t TFtpCli :: Pasv(unsigned char * addr){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];    unsigned char *p;    int i;   	int CtrlSock; 		CtrlSock = CtrlSkp->GetSockfd();		sprintf(szBuffer, "PASV\r\n");	    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK) 		return err;	    if (*szBuffer != '2') 		return FTPNOPASV;	    p = (unsigned char *)szBuffer;    	for (p += 4; *p && !isdigit(*p); p++);	    if (!*p) 		return FTPINVPASV;    for (i = 0; i < 6; i++)    {		addr[i] = 0;		for (; isdigit(*p); p++)	    	addr[i] = (*p - '0') + 10 * addr[i];				if (*p == ',')	    	p++;		else if (i < 5)	    	return FTPINVPASV;    }    return FTPOK;}uerr_t TFtpCli :: Rest(long Bytes){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;		CtrlSock = CtrlSkp->GetSockfd();	sprintf(szBuffer, "REST %ld\r\n", Bytes);	    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;   	err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;	    if (*szBuffer != '3')		return FTPRESTFAIL;    	return FTPOK;}/* * CWD command  */uerr_t TFtpCli :: Cwd(const char * Dir){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock;	   	CtrlSock = CtrlSkp->GetSockfd(); 		sprintf(szBuffer, "CWD %s\r\n", Dir);    	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));	    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;		/*     * check and see wether the CWD succeeded      */	if (*szBuffer == '5')		return FTPNSFOD;    if (*szBuffer != '2')		return CWDFAIL;    return FTPOK;}/* *  Returns the Current working directory in dir  */uerr_t TFtpCli :: Pwd(char * Dir){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	char *r, *l;   	int CtrlSock;	   	CtrlSock = CtrlSkp->GetSockfd(); 	sprintf(szBuffer, "PWD\r\n");    	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;    /*     * check and see wether the PWD succeeded      */    if (*szBuffer == '5')		return FTPPWDERR;    if (*szBuffer != '2')		return PWDFAIL;    if ((r = strrchr(szBuffer, '"')) != NULL)    {		l = strchr(szBuffer, '"');		if ((l != NULL) && (l != r))		{	    	*r = '\0';	    	++l;	    	strcpy(Dir, l);	    	*r = '"';		}    } 	else    {		if ((r = strchr(szBuffer, ' ')) != NULL)		{	    	*r = '\0';	    	strcpy(Dir, szBuffer);	    	*r = ' ';		}    }		ShowMsg(Dir);	    return FTPOK;}/* * this will call bind to return a bound socket then the  ftp server  * will be connected with a port request and asked to connect  */uerr_t TFtpCli :: GetListenSocket(void){	uerr_t err;    char Cmd[MAX_MSG_SIZE];    	struct sockaddr_in TmpAddr;	struct sockaddr_in SvrAddr;    	socklen_t Len;		char *Ports, *IpAddr;    	int ListenSock;	int CtrlSock;	struct utsname ut;		uname(&ut);		if(ListenSkp != NULL)	{		close(ListenSkp->GetSockfd());		delete ListenSkp;	}		ListenSkp = new TSocketSvr(ut.sysname);	err = ListenSkp->Bind();	ListenSock = ListenSkp->GetSockfd();    	if (err != BINDOK)		return LISTENERR;    Len = sizeof(SvrAddr);    if (getsockname(ListenSock, (struct sockaddr *)&SvrAddr, &Len) < 0)    {		perror("getsockname");		close(ListenSock);		return CONPORTERR;    }   	Len = sizeof(TmpAddr);	CtrlSock = CtrlSkp->GetSockfd();    if (getsockname(CtrlSock, (struct sockaddr *)&TmpAddr, &Len) < 0)    {		perror("getsockname");		close(CtrlSock);		return CONPORTERR;    }    IpAddr = (char *)&TmpAddr.sin_addr;    Ports = (char *)&SvrAddr.sin_port;#define  UC(b)  (((int)b)&0xff)    sprintf(Cmd, "PORT %d,%d,%d,%d,%d,%d\r\n",	    UC(IpAddr[0]), UC(IpAddr[1]), UC(IpAddr[2]), UC(IpAddr[3]),	    UC(Ports[0]), UC(Ports[1]));    err = Port(Cmd);	    if (err != FTPOK)		return err;    	return FTPOK;}uerr_t TFtpCli :: Login(void){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock; 		CtrlSock = CtrlSkp->GetSockfd();		sprintf(szBuffer, "USER %s\r\n", UserName);    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    	if (err != FTPOK)		return err;		memset(szBuffer, 0, FTP_BUF_SIZE);    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;    if (*szBuffer == '2')		return FTPOK;    	if (*szBuffer != '3')		return FTPLOGREFUSED;	sprintf(szBuffer, "PASS %s\r\n", PassWord);    	err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);    if (err != FTPOK)		return err;    if (*szBuffer != '2')		return FTPLOGREFUSED;    return FTPOK;}uerr_t TFtpCli :: RetrFileKnownSize(TThread * This){	long Total = 0, BytesRead = 0, Length;		char szBuffer[FTP_BUF_SIZE];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -