栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c/c++ 实现FTP+SSL/TLS FTPS客户端(隐式+被动)和sftp客户端

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c/c++ 实现FTP+SSL/TLS FTPS客户端(隐式+被动)和sftp客户端

写FTP+SSL/TLS(FTPS)比SFTP客户端要麻烦点,虽然有ftplibpp这种优秀的库可以用,但是我发现ftplibpp在对有些FTPS服务端支持的并不是特别好,比如说FTPS+隐式链接时,会出现一些问题,本来想自己改一下ftplibpp但是发现改起来并非容易,索性自己重新了一个ftps客户端。

 目前实现了隐式+被动的方式ftps客户端以及sftp客户端。sftp就比较方便libssh2库直接有函数支持非常方便。

注:每台服务器的ftp协议可能会有细微差别,需要自行调整。

l

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"

//settings
#define IMPLICIT_CONN 0
#define EXPLICIT_CONN 1

//ftp
#define FEAT_CMD "FEATrn"
#define TYPE_A_CMD "TYPE Arn"
#define TYPE_I_CMD "TYPE Irn"
#define PASV_CMD "PASVrn"
#define PROT_P_CMD "PROT Prn"
#define PBSZ_0_CMD "PBSZ 0rn"
#define OPTS_MLST "OPTS MLST Size;Modify;Type;Perm;rn"
#define SET_UTF8_CMD "OPTS UTF8 ONrn"
#define ABOR_CMD "ABORrn"
#define SYST_CMD "SYSTrn"
#define AUTH_SSL_CMD "AUTH SSLrn"
#define AUTH_TLS_CMD "AUTH_TLSrn"

//socket
#define SETSOCKOPT_OPTVAL_TYPE (void *)

//ssl/tls
#define _FTPLIB_SSL_CLIENT_METHOD_ TLSv1_2_client_method
typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct bio_st BIO;
typedef struct x509_st X509;
//typedef bool (*FtpCallbackCert)(void *arg, X509 *cert);

//ftp cmd codemapping
#define DOWNLOAD 0
#define UPLOAD   1
#define LS_AL    2


typedef struct _ftps_client_{
	SSL* ssl;
	SSL_CTX* ctx;
	BIO* sbio;
	int connfd;
	int mode;
	char ip[200];
	X509 *cert;
}FtpsClient;



struct _sftp_client_
{
	LIBSSH2_SESSION* session;
	LIBSSH2_SFTP* sftp_session;
	LIBSSH2_SFTP_HANDLE* sftp_handle;
	char                curdir[2048];
	int                 sockfd;
}SftpClient;



static int SetConnType(FtpsClient *cli, const int type);
static int CloseFtpsDataConn(FtpsClient *cli,FtpsClient *datahandle);




int TestConnection(int sock)
{
    struct sockaddr_in addr;
    socklen_t addr_len = sizeof(addr);
    int32_t ret = getsockname(sock, (struct sockaddr *)&addr, &addr_len);
    if(ret == 0)
    {
        printf("getsockname succ:%s:%dn", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    }
    else
    {
        printf("getsockname failed,error=%dn", errno);
        
    }

    memset(&addr, 0, sizeof(addr));
    ret = getpeername(sock, (struct sockaddr *)&addr, &addr_len);
    if(ret == 0)
    {
        printf("getpeername succ:%s:%dn", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    }
    else
    {
        printf("getpeername failed,error=%dn", errno);
        return -1;
    }
    
    return 0;
}


int OpenConnectByIp(const char* ip, const char* port)
{

	struct sockaddr_in sa;
	//    fd_set             rSet;
	int                connfd = 0;
	//    int                arg = 0;

	memset(&sa, 0, sizeof(sa));

	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = inet_addr(ip);
	sa.sin_port = htons(atoi(port));

	connfd = socket(AF_INET, SOCK_STREAM, 0);
	if (connfd < 0) {
		return -1;
	}
	
	int r = connect(connfd, (struct sockaddr*)&sa, sizeof(sa));
	if (r) {
		perror("sock connect:");
		fprintf(stderr, "connect err retcode:%d", r);
		
		close(connfd);
		return -1;
	}

	return connfd;
}




int OpenConnectByHost(FtpsClient *cli, const char *host)
{
	struct sockaddr_in sin;
	struct linger lng = { 0, 0 };
	struct hostent *phe;
	struct servent *pse;
	int sControl = 0;
	int on=1;
	int ret;
	char *lhost;
	char *pnum;
	
	memset(&sin,0,sizeof(sin));
	sin.sin_family = AF_INET;
	lhost = strdup(host);
	pnum = strchr(lhost,':');
	if (pnum == NULL)
	{
		if ((pse = getservbyname("ftp","tcp")) == NULL)
		{
			perror("getservbyname");
			free(lhost);
			return 0;
		}
		sin.sin_port = pse->s_port;
	}
	else
	{
		*pnum++ = '';
		if (isdigit(*pnum)) sin.sin_port = htons(atoi(pnum));
		else
		{
			pse = getservbyname(pnum,"tcp");
			sin.sin_port = pse->s_port;
		}
	}
	printf("getservbyname successn");	
		
	ret = inet_aton(lhost, &sin.sin_addr);
	if (ret == 0){
		if ((phe = gethostbyname(lhost)) == NULL)
		{
			perror("gethostbyname");
			free(lhost);
			return -1;
		}
		memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);
		snprintf(cli->ip,sizeof(cli->ip),"%s",inet_ntoa(*(struct in_addr*)phe->h_addr_list[0])	);	
	}else
		snprintf(cli->ip,sizeof(cli->ip),"%s",lhost);	
	
	
	free(lhost);

	sControl = socket(AF_INET, SOCK_STREAM, 0);
	if (sControl == -1)
	{
		perror("socket");
		return -1;
	}
	
	if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1)
	{
		perror("setsockopt");
		return -1;
	}
	
	if (setsockopt(sControl,SOL_SOCKET,SO_LINGER, SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1)
	{
		perror("setsockopt");
		close(sControl);
		return -1;
	}
	

	if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1)
	{
		perror("connect");
		return -1;
	}
	printf("socket connect success,connect fd = %dn",sControl);	
	
	cli->connfd = sControl;
	
	return 0;
	
}









int InitSSL(FtpsClient *cli)
{
	SSL_library_init();
	SSL_load_error_strings();
	cli->ctx = SSL_CTX_new(_FTPLIB_SSL_CLIENT_METHOD_());
	SSL_CTX_set_verify(cli->ctx, SSL_VERIFY_NONE, NULL);
	cli->ssl = SSL_new(cli->ctx);	
	
	return 0;	
}


int NegoSSL(FtpsClient *cli)
{
	int ret = 0;
	long iErr = 0;
	char *pErr = NULL;
//	cli->sbio = BIO_new_socket(cli->connfd, BIO_NOCLOSE);
//	SSL_set_bio(cli->ssl,cli->sbio,cli->sbio);

	SSL_set_fd(cli->ssl,cli->connfd);
	ret = SSL_connect(cli->ssl);
	printf("ssl_connect %s  ret = %d n ",ret==1?"success":"failed",ret);
	if(ret<=0){
		ret = SSL_get_error(cli->ssl, ret);
		printf("SSL_get_error return code[%d]n",ret);
		ERR_print_errors_fp(stdout);
		iErr = ERR_get_error();
		pErr = ERR_error_string(ret, NULL);
		printf("pErr=%sn",pErr);
		return -1;
	}
	cli->cert = SSL_get_peer_certificate(cli->ssl);
	return 0;
}


int PrintResp(FtpsClient *cli)
{
	char recvbuf[10240];bzero(recvbuf,sizeof(recvbuf));
	SSL_read(cli->ssl, recvbuf, sizeof(recvbuf));
	printf("Resp:%s",recvbuf);
	return 0;	
}


int EnRecv(FtpsClient *cli,char *recvbuf,int recvlen)
{
	return SSL_read(cli->ssl, recvbuf, recvlen);
}


int EnSend(FtpsClient *cli,const char *sendbuf,int sendlen)
{
	int ret = SSL_write(cli->ssl, sendbuf, sendlen);
	if(ret <= 0){
		printf("SSL_write error");
		return -1;
	}	
	return 0;	
}




int FtpsConn(FtpsClient *cli,const char *host)
{
	int ret = 0;
	
	ret = OpenConnectByHost(cli,host);
	if(ret)
		return -1;
	ret = InitSSL(cli);
	if(ret)
		return -1;	
	ret = NegoSSL(cli);	
	if(ret)
		return -1;	

	
	return 0;	
}


int FtpsLogin(FtpsClient *cli,const char *user,const char *pass)
{
	char buff[10240];
	bzero(buff,sizeof(buff));
	snprintf(buff,sizeof(buff),"USER %srn",user);
	EnSend(cli,buff,strlen(buff));
	PrintResp(cli);
	snprintf(buff,sizeof(buff),"PASS %srn",pass);
	EnSend(cli,buff,strlen(buff));
	PrintResp(cli);
	
	SetConnType(cli,0);	
	
	return 0;
}


int SetConnType(FtpsClient *cli, const int type)
{
	char rbuff[1024];
	bzero(rbuff,sizeof(rbuff));
	
	EnSend(cli,FEAT_CMD,strlen(FEAT_CMD));
	PrintResp(cli);	
	
	EnSend(cli,SYST_CMD,strlen(SYST_CMD));
	PrintResp(cli);		

	
	EnSend(cli,SET_UTF8_CMD,strlen(SET_UTF8_CMD));
	PrintResp(cli);	
	
	EnSend(cli,PROT_P_CMD,strlen(PROT_P_CMD));
	PrintResp(cli);	
	
	EnSend(cli,PBSZ_0_CMD,strlen(PBSZ_0_CMD));
	PrintResp(cli);
	
	
	if(EXPLICIT_CONN == type){
		
		EnSend(cli,AUTH_SSL_CMD,strlen(AUTH_SSL_CMD));
		PrintResp(cli);
		EnSend(cli,AUTH_TLS_CMD,strlen(AUTH_TLS_CMD));
		PrintResp(cli);
	}
	
	return 0;
	
}


FtpsClient* OpenFtpsClient(const char *host)
{
	FtpsClient* cli = NULL;
	int failed = 0;
	
	cli = (FtpsClient*)malloc(sizeof(FtpsClient));
	if(cli == NULL){
		perror("FtpsClient control handle malloc errn");	
		return NULL;
	}
		
	
	failed = FtpsConn(cli,host);
	if(failed){
		return NULL;
	}
	
	PrintResp(cli);

	return cli;
	
}





int FtpsOpenPasvSockConn(FtpsClient *cli,FtpsClient *datahandle)
{
	int ret = 0;
	char host[500];
	int port = 0;
	char *cp,buff[1024],str1[100],str2[100],str3[100];
	int v[7];

	
	
	do{

		bzero(buff,sizeof(buff));
		bzero(v,sizeof(v));
		EnSend(cli,PASV_CMD,strlen(PASV_CMD));
//		PrintResp(cli);
		EnRecv(cli,buff,sizeof(buff));
		printf("PASV port :%s",buff);
		cp = strchr(buff,'(');
		if (cp == NULL) {
			printf("PASV return may some error");
			return -1;
		}	
		cp++;
	
		sscanf(buff,"%d %s %s %s (%d,%d,%d,%d,%d,%d).",&v[0],str1,str2,str3,&v[1],&v[2],&v[3],&v[4],&v[5],&v[6]);        
		
		printf("server ip=%sn",cli->ip);
		port=v[5]*256+v[6];
		printf("port=[%d] v[5]=%d,v[6]=%dn",port,v[5],v[6]);
		
		snprintf(host,sizeof(host),"%s:%d",cli->ip,port);		
		
		ret = OpenConnectByHost(datahandle,host);
		if(ret < 0)
			printf("Host:%s data sock connect failed,To retry another port...n",host);
		else
			break;	
		sleep(5);
	}while(ret < 0);
	
//	TestConnection(datahandle->connfd);
	
	return 0;
}



int FtpsOpenPasvSslConn(FtpsClient *cli,FtpsClient *datahandle)
{
	int success = 0;
	int failed = 0;
	char *perr = NULL;
	datahandle->ssl = SSL_new(cli->ctx);
	if(datahandle->ssl == NULL){
		printf("pdatacli->ssl errn");
		close(datahandle->connfd);
		return -1;	
	}
	SSL_set_fd(datahandle->ssl,datahandle->connfd);
	success = SSL_connect(datahandle->ssl);
	printf(" ssl_connect %s  success = %d n ",success==1?"success":"failed",success);
	if (success != 1){
		failed = SSL_get_error(datahandle->ssl, success);
		perr = ERR_error_string(failed, NULL);
		printf("ssl connect err:[%s] errcode:[%d]n",perr,failed);
		return -1;	
	} 	
	
	return 0;
}


int FtpsOpenPasvDataConn(FtpsClient *cli,FtpsClient *datahandle,const char *cmd)
{
	if(cli == NULL || datahandle == NULL || cmd == NULL){
		printf("cli or datahandle or cmd is null pointer");
		return -1;
	}
	
	int failed = 0;
	char buff[1024];
	bzero(buff,sizeof(buff));

	failed = FtpsOpenPasvSockConn(cli,datahandle);
	if(failed){
		return -1;	
	}
	
	EnSend(cli,TYPE_I_CMD,strlen(TYPE_I_CMD));
	PrintResp(cli);
	EnSend(cli,cmd,strlen(cmd));
	EnRecv(cli,buff,sizeof(buff));
	printf("%sn",buff);
	if(buff[0] == '5'){
		printf("Failed to execute %s n",cmd);
		printf("%sn",buff);
		close(datahandle->connfd);
		return -1;
	}
	
	
	failed = FtpsOpenPasvSslConn(cli,datahandle);
	if(failed){
		close(datahandle->connfd);
		return -1;	
	}
	
	return 0;
}

int FtpsAccessDataByPasvMode(FtpsClient *cli,const char *localpath,const char *cmd)
{
	if(cli == NULL || cmd ==NULL)
		return -1;

	if(localpath == NULL){
			localpath = "./temp.record";
	}

	int failed = 0,len = 0;
	FtpsClient *datahandle = NULL;
	FILE *fp = NULL;
	char buff[10240];
	
	bzero(buff,sizeof(buff));
	
	datahandle = (FtpsClient *)malloc(sizeof(FtpsClient));
	if(datahandle == NULL){
		perror("datahandle malloc err:");	
		return -1;
	}
	
	bzero(datahandle,sizeof(FtpsClient));
	
	fp = fopen(localpath,"wb+");
	if(fp == NULL){
		perror("To open local path error when download file:");	
		return -1;
	}
	
	failed = FtpsOpenPasvDataConn(cli,datahandle,cmd);
	if(failed){
		printf("Ftps Open Pasv Data Connection errorn");
		return -1;
	}
	
	while( (len = SSL_read(datahandle->ssl,buff,sizeof(buff))) > 0){
		if (fwrite(buff, 1, len, fp) <= 0)
		{
			perror("local path");
			break;
		}		
		bzero(buff,sizeof(buff));
	}//end while	

	
	CloseFtpsDataConn(cli,datahandle);
	fclose(fp);
	return 0;	
	
}



int FtpsGet(FtpsClient *cli,const char *localpath,const char *remotepath)
{
	char cmd[10240];
	int failed = 0;
	char buff[10240];
	
	bzero(cmd,sizeof(cmd));
	bzero(buff,sizeof(buff));


	snprintf(cmd,sizeof(cmd),"RETR %srn",remotepath);
	
	failed = FtpsAccessDataByPasvMode(cli, localpath, cmd);
	if(failed){
		printf("Download remote File[%s] failedn",cmd);
		return -1;
	}
	
	return 0;	
}


int FtpsSize(FtpsClient *cli,const char *path, size_t *size)
{
	char cmd[256],buff[1024];
	size_t resp = 0,sz = 0,rv=0;
	bzero(cmd,sizeof(cmd));
	bzero(buff,sizeof(buff));

	snprintf(cmd,sizeof(cmd), TYPE_A_CMD);
	EnSend(cli,cmd,strlen(cmd));
	EnRecv(cli,buff,sizeof(buff));
	printf("recv = %sn",buff);
	
	bzero(buff,sizeof(buff));
	snprintf(cmd,sizeof(cmd),"SIZE %srn",path);
	EnSend(cli,cmd,strlen(cmd));
	EnRecv(cli,buff,sizeof(buff));
	printf("recv = %sn",buff);

	if (sscanf(buff, "%lu %lu", &resp, &sz) == 2) 
		*size = sz;
	else 
		rv = -1;

   return rv;
}



int FtpsDir(FtpsClient *cli,const char *localpath,const char *remotepath)
{
	char cmd[10240];
	int failed = 0;

	
	bzero(cmd,sizeof(cmd));

	snprintf(cmd,sizeof(cmd),"LIST -aL %srn",remotepath);
	
	failed = FtpsAccessDataByPasvMode(cli, localpath, cmd);
	if(failed){
		printf("Download remote File[%s] failedn",cmd);
		return -1;
	}
	
	return 0;		
}


int FtpsChdir(FtpsClient *cli,const char *path)
{
	if(path == NULL)
		return 0;
	
	char buf[256];
	int ret = 0;
	
	sprintf(buf,"CWD %srn",path);
	ret = EnSend(cli,buf,strlen(buf));
	if(ret <0){
		return -1;
	}	
	
	bzero(buf,sizeof(buf));
	ret = EnRecv(cli,buf,sizeof(buf));
	if(ret <=0){
		return -1;
	}	
	printf("%sn",buf);
	if(buf[0] == '5')
		return -1;	
	
	return 0;
}





int CloseFtpsDataConn(FtpsClient *cli,FtpsClient *datahandle)
{
	EnSend(cli,ABOR_CMD,strlen(ABOR_CMD));
	PrintResp(cli);
	PrintResp(cli);
	CloseFtpsClient(datahandle);		
	return 0;
}



int CloseFtpsClient(FtpsClient *cli)
{
	if(cli == NULL)
		return 0;
	if(cli->ssl != NULL)
		SSL_free(cli->ssl);
	if(cli->ctx != NULL)	
		SSL_CTX_free(cli->ctx);	
	close(cli->connfd);
	free(cli);
	
	return 0;
}






SftpClient* OpenSftpClient(const char* svrip, const char* svrport)
{
	LIBSSH2_SESSION* session = NULL;
	int clientfd = 0;
	int failed = 0, ii = 0, finlen = 0;
	SftpClient* sclient = NULL;

	sclient = (SftpClient*)malloc(sizeof(SftpClient));
	if (sclient == NULL) {
		fprintf(stderr, "SftpClient malloc err!");
		return NULL;
	}

	bzero(sclient, sizeof(SftpClient));

	clientfd = OpenConnectByIp(svrip, svrport);
	if (clientfd < 0) {
		fprintf(stderr, "OpenConnectByIp errn");
		return NULL;
	}


	failed = libssh2_init(0);
	if (failed) {
		fprintf(stderr, "libssh2 initialization failed (%d)n", failed);
		close(clientfd);
		return NULL;
	}

	session = libssh2_session_init();
	if (!session)
	{
		close(clientfd);
		return NULL;
	}

	libssh2_session_set_blocking(session, 1);

	while ((failed = libssh2_session_handshake(session, clientfd)) == LIBSSH2_ERROR_EAGAIN);
	if (failed) {
		fprintf(stderr, "Call libssh2_session_handshake failed,code[%d]n", failed);
		libssh2_session_free(session);
		close(clientfd);
		return NULL;
	}


	
	const char* fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
	finlen = strlen(fingerprint);
	for (ii = 0; ii < finlen; ii++) {
		fprintf(stderr, "%08x", fingerprint[ii]);
	}
	fprintf(stderr, "n");

	sclient->session = session;
	sclient->sockfd = clientfd;

	return sclient;
}

int SftpLogin(SftpClient* sclient, const char* user, const char* pswd)
{
	if (sclient == NULL)
		return -1;

	int failed = -1;

	while ((failed = libssh2_userauth_password(sclient->session, user, pswd)) == LIBSSH2_ERROR_EAGAIN);
	if (failed) {
		fprintf(stderr, "Authentication by password failed user[%s] pswd[%s] libssh2 failed code[%d]n", user, pswd, failed);
		return -1;
	}

	sclient->sftp_session = libssh2_sftp_init(sclient->session);
	if (sclient->sftp_session == NULL) {
		fprintf(stderr, "Unable to init SFTP session ,libssh2 failed code[%lu]n", libssh2_sftp_last_error(sclient->sftp_session));
		return -1;
	}

	return 0;
}



int SftpGet(SftpClient* client, const char* dstlocal, const char* srcremote)
{
	if (client == NULL)
		return -1;

	FILE* fp = NULL;
	char  buff[1024];
	int   readbytes = 0;

	bzero(buff, sizeof(buff));



	client->sftp_handle = libssh2_sftp_open(client->sftp_session, srcremote, LIBSSH2_FXF_READ, 0);
	if (client->sftp_handle == NULL) {
		fprintf(stderr, "sftp remote path[%s] err! errcode[%lu]n", srcremote, libssh2_sftp_last_error(client->sftp_session));
		return -1; 
	}

	fp = fopen(dstlocal, "wb+");
	if (fp == NULL) {
		fprintf(stderr, "fopen local path[%s] err!n", dstlocal);
		return -1;
	}

	do {
		readbytes = libssh2_sftp_read(client->sftp_handle, buff, sizeof(buff));
		if (!readbytes) {
			break;
		}

		fwrite(buff, 1, readbytes, fp);
		bzero(buff, sizeof(buff));

	} while (1);

	fclose(fp);
	return 0;
}


int SftpPut(SftpClient* client, const char* dstremote, const char* srclocal)
{
	if (client == NULL)
		return -1;

	FILE* fp = NULL;
	char  buff[1024];
	int   localreadbytes = 0;
	int   remotewritebytes = 0;
	char* curptr = NULL;

	bzero(buff, sizeof(buff));

	fp = fopen(srclocal, "rb");
	if (fp == NULL) {
		fprintf(stderr, "fopen src local path[%s] err!", srclocal);
		return -1;
	}

	client->sftp_handle = libssh2_sftp_open(client->sftp_session, dstremote,
		LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC,
		LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR |
		LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH);
	if (client->sftp_handle == NULL) {
		fprintf(stderr, "Open remote path[%s] err! %lun", dstremote, libssh2_sftp_last_error(client->sftp_session));
		return -1;
	}

	do {
		localreadbytes = fread(buff, 1, sizeof(buff), fp);
		if (localreadbytes <= 0) {
			break;
		}
		curptr = buff;
		do {
			remotewritebytes = libssh2_sftp_write(client->sftp_handle, curptr, localreadbytes);
			if (remotewritebytes < 0)
				break;

			curptr += remotewritebytes;
			localreadbytes -= remotewritebytes;

		} while (localreadbytes);

	} while (remotewritebytes > 0);

	return 0;
}


int SftpDir(SftpClient* client, const char* path)
{
	if (client == NULL)
		return -1;

	LIBSSH2_SFTP_ATTRIBUTES attrs;
	int                     success = 0;
	char                    entry[1024];
	char                    file[1024];

	bzero(entry, sizeof(entry));
	bzero(file, sizeof(file));

	client->sftp_handle = libssh2_sftp_opendir(client->sftp_session, path);
	if (client->sftp_handle == NULL) {
		fprintf(stderr, "sftp opendir err!n");
		return -1;
	}


	
	while (1) {
		success = libssh2_sftp_readdir_ex(client->sftp_handle, file, sizeof(file), entry, sizeof(entry), &attrs);
		if (success) {
			if (entry[0] != '') {
				if (!strcmp(file, ".") || !strcmp(file, "..")) {
					continue;
				}
				if (S_ISREG(attrs.permissions)) {
					fprintf(stderr, "file[%s]n", file);
				}
				else if (S_ISDIR(attrs.permissions)) {
					fprintf(stderr, "dir[%s]n", file);
				}
			}
		}
		else
			break;

		bzero(entry, sizeof(entry));
		bzero(file, sizeof(file));

	}//end while 1 ...

	if (0 != libssh2_sftp_closedir(client->sftp_handle)) {
		fprintf(stderr, "sftp close dir err!n");
		return -1;
	}

	client->sftp_handle = NULL;

	return 0;
}


int SftpChdir(SftpClient* client, const char* path)
{
	if (client == NULL)
		return -1;

	return 0;

}


int CloseSftpClient(SftpClient* client)
{
	if (client == NULL)
		return 0;

	if (client->sftp_handle != NULL)
		libssh2_sftp_close(client->sftp_handle);

	if (client->sftp_session != NULL)
		libssh2_sftp_shutdown(client->sftp_session);

	if (client->sftp_session != NULL)
		libssh2_session_disconnect(client->session, "To shutdown sftp clientn");

	if (client->sftp_session != NULL)
		libssh2_session_free(client->session);

	client->session = NULL;

	close(client->sockfd);

	return 0;
}


#ifdef _SFTP_CLIENT_TEST_

int main()
{
	const char* ip = "127.0.0.1";
	const char* port = "8092";
	char user[20] = "root";
	char pswd[50] = "root";
	int ret = 0;

	SftpClient* sftp = OpenSftpClient(ip, port);
	if (sftp == NULL) {
		fprintf(stderr, "OpenSftpClient err ip[%s],port[%s] n", ip, port);
		return -1;
	}

	ret = SftpLogin(sftp, user, pswd);
	ret = SftpDir(sftp, "./data_iftp/");
	ret = SftpGet(sftp, "/home/fis/guoxf/债券收盘收益率曲线报表_20220307.csv", "/data_iftp/债券收盘收益率曲线报表_20220307.csv");
	


	CloseSftpClient(sftp);

	return 0;
}

#elif _FTPS_CLIENT_TEST_
//iconv
#define TO_UTF8 "UTF-8//IGNORE"
#define TO_GB2312 "GB2312//IGNORE"
#define FROM_UTF8 "UTF-8"
#define FROM_GB2312 "GB2312"
#define CMDS_MAX_MSG_GBK_SIZE  16384
#define CMDS_MAX_MSG_UTF8_SIZE  32768


int iconv_gbk_to_utf8(char* inbuf)
{
	iconv_t     cd;
	int         ret;
	size_t      ileft, oleft;
	char* fptr;
	char* tptr;
	int          count;
	char   iconv_tmp_string[CMDS_MAX_MSG_UTF8_SIZE];

	cd = iconv_open(TO_UTF8, FROM_GB2312);
	if (cd == (iconv_t)-1)
	{
		fprintf(stdout, "iconv_open failed[%d]n", errno);
		return 0;
	}

	memset(iconv_tmp_string, 0, CMDS_MAX_MSG_UTF8_SIZE);
	ileft = strlen(inbuf);
	oleft = CMDS_MAX_MSG_UTF8_SIZE;
	tptr = &iconv_tmp_string[0];
	fptr = inbuf;

	if ((ret = iconv(cd, &fptr, &ileft, &tptr, &oleft)) != 0)
	{
		fprintf(stdout, "iconv errno code=%d.n", errno);

		fprintf(stdout, "after iconv tmp_string=%sn", iconv_tmp_string);
		//有时候会出现11的错误码,可忽略掉
		if (errno != 0 && errno != 2 && errno != 11 && errno != 10 && errno != 84)
		{
			fprintf(stdout, "iconv error use original gb2312n");
			iconv_close(cd);
			return 0;
		}
	}

	iconv_close(cd);
	count = strlen(iconv_tmp_string);
	memmove(inbuf, iconv_tmp_string, count);
	inbuf[count] = '';
	return 1;
}

int main()
{
	const char *host = "127.0.0.1:1250";
	const char *user = "root";
	const char *pass = "root";
	int failed =  0;
	size_t size = 0;
	
	char remotepath[20000];
	char remotedir[10000];
	
	bzero(remotepath,sizeof(remotepath));
	bzero(remotedir,sizeof(remotedir));
	
	snprintf(remotepath,sizeof(remotepath),"/基准数据报表/债券收盘估值/债券收盘估值_20220507.csv");
	iconv_gbk_to_utf8(remotepath);
	snprintf(remotedir,sizeof(remotedir),"/基准数据报表/债券收盘估值");
	iconv_gbk_to_utf8(remotedir);
	
	FtpsClient *cli = NULL;
	cli = OpenFtpsClient(host);
	if(cli == NULL)
		return -1;
		
	failed = FtpsLogin(cli,user,pass);	
	if(failed)
		return -1;

		
	failed = FtpsGet(cli,"./test.csv",remotepath);	
	if(failed)
		return -1;	
	failed = FtpsDir(cli,NULL,remotedir);
	if(failed)
		return -1;
	
	FtpsChdir(cli,remotedir);	
	
	
	snprintf(remotepath,sizeof(remotepath),"/基准数据报表/债券收盘估值/债券收盘估值_20220509.csv");
	iconv_gbk_to_utf8(remotepath);		
	failed = FtpsGet(cli,"./test.csv",remotepath);
	if(failed)
		return -1;	
	
	failed = FtpsSize(cli,remotepath, &size);
	if(failed)
		return -1;	
	
	CloseFtpsClient(cli);
	
	return 0;
}




#endif


编译命令:

cc ftpclient.c -lssl -lssh2 -lcrypto -lz -oftpclient -g

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/889532.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号