目录结构:
ftpdemo/include/elapse.h

1 /************************************************* 2 Copyright (C), 2019-2029, Guide Tech. Co., Ltd. 3 File name: elapse.h 4 Author: henry 5 Version: V1.0.0.0 6 Date: 20241008 7 Description:计算函数运行时间 8 *************************************************/ 9 10 #ifndef __ELAPSE_MILLSEC_H__ 11 #define __ELAPSE_MILLSEC_H__ 12 13 //#include <iostream> 14 #include <chrono> 15 #include <iomanip> // 用于设置输出流的格式 16 using namespace std; 17 //计算耗时 18 class ElapseMillsec{ 19 public: 20 21 ElapseMillsec(std::string comment); 22 ElapseMillsec(); 23 ~ElapseMillsec(); 24 25 private: 26 std::string m_comment=""; 27 std::chrono::high_resolution_clock::time_point m_Start; 28 std::chrono::high_resolution_clock::time_point m_End; 29 }; 30 31 #endif
ftpdemo/include/ftplib.h

1 /*************************************************************************** 2 ftplib.h - description 3 ------------------- 4 begin : Son Jul 27 2003 5 copyright : (C) 2013 by magnus kulke 6 email : mkulke@gmail.com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU Lesser General Public License as * 13 * published by the Free Software Foundation; either version 2.1 of the * 14 * License, or (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 /*************************************************************************** 19 * Note: ftplib, on which ftplibpp was originally based upon used to be * 20 * licensed as GPL 2.0 software, as of Jan. 26th 2013 its author Thomas * 21 * Pfau allowed the distribution of ftplib via LGPL. Thus the license of * 22 * ftplibpp changed aswell. * 23 ***************************************************************************/ 24 25 #ifndef FTPLIB_H 26 #define FTPLIB_H 27 28 #if defined(_WIN32) 29 30 #if BUILDING_DLL 31 # define DLLIMPORT __declspec (dllexport) 32 #else /* Not BUILDING_DLL */ 33 # define DLLIMPORT __declspec (dllimport) 34 #endif /* Not BUILDING_DLL */ 35 36 #include <time.h> 37 #endif 38 39 #ifndef _WIN32 40 #include <unistd.h> 41 #include <sys/time.h> 42 #endif 43 44 #ifdef NOLFS 45 #define off64_t long 46 #define fseeko64 fseek 47 #define fopen64 fopen 48 #endif 49 50 #if defined(__APPLE__) 51 #define off64_t __darwin_off_t 52 #define fseeko64 fseeko 53 #define fopen64 fopen 54 #endif 55 56 //SSL 57 typedef struct ssl_st SSL; 58 typedef struct ssl_ctx_st SSL_CTX; 59 typedef struct bio_st BIO; 60 typedef struct x509_st X509; 61 62 #include <sys/types.h> 63 64 #ifndef _FTPLIB_SSL_CLIENT_METHOD_ 65 #define _FTPLIB_SSL_CLIENT_METHOD_ TLSv1_2_client_method 66 #endif 67 68 using namespace std; 69 70 //SSL 71 typedef struct ssl_st SSL; 72 typedef struct ssl_ctx_st SSL_CTX; 73 typedef struct bio_st BIO; 74 typedef struct x509_st X509; 75 76 /** 77 *@author mkulke 78 */ 79 80 typedef int (*FtpCallbackXfer)(off64_t xfered, void *arg); 81 typedef int (*FtpCallbackIdle)(void *arg); 82 typedef void (*FtpCallbackLog)(char *str, void* arg, bool out); 83 //SSL 84 typedef bool (*FtpCallbackCert)(void *arg, X509 *cert); 85 86 87 struct ftphandle { 88 char *cput,*cget; 89 int handle; 90 int cavail,cleft; 91 char *buf; 92 int dir; 93 ftphandle *ctrl; 94 int cmode; 95 struct timeval idletime; 96 FtpCallbackXfer xfercb; 97 FtpCallbackIdle idlecb; 98 FtpCallbackLog logcb; 99 void *cbarg; 100 off64_t xfered; 101 off64_t cbbytes; 102 off64_t xfered1; 103 char response[1024]; 104 //SSL 105 SSL* ssl; 106 SSL_CTX* ctx; 107 BIO* sbio; 108 int tlsctrl; 109 int tlsdata; 110 FtpCallbackCert certcb; 111 112 off64_t offset; 113 bool correctpasv; 114 }; 115 116 #if defined(_WIN32) 117 class DLLIMPORT ftplib { 118 #else 119 class ftplib { 120 #endif 121 public: 122 123 enum accesstype 124 { 125 dir = 1, 126 dirverbose, 127 fileread, 128 filewrite, 129 filereadappend, 130 filewriteappend 131 }; 132 133 enum transfermode 134 { 135 ascii = 'A', 136 image = 'I' 137 }; 138 139 enum connmode 140 { 141 pasv = 1, 142 port 143 }; 144 145 enum fxpmethod 146 { 147 defaultfxp = 0, 148 alternativefxp 149 }; 150 151 enum dataencryption 152 { 153 unencrypted = 0, 154 secure 155 }; 156 157 ftplib(); 158 ~ftplib(); 159 char* LastResponse(); 160 int Connect(const char *host); 161 int Login(const char *user, const char *pass); 162 int Site(const char *cmd); 163 int Raw(const char *cmd); 164 int SysType(char *buf, int max); 165 int Mkdir(const char *path); 166 int Chdir(const char *path); 167 int Cdup(); 168 int Rmdir(const char *path); 169 int Pwd(char *path, int max); 170 int Nlst(const char *outputfile, const char *path); 171 int Dir(const char *outputfile, const char *path); 172 int Size(const char *path, int *size, transfermode mode); 173 int ModDate(const char *path, char *dt, int max); 174 int Get(const char *outputfile, const char *path, transfermode mode, off64_t offset = 0); 175 int Put(const char *inputfile, const char *path, transfermode mode, off64_t offset = 0); 176 int Rename(const char *src, const char *dst); 177 int Delete(const char *path); 178 int Quit(); 179 void SetCallbackIdleFunction(FtpCallbackIdle pointer); 180 void SetCallbackLogFunction(FtpCallbackLog pointer); 181 void SetCallbackXferFunction(FtpCallbackXfer pointer); 182 void SetCallbackArg(void *arg); 183 void SetCallbackBytes(off64_t bytes); 184 void SetCorrectPasv(bool b) { mp_ftphandle->correctpasv = b; }; 185 void SetCallbackIdletime(int time); 186 void SetConnmode(connmode mode); 187 static int Fxp(ftplib* src, ftplib* dst, const char *pathSrc, const char *pathDst, transfermode mode, fxpmethod method); 188 ftphandle* RawOpen(const char *path, accesstype type, transfermode mode); 189 int RawClose(ftphandle* handle); 190 int RawWrite(void* buf, int len, ftphandle* handle); 191 int RawRead(void* buf, int max, ftphandle* handle); 192 // SSL 193 int SetDataEncryption(dataencryption enc); 194 int NegotiateEncryption(); 195 void SetCallbackCertFunction(FtpCallbackCert pointer); 196 197 private: 198 ftphandle* mp_ftphandle; 199 200 int FtpXfer(const char *localfile, const char *path, ftphandle *nControl, accesstype type, transfermode mode); 201 int FtpOpenPasv(ftphandle *nControl, ftphandle **nData, transfermode mode, int dir, char *cmd); 202 int FtpSendCmd(const char *cmd, char expresp, ftphandle *nControl); 203 int FtpAcceptConnection(ftphandle *nData, ftphandle *nControl); 204 int FtpOpenPort(ftphandle *nControl, ftphandle **nData, transfermode mode, int dir, char *cmd); 205 int FtpRead(void *buf, int max, ftphandle *nData); 206 int FtpWrite(void *buf, int len, ftphandle *nData); 207 int FtpAccess(const char *path, accesstype type, transfermode mode, ftphandle *nControl, ftphandle **nData); 208 int FtpClose(ftphandle *nData); 209 int socket_wait(ftphandle *ctl); 210 int readline(char *buf,int max,ftphandle *ctl); 211 int writeline(char *buf, int len, ftphandle *nData); 212 int readresp(char c, ftphandle *nControl); 213 void sprint_rest(char *buf, off64_t offset); 214 void ClearHandle(); 215 int CorrectPasvResponse(unsigned char *v); 216 }; 217 218 #endif
ftpdemo/src/elapse.cpp

#include "elapse.h"ElapseMillsec::ElapseMillsec(std::string comment):m_comment(comment){m_Start = std::chrono::high_resolution_clock::now(); // 获取开始时间 }ElapseMillsec::ElapseMillsec(){m_Start = std::chrono::high_resolution_clock::now(); // 获取开始时间 }ElapseMillsec::~ElapseMillsec(){m_End = std::chrono::high_resolution_clock::now(); // 获取结束时间 // 计算持续时间 std::chrono::duration<double, std::milli> elapsed = m_End - m_Start; // 输出执行时间,以毫秒为单位 printf("%s cost %f milliseconds.\r\n", m_comment.c_str(), elapsed.count());//gdInfo("%s cost %f milliseconds.\r\n", m_comment.c_str(), elapsed.count()); }
ftpdemo/src/ftplib.cpp

// enable > 2gb support (LFS) #ifndef NOLFS #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #endif#ifndef NOSSL #include <openssl/ssl.h> #endif#include "ftplib.h"#ifndef NOSSL #include <openssl/ssl.h> #endif#if defined(_WIN32) #include <windows.h> #include <winsock.h> #else #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #endif#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <ctype.h> #include <sys/types.h>#if defined(_WIN32) #define SETSOCKOPT_OPTVAL_TYPE (const char *) #else #define SETSOCKOPT_OPTVAL_TYPE (void *) #endif#if defined(_WIN32) #define net_read(x,y,z) recv(x,(char*)y,z,0) #define net_write(x,y,z) send(x,(char*)y,z,0) #define net_close closesocket #else #define net_read read #define net_write write #define net_close close #endif#if defined(_WIN32) typedef int socklen_t; #endif#if defined(_WIN32) #define memccpy _memccpy #define strdup _strdup #endifusing namespace std;/* socket values */ //#define SETSOCKOPT_OPTVAL_TYPE (void *) #define FTPLIB_BUFSIZ 1024 #define ACCEPT_TIMEOUT 30/* io types */ #define FTPLIB_CONTROL 0 #define FTPLIB_READ 1 #define FTPLIB_WRITE 2/* win32 dll initializer */#if defined(_WIN32) BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) {switch (reason){case DLL_PROCESS_ATTACH:break;case DLL_PROCESS_DETACH:break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;}/* Returns TRUE on success, FALSE on failure */return TRUE; } #endif/** Constructor*/ftplib::ftplib() {#if defined(_WIN32)WSADATA wsa;if (WSAStartup(MAKEWORD(1, 1), &wsa)){printf("WSAStartup() failed, %lu\n", (unsigned long)GetLastError());}#endif#ifndef NOSSLSSL_library_init();#endif mp_ftphandle = static_cast<ftphandle *>(calloc(1,sizeof(ftphandle)));if (mp_ftphandle == NULL) perror("calloc");mp_ftphandle->buf = static_cast<char *>(malloc(FTPLIB_BUFSIZ));if (mp_ftphandle->buf == NULL){perror("calloc");free(mp_ftphandle);}#ifndef NOSSLmp_ftphandle->ctx = SSL_CTX_new(_FTPLIB_SSL_CLIENT_METHOD_());SSL_CTX_set_verify(mp_ftphandle->ctx, SSL_VERIFY_NONE, NULL);mp_ftphandle->ssl = SSL_new(mp_ftphandle->ctx);#endifClearHandle(); }/** Destructor*/ftplib::~ftplib() {#ifndef NOSSLSSL_free(mp_ftphandle->ssl);SSL_CTX_free(mp_ftphandle->ctx);#endiffree(mp_ftphandle->buf);free(mp_ftphandle); }void ftplib::sprint_rest(char *buf, off64_t offset) { #if defined(__APPLE__)sprintf(buf,"REST %lld",offset); #elsesprintf(buf,"REST %ld",offset); #endif }/** socket_wait - wait for socket to receive or flush data** return 1 if no user callback, otherwise, return value returned by* user callback*/ int ftplib::socket_wait(ftphandle *ctl) {fd_set fd,*rfd = NULL,*wfd = NULL;struct timeval tv;int rv = 0;if (ctl->idlecb == NULL) return 1;/*if ((ctl->dir == FTPLIB_CONTROL)|| (ctl->idlecb == NULL)|| ((ctl->idletime.tv_sec == 0)&& //(ctl->idletime.tv_usec 0))return 1;*/if (ctl->dir == FTPLIB_WRITE) wfd = &fd;else rfd = &fd;FD_ZERO(&fd);do{FD_SET(ctl->handle,&fd);tv = ctl->idletime;rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);if (rv == -1){rv = 0;strncpy(ctl->ctrl->response, strerror(errno), sizeof(ctl->ctrl->response));break;}else if (rv > 0){rv = 1;break;}} while ((rv = ctl->idlecb(ctl->cbarg)));return rv; }/** read a line of text** return -1 on error or bytecount*/ int ftplib::readline(char *buf,int max,ftphandle *ctl) {int x,retval = 0;char *end,*bp=buf;int eof = 0;if ((ctl->dir != FTPLIB_CONTROL) && (ctl->dir != FTPLIB_READ))return -1;if (max == 0)return 0;do{if (ctl->cavail > 0){x = (max >= ctl->cavail) ? ctl->cavail : max-1;end = static_cast<char*>(memccpy(bp,ctl->cget,'\n',x));if (end != NULL)x = end - bp;retval += x;bp += x;*bp = '\0';max -= x;ctl->cget += x;ctl->cavail -= x;if (end != NULL){bp -= 2;if (strcmp(bp,"\r\n") == 0){*bp++ = '\n';*bp++ = '\0';--retval;}break;}}if (max == 1){*buf = '\0';break;}if (ctl->cput == ctl->cget){ctl->cput = ctl->cget = ctl->buf;ctl->cavail = 0;ctl->cleft = FTPLIB_BUFSIZ;}if (eof){if (retval == 0)retval = -1;break;}if (!socket_wait(ctl)) return retval;#ifndef NOSSLif (ctl->tlsdata) x = SSL_read(ctl->ssl, ctl->cput, ctl->cleft);else{if (ctl->tlsctrl) x = SSL_read(ctl->ssl, ctl->cput, ctl->cleft);else x = net_read(ctl->handle,ctl->cput,ctl->cleft);} #elsex = net_read(ctl->handle,ctl->cput,ctl->cleft); #endifif ( x == -1){perror("read");retval = -1;break;}// LOGGING FUNCTIONALITY!!!if ((ctl->dir == FTPLIB_CONTROL) && (mp_ftphandle->logcb != NULL)){*((ctl->cput)+x) = '\0';mp_ftphandle->logcb(ctl->cput, mp_ftphandle->cbarg, true);}if (x == 0) eof = 1;ctl->cleft -= x;ctl->cavail += x;ctl->cput += x;} while (1);return retval; }/** write lines of text** return -1 on error or bytecount*/ int ftplib::writeline(char *buf, int len, ftphandle *nData) {int x, nb=0, w;char *ubp = buf, *nbp;char lc=0;if (nData->dir != FTPLIB_WRITE)return -1;nbp = nData->buf;for (x=0; x < len; x++){if ((*ubp == '\n') && (lc != '\r')){if (nb == FTPLIB_BUFSIZ){if (!socket_wait(nData)) return x; #ifndef NOSSLif (nData->tlsctrl) w = SSL_write(nData->ssl, nbp, FTPLIB_BUFSIZ);else w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); #elsew = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); #endifif (w != FTPLIB_BUFSIZ){printf("write(1) returned %d, errno = %d\n", w, errno);return(-1);}nb = 0;}nbp[nb++] = '\r';}if (nb == FTPLIB_BUFSIZ){if (!socket_wait(nData))return x; #ifndef NOSSLif (nData->tlsctrl) w = SSL_write(nData->ssl, nbp, FTPLIB_BUFSIZ);else w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); #elsew = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); #endif if (w != FTPLIB_BUFSIZ){printf("write(2) returned %d, errno = %d\n", w, errno);return(-1);}nb = 0;}nbp[nb++] = lc = *ubp++;}if (nb){if (!socket_wait(nData)) return x; #ifndef NOSSLif (nData->tlsctrl) w = SSL_write(nData->ssl, nbp, nb);else w = net_write(nData->handle, nbp, nb); #elsew = net_write(nData->handle, nbp, nb); #endifif (w != nb){printf("write(3) returned %d, errno = %d\n", w, errno);return(-1);}}return len; }/** read a response from the server** return 0 if first char doesn't match* return 1 if first char matches*/ int ftplib::readresp(char c, ftphandle *nControl) {char match[5];if (readline(nControl->response,256,nControl) == -1){perror("Control socket read failed");return 0;}if (nControl->response[3] == '-'){strncpy(match,nControl->response,3);match[3] = ' ';match[4] = '\0';do{if (readline(nControl->response,256,nControl) == -1){perror("Control socket read failed");return 0;}} while (strncmp(nControl->response,match,4));}if (nControl->response[0] == c) return 1;return 0; }/** FtpLastResponse - return a pointer to the last response received*/ char* ftplib::LastResponse() {if ((mp_ftphandle) && (mp_ftphandle->dir == FTPLIB_CONTROL)) return mp_ftphandle->response;return NULL; }/** ftplib::Connect - connect to remote server** return 1 if connected, 0 if not*/ int ftplib::Connect(const char *host) {int sControl;struct sockaddr_in sin;struct hostent *phe;struct servent *pse;int on=1;int ret;char *lhost;char *pnum;mp_ftphandle->dir = FTPLIB_CONTROL;mp_ftphandle->ctrl = NULL;mp_ftphandle->xfered = 0;mp_ftphandle->xfered1 = 0; #ifndef NOSSL mp_ftphandle->tlsctrl = 0;mp_ftphandle->tlsdata = 0; #endifmp_ftphandle->offset = 0;mp_ftphandle->handle = 0;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++ = '\0';if (isdigit(*pnum)) sin.sin_port = htons(atoi(pnum));else{pse = getservbyname(pnum,"tcp");sin.sin_port = pse->s_port;}}#if defined(_WIN32)if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) #elseret = inet_aton(lhost, &sin.sin_addr);if (ret == 0) #endif{if ((phe = gethostbyname(lhost)) == NULL){perror("gethostbyname");free(lhost);return 0;}memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);}free(lhost);sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);if (sControl == -1){perror("socket");return 0;}if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1){perror("setsockopt");net_close(sControl);return 0;}if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("connect");net_close(sControl);return 0;}mp_ftphandle->handle = sControl;if (readresp('2', mp_ftphandle) == 0){net_close(sControl);mp_ftphandle->handle = 0;return 0;}return 1; }/** FtpSendCmd - send a command and wait for expected response** return 1 if proper response received, 0 otherwise*/ int ftplib::FtpSendCmd(const char *cmd, char expresp, ftphandle *nControl) {char buf[256];int x;if (!nControl->handle) return 0;if (nControl->dir != FTPLIB_CONTROL) return 0;sprintf(buf,"%s\r\n",cmd);#ifndef NOSSLif (nControl->tlsctrl) x = SSL_write(nControl->ssl,buf,strlen(buf));else x = net_write(nControl->handle,buf,strlen(buf)); #elsex = net_write(nControl->handle,buf,strlen(buf)); #endifif (x <= 0){perror("write");return 0;}if (mp_ftphandle->logcb != NULL) mp_ftphandle->logcb(buf, mp_ftphandle->cbarg, false);return readresp(expresp, nControl); }/** FtpLogin - log in to remote server** return 1 if logged in, 0 otherwise*/ int ftplib::Login(const char *user, const char *pass) {char tempbuf[64];if (((strlen(user) + 7) > sizeof(tempbuf)) || ((strlen(pass) + 7) > sizeof(tempbuf))) return 0;sprintf(tempbuf, "USER %s", user);if (!FtpSendCmd(tempbuf,'3',mp_ftphandle)){if (mp_ftphandle->ctrl != NULL) return 1;if (*LastResponse() == '2') return 1;return 0;}sprintf(tempbuf,"PASS %s",pass);return FtpSendCmd(tempbuf,'2',mp_ftphandle); }/** FtpAcceptConnection - accept connection from server** return 1 if successful, 0 otherwise*/ int ftplib::FtpAcceptConnection(ftphandle *nData, ftphandle *nControl) {int sData;struct sockaddr addr;socklen_t l;int i;struct timeval tv;fd_set mask;int rv = 0;FD_ZERO(&mask);FD_SET(nControl->handle, &mask);FD_SET(nData->handle, &mask);tv.tv_usec = 0;tv.tv_sec = ACCEPT_TIMEOUT;i = nControl->handle;if (i < nData->handle) i = nData->handle;i = select(i+1, &mask, NULL, NULL, &tv);if (i == -1){strncpy(nControl->response, strerror(errno), sizeof(nControl->response));net_close(nData->handle);nData->handle = 0;rv = 0;}else if (i == 0){strcpy(nControl->response, "timed out waiting for connection");net_close(nData->handle);nData->handle = 0;rv = 0;}else{if (FD_ISSET(nData->handle, &mask)){l = sizeof(addr);sData = accept(nData->handle, &addr, &l);i = errno;net_close(nData->handle);if (sData > 0){rv = 1;nData->handle = sData;nData->ctrl = nControl;}else{strncpy(nControl->response, strerror(i), sizeof(nControl->response));nData->handle = 0;rv = 0;}}else if (FD_ISSET(nControl->handle, &mask)){net_close(nData->handle);nData->handle = 0;readresp('2', nControl);rv = 0;}}return rv; }/** FtpAccess - return a handle for a data stream** return 1 if successful, 0 otherwise*/ int ftplib::FtpAccess(const char *path, accesstype type, transfermode mode, ftphandle *nControl, ftphandle **nData) {char buf[256];int dir;printf("FtpAccess msg come in ... \n\n");if ((path == NULL) && ((type == ftplib::filewrite)|| (type == ftplib::fileread)|| (type == ftplib::filereadappend)|| (type == ftplib::filewriteappend))){sprintf(nControl->response,"Missing path argument for file transfer\n");printf("FtpAccess 001 \n\n");return 0;}sprintf(buf, "TYPE %c", mode);if (!FtpSendCmd(buf, '2', nControl)){printf("FtpAccess 002 \n\n");return 0;} switch (type){case ftplib::dir:strcpy(buf,"NLST");dir = FTPLIB_READ;break;case ftplib::dirverbose:strcpy(buf,"LIST -aL");dir = FTPLIB_READ;break;case ftplib::filereadappend:case ftplib::fileread:strcpy(buf,"RETR");dir = FTPLIB_READ;break;case ftplib::filewriteappend:case ftplib::filewrite:strcpy(buf,"STOR");dir = FTPLIB_WRITE;break;default:sprintf(nControl->response, "Invalid open type %d\n", type);printf("FtpAccess 003 \n\n");return 0;}if (path != NULL){int i = strlen(buf);buf[i++] = ' ';if ((strlen(path) + i) >= sizeof(buf)) {printf("FtpAccess 00d \n\n");return 0;}strcpy(&buf[i],path);}if (nControl->cmode == ftplib::pasv){if (FtpOpenPasv(nControl, nData, mode, dir, buf) == -1) {printf("FtpAccess 00c \n\n");return 0;}}if (nControl->cmode == ftplib::port){if (FtpOpenPort(nControl, nData, mode, dir, buf) == -1) {printf("FtpAccess 00b \n\n");return 0;} if (!FtpAcceptConnection(*nData,nControl)){FtpClose(*nData);*nData = NULL;printf("FtpAccess 004 \n\n");return 0;}}printf("FtpAccess 005 \n\n");#ifndef NOSSLprintf("FtpAccess 006 \n\n");if (nControl->tlsdata){(*nData)->ssl = SSL_new(nControl->ctx);(*nData)->sbio = BIO_new_socket((*nData)->handle, BIO_NOCLOSE);SSL_set_bio((*nData)->ssl,(*nData)->sbio,(*nData)->sbio);int ret = SSL_connect((*nData)->ssl);if (ret != 1) {printf("FtpAccess 007 \n\n");return 0;}printf("FtpAccess 008 \n\n");(*nData)->tlsdata = 1;}printf("FtpAccess 009 \n\n"); #endifprintf("FtpAccess 00a \n\n");return 1; }/** FtpOpenPort - Establishes a PORT connection for data transfer** return 1 if successful, -1 otherwise*/ int ftplib::FtpOpenPort(ftphandle *nControl, ftphandle **nData, transfermode mode, int dir, char *cmd) {int sData;union {struct sockaddr sa;struct sockaddr_in in;} sin;struct linger lng = { 0, 0 };socklen_t l;int on=1;ftphandle *ctrl;char buf[256];if (nControl->dir != FTPLIB_CONTROL) return -1;if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE)){sprintf(nControl->response, "Invalid direction %d\n", dir);return -1;}if ((mode != ftplib::ascii) && (mode != ftplib::image)){sprintf(nControl->response, "Invalid mode %c\n", mode);return -1;}l = sizeof(sin);if (getsockname(nControl->handle, &sin.sa, &l) < 0){perror("getsockname");return -1;}sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);if (sData == -1){perror("socket");return -1;}if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1){perror("setsockopt");net_close(sData);return -1;}if (setsockopt(sData,SOL_SOCKET,SO_LINGER, SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1){perror("setsockopt");net_close(sData);return -1;}sin.in.sin_port = 0;if (bind(sData, &sin.sa, sizeof(sin)) == -1){perror("bind");net_close(sData);return -1;}if (listen(sData, 1) < 0){perror("listen");net_close(sData);return -1;}if (getsockname(sData, &sin.sa, &l) < 0) return 0;sprintf(buf, "PORT %hhu,%hhu,%hhu,%hhu,%hhu,%hhu",(unsigned char) sin.sa.sa_data[2],(unsigned char) sin.sa.sa_data[3],(unsigned char) sin.sa.sa_data[4],(unsigned char) sin.sa.sa_data[5],(unsigned char) sin.sa.sa_data[0],(unsigned char) sin.sa.sa_data[1]);if (!FtpSendCmd(buf,'2',nControl)){net_close(sData);return -1;}if (mp_ftphandle->offset != 0){char buf[256];sprint_rest(buf, mp_ftphandle->offset);if (!FtpSendCmd(buf,'3',nControl)){net_close(sData);return 0;}}ctrl = static_cast<ftphandle*>(calloc(1,sizeof(ftphandle)));if (ctrl == NULL){perror("calloc");net_close(sData);return -1;}if ((mode == 'A') && ((ctrl->buf = static_cast<char*>(malloc(FTPLIB_BUFSIZ))) == NULL)){perror("calloc");net_close(sData);free(ctrl);return -1;}if (!FtpSendCmd(cmd, '1', nControl)){FtpClose(*nData);*nData = NULL;return -1;}ctrl->handle = sData;ctrl->dir = dir;ctrl->ctrl = (nControl->cmode == ftplib::pasv) ? nControl : NULL;ctrl->idletime = nControl->idletime;ctrl->cbarg = nControl->cbarg;ctrl->xfered = 0;ctrl->xfered1 = 0;ctrl->cbbytes = nControl->cbbytes;if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec) ctrl->idlecb = nControl->idlecb;else ctrl->idlecb = NULL;if (ctrl->cbbytes ) ctrl->xfercb = nControl->xfercb;else ctrl->xfercb = NULL;*nData = ctrl;return 1; }/** FtpOpenPasv - Establishes a PASV connection for data transfer** return 1 if successful, -1 otherwise*/ int ftplib::FtpOpenPasv(ftphandle *nControl, ftphandle **nData, transfermode mode, int dir, char *cmd) {int sData;union {struct sockaddr sa;struct sockaddr_in in;} sin;struct linger lng = { 0, 0 };unsigned int l;int on=1;ftphandle *ctrl;char *cp;unsigned char v[6];int ret;if (nControl->dir != FTPLIB_CONTROL) return -1;if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE)){sprintf(nControl->response, "Invalid direction %d\n", dir);return -1;}if ((mode != ftplib::ascii) && (mode != ftplib::image)){sprintf(nControl->response, "Invalid mode %c\n", mode);return -1;}l = sizeof(sin);memset(&sin, 0, l);sin.in.sin_family = AF_INET;if (!FtpSendCmd("PASV",'2',nControl)) return -1;cp = strchr(nControl->response,'(');if (cp == NULL) return -1;cp++; #if defined(_WIN32)unsigned int v_i[6];sscanf(cp,"%u,%u,%u,%u,%u,%u",&v_i[2],&v_i[3],&v_i[4],&v_i[5],&v_i[0],&v_i[1]);for (int i = 0; i < 6; i++) v[i] = (unsigned char) v_i[i]; #elsesscanf(cp,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]); #endifif (nControl->correctpasv) if (!CorrectPasvResponse(v)) return -1;sin.sa.sa_data[2] = v[2];sin.sa.sa_data[3] = v[3];sin.sa.sa_data[4] = v[4];sin.sa.sa_data[5] = v[5];sin.sa.sa_data[0] = v[0];sin.sa.sa_data[1] = v[1];if (mp_ftphandle->offset != 0){char buf[256];sprint_rest(buf, mp_ftphandle->offset);if (!FtpSendCmd(buf,'3',nControl)) return 0;}sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);if (sData == -1){perror("socket");return -1;}if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1){perror("setsockopt");net_close(sData);return -1;}if (setsockopt(sData,SOL_SOCKET,SO_LINGER, SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1){perror("setsockopt");net_close(sData);return -1;}if (nControl->dir != FTPLIB_CONTROL) return -1;memcpy(cmd + strlen(cmd), "\r\n\0", 3); #ifndef NOSSLif (nControl->tlsctrl) ret = SSL_write(nControl->ssl,cmd,strlen(cmd));else ret = net_write(nControl->handle,cmd,strlen(cmd)); #elseret = net_write(nControl->handle,cmd,strlen(cmd)); #endifif (ret <= 0){perror("write");return -1;}if (connect(sData, &sin.sa, sizeof(sin.sa)) == -1){perror("connect");net_close(sData);return -1;}if (!readresp('1', nControl)){net_close(sData);return -1;}ctrl = static_cast<ftphandle*>(calloc(1,sizeof(ftphandle)));if (ctrl == NULL){perror("calloc");net_close(sData);return -1;}if ((mode == 'A') && ((ctrl->buf = static_cast<char*>(malloc(FTPLIB_BUFSIZ))) == NULL)){perror("calloc");net_close(sData);free(ctrl);return -1;}ctrl->handle = sData;ctrl->dir = dir;ctrl->ctrl = (nControl->cmode == ftplib::pasv) ? nControl : NULL;ctrl->idletime = nControl->idletime;ctrl->cbarg = nControl->cbarg;ctrl->xfered = 0;ctrl->xfered1 = 0;ctrl->cbbytes = nControl->cbbytes;if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec) ctrl->idlecb = nControl->idlecb;else ctrl->idlecb = NULL;if (ctrl->cbbytes ) ctrl->xfercb = nControl->xfercb;else ctrl->xfercb = NULL;*nData = ctrl;return 1; }/** FtpClose - close a data connection*/ int ftplib::FtpClose(ftphandle *nData) {ftphandle *ctrl;if (nData->dir == FTPLIB_WRITE){if (nData->buf != NULL) writeline(NULL, 0, nData);}else if (nData->dir != FTPLIB_READ) {printf("FtpClose 001 \n\n");return 0;}if (nData->buf) free(nData->buf);shutdown(nData->handle,2);net_close(nData->handle);ctrl = nData->ctrl; #ifndef NOSSLSSL_free(nData->ssl); #endiffree(nData);if (ctrl) {printf("FtpClose 002 \n\n");return readresp('2', ctrl);}printf("FtpClose 003 \n\n");return 1; }/** FtpRead - read from a data connection*/ int ftplib::FtpRead(void *buf, int max, ftphandle *nData) {int i;if (nData->dir != FTPLIB_READ)return 0;if (nData->buf) i = readline(static_cast<char*>(buf), max, nData);else{i = socket_wait(nData);if (i != 1) return 0; #ifndef NOSSLif (nData->tlsdata) i = SSL_read(nData->ssl, buf, max);else i = net_read(nData->handle,buf,max); #elsei = net_read(nData->handle,buf,max); #endif}if (i == -1) return 0;nData->xfered += i;if (nData->xfercb && nData->cbbytes){nData->xfered1 += i;if (nData->xfered1 > nData->cbbytes){if (nData->xfercb(nData->xfered, nData->cbarg) == 0) return 0;nData->xfered1 = 0;}}return i; }/** FtpWrite - write to a data connection*/ int ftplib::FtpWrite(void *buf, int len, ftphandle *nData) {int i;if (nData->dir != FTPLIB_WRITE) return 0;if (nData->buf) i = writeline(static_cast<char*>(buf), len, nData);else{socket_wait(nData); #ifndef NOSSLif (nData->tlsdata) i = SSL_write(nData->ssl, buf, len);else i = net_write(nData->handle, buf, len); #elsei = net_write(nData->handle, buf, len); #endif}if (i == -1) return 0;nData->xfered += i;if (nData->xfercb && nData->cbbytes){nData->xfered1 += i;if (nData->xfered1 > nData->cbbytes){if (nData->xfercb(nData->xfered, nData->cbarg) == 0) return 0;nData->xfered1 = 0;}}return i; }/** FtpSite - send a SITE command** return 1 if command successful, 0 otherwise*/ int ftplib::Site(const char *cmd) {char buf[256];if ((strlen(cmd) + 7) > sizeof(buf)) return 0;sprintf(buf,"SITE %s",cmd);if (!FtpSendCmd(buf,'2',mp_ftphandle)) return 0;return 1; }/** FtpRaw - send a raw string string** return 1 if command successful, 0 otherwise*/int ftplib::Raw(const char *cmd) {char buf[256];strncpy(buf, cmd, 256);if (!FtpSendCmd(buf,'2',mp_ftphandle)) return 0;return 1; }/** FtpSysType - send a SYST command** Fills in the user buffer with the remote system type. If more* information from the response is required, the user can parse* it out of the response buffer returned by FtpLastResponse().** return 1 if command successful, 0 otherwise*/ int ftplib::SysType(char *buf, int max) {int l = max;char *b = buf;char *s;if (!FtpSendCmd("SYST",'2',mp_ftphandle)) return 0;s = &mp_ftphandle->response[4];while ((--l) && (*s != ' ')) *b++ = *s++;*b++ = '\0';return 1; }/** FtpMkdir - create a directory at server** return 1 if successful, 0 otherwise*/ int ftplib::Mkdir(const char *path) {char buf[256];if ((strlen(path) + 6) > sizeof(buf)) return 0;sprintf(buf,"MKD %s",path);if (!FtpSendCmd(buf,'2', mp_ftphandle)) return 0;return 1; }/** FtpChdir - change path at remote** return 1 if successful, 0 otherwise*/ int ftplib::Chdir(const char *path) {char buf[256];if ((strlen(path) + 6) > sizeof(buf)) return 0;sprintf(buf,"CWD %s",path);if (!FtpSendCmd(buf,'2',mp_ftphandle)) return 0;return 1; }/** FtpCDUp - move to parent directory at remote** return 1 if successful, 0 otherwise*/ int ftplib::Cdup() {if (!FtpSendCmd("CDUP",'2',mp_ftphandle)) return 0;return 1; }/** FtpRmdir - remove directory at remote** return 1 if successful, 0 otherwise*/ int ftplib::Rmdir(const char *path) {char buf[256];if ((strlen(path) + 6) > sizeof(buf)) return 0;sprintf(buf,"RMD %s",path);if (!FtpSendCmd(buf,'2',mp_ftphandle)) return 0;return 1; }/** FtpPwd - get working directory at remote** return 1 if successful, 0 otherwise*/ int ftplib::Pwd(char *path, int max) {int l = max;char *b = path;char *s;if (!FtpSendCmd("PWD",'2',mp_ftphandle)) return 0;s = strchr(mp_ftphandle->response, '"');if (s == NULL) return 0;s++;while ((--l) && (*s) && (*s != '"')) *b++ = *s++;*b = '\0';return 1; }/** FtpXfer - issue a command and transfer data** return 1 if successful, 0 otherwise*/ int ftplib::FtpXfer(const char *localfile, const char *path, ftphandle *nControl, accesstype type, transfermode mode) {int l,c;char *dbuf;FILE *local = NULL;ftphandle *nData;printf("FtpXfer msg come in...\r\n");if (localfile != NULL){char ac[3] = " ";if ((type == ftplib::dir) || (type == ftplib::dirverbose)) { ac[0] = 'w'; ac[1] = '\0'; }if (type == ftplib::fileread) { ac[0] = 'w'; ac[1] = '\0'; }if (type == ftplib::filewriteappend) { ac[0] = 'r'; ac[1] = '\0'; }if (type == ftplib::filereadappend) { ac[0] = 'a'; ac[1] = '\0'; }if (type == ftplib::filewrite) { ac[0] = 'r'; ac[1] = '\0'; }if (mode == ftplib::image) ac[1] = 'b';local = fopen64(localfile, ac);printf("FtpXfer localfile:%s\r\n", localfile);if (local == NULL){strncpy(nControl->response, strerror(errno), sizeof(nControl->response));printf("FtpXfer 001, response:%s \n\n", nControl->response);return 0;}if (type == ftplib::filewriteappend) fseeko64(local,mp_ftphandle->offset,SEEK_SET);}if (local == NULL) local = ((type == ftplib::filewrite)|| (type == ftplib::filewriteappend)) ? stdin : stdout;if (!FtpAccess(path, type, mode, nControl, &nData)) {if (localfile != NULL) fclose(local);printf("FtpXfer 002 \n\n");return 0;}dbuf = static_cast<char*>(malloc(FTPLIB_BUFSIZ));if ((type == ftplib::filewrite) || (type == ftplib::filewriteappend)){while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0){if ((c = FtpWrite(dbuf, l, nData)) < l){printf("short write: passed %d, wrote %d\n", l, c);break;}}}else{while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0){if (fwrite(dbuf, 1, l, local) <= 0){perror("localfile write");break;}}}free(dbuf);fflush(local);if (localfile != NULL) fclose(local);printf("FtpXfer 003 \n\n");return FtpClose(nData); }/** FtpNlst - issue an NLST command and write response to output** return 1 if successful, 0 otherwise*/ int ftplib::Nlst(const char *outputfile, const char *path) {mp_ftphandle->offset = 0;return FtpXfer(outputfile, path, mp_ftphandle, ftplib::dir, ftplib::ascii); }/** FtpDir - issue a LIST command and write response to output** return 1 if successful, 0 otherwise*/ int ftplib::Dir(const char *outputfile, const char *path) {mp_ftphandle->offset = 0;return FtpXfer(outputfile, path, mp_ftphandle, ftplib::dirverbose, ftplib::ascii); }/** FtpSize - determine the size of a remote file** return 1 if successful, 0 otherwise*/ int ftplib::Size(const char *path, int *size, transfermode mode) {char cmd[256];int resp,sz,rv=1;if ((strlen(path) + 7) > sizeof(cmd)) return 0;sprintf(cmd, "TYPE %c", mode);if (!FtpSendCmd(cmd, '2', mp_ftphandle)) return 0;sprintf(cmd,"SIZE %s",path);if (!FtpSendCmd(cmd,'2',mp_ftphandle)) rv = 0;else{if (sscanf(mp_ftphandle->response, "%d %d", &resp, &sz) == 2) *size = sz;else rv = 0;}return rv; }/** FtpModDate - determine the modification date of a remote file** return 1 if successful, 0 otherwise*/ int ftplib::ModDate(const char *path, char *dt, int max) {char buf[256];int rv = 1;if ((strlen(path) + 7) > sizeof(buf)) return 0;sprintf(buf,"MDTM %s",path);if (!FtpSendCmd(buf,'2',mp_ftphandle)) rv = 0;else strncpy(dt, &mp_ftphandle->response[4], max);return rv; }/** FtpGet - issue a GET command and write received data to output** return 1 if successful, 0 otherwise*/int ftplib::Get(const char *outputfile, const char *path, transfermode mode, off64_t offset) {mp_ftphandle->offset = offset;if (offset == 0) return FtpXfer(outputfile, path, mp_ftphandle, ftplib::fileread, mode);else return FtpXfer(outputfile, path, mp_ftphandle, ftplib::filereadappend, mode); }/** FtpPut - issue a PUT command and send data from input** return 1 if successful, 0 otherwise*/int ftplib::Put(const char *inputfile, const char *path, transfermode mode, off64_t offset) {mp_ftphandle->offset = offset;if (offset == 0) return FtpXfer(inputfile, path, mp_ftphandle, ftplib::filewrite, mode);else return FtpXfer(inputfile, path, mp_ftphandle, ftplib::filewriteappend, mode); }int ftplib::Rename(const char *src, const char *dst) {char cmd[256];if (((strlen(src) + 7) > sizeof(cmd)) || ((strlen(dst) + 7) > sizeof(cmd))) return 0;sprintf(cmd,"RNFR %s",src);if (!FtpSendCmd(cmd,'3',mp_ftphandle)) return 0;sprintf(cmd,"RNTO %s",dst);if (!FtpSendCmd(cmd,'2',mp_ftphandle)) return 0;return 1; }int ftplib::Delete(const char *path) {char cmd[256];if ((strlen(path) + 7) > sizeof(cmd)) return 0;sprintf(cmd,"DELE %s",path);if (!FtpSendCmd(cmd,'2', mp_ftphandle)) return 0;return 1; }/** FtpQuit - disconnect from remote** return 1 if successful, 0 otherwise*/ int ftplib::Quit() {if (mp_ftphandle->dir != FTPLIB_CONTROL) return 0;if (mp_ftphandle->handle == 0){strcpy(mp_ftphandle->response, "error: no anwser from server\n");return 0;}if (!FtpSendCmd("QUIT",'2',mp_ftphandle)){net_close(mp_ftphandle->handle);return 0;}else{net_close(mp_ftphandle->handle);return 1;} }int ftplib::Fxp(ftplib* src, ftplib* dst, const char *pathSrc, const char *pathDst, transfermode mode, fxpmethod method) {char *cp;unsigned char v[6];char buf[256];int retval = 0;sprintf(buf, "TYPE %c", mode);if (!dst->FtpSendCmd(buf,'2',dst->mp_ftphandle)) return -1;if (!src->FtpSendCmd(buf,'2',src->mp_ftphandle)) return -1;if (method == ftplib::defaultfxp){// PASV dstif (!dst->FtpSendCmd("PASV",'2',dst->mp_ftphandle)) return -1;cp = strchr(dst->mp_ftphandle->response,'(');if (cp == NULL) return -1;cp++; #if defined(_WIN32)unsigned int v_i[6];sscanf(cp,"%u,%u,%u,%u,%u,%u",&v_i[2],&v_i[3],&v_i[4],&v_i[5],&v_i[0],&v_i[1]);for (int i = 0; i < 6; i++) v[i] = (unsigned char) v_i[i]; #elsesscanf(cp,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]); #endifif (dst->mp_ftphandle->correctpasv) if (!dst->CorrectPasvResponse(v)) return -1;// PORT src sprintf(buf, "PORT %d,%d,%d,%d,%d,%d", v[2],v[3],v[4],v[5],v[0],v[1]);if (!src->FtpSendCmd(buf,'2',src->mp_ftphandle)) return -1;// RETR src strcpy(buf,"RETR");if (pathSrc != NULL){int i = strlen(buf);buf[i++] = ' ';if ((strlen(pathSrc) + i) >= sizeof(buf)) return 0;strcpy(&buf[i],pathSrc);}if (!src->FtpSendCmd(buf, '1', src->mp_ftphandle)) return 0;// STOR dst strcpy(buf,"STOR");if (pathDst != NULL){int i = strlen(buf);buf[i++] = ' ';if ((strlen(pathDst) + i) >= sizeof(buf)) return 0;strcpy(&buf[i],pathDst);}if (!dst->FtpSendCmd(buf, '1', dst->mp_ftphandle)){/* this closes the data connection, to abort the RETR onthe source ftp. all hail pftp, it took me severalhours and i was absolutely clueless, playing around withABOR and whatever, when i desperately checked the pftpsource which gave me this final hint. thanks dude(s). */dst->FtpSendCmd("PASV", '2', dst->mp_ftphandle);src->readresp('4', src->mp_ftphandle);return 0;}retval = (src->readresp('2', src->mp_ftphandle)) & (dst->readresp('2', dst->mp_ftphandle));}else {// PASV srcif (!src->FtpSendCmd("PASV",'2',src->mp_ftphandle)) return -1;cp = strchr(src->mp_ftphandle->response,'(');if (cp == NULL) return -1;cp++; #if defined(_WIN32)unsigned int v_i[6];sscanf(cp,"%u,%u,%u,%u,%u,%u",&v_i[2],&v_i[3],&v_i[4],&v_i[5],&v_i[0],&v_i[1]);for (int i = 0; i < 6; i++) v[i] = (unsigned char) v_i[i]; #elsesscanf(cp,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]); #endifif (src->mp_ftphandle->correctpasv) if (!src->CorrectPasvResponse(v)) return -1;// PORT dst sprintf(buf, "PORT %d,%d,%d,%d,%d,%d", v[2],v[3],v[4],v[5],v[0],v[1]);if (!dst->FtpSendCmd(buf,'2',dst->mp_ftphandle)) return -1;// STOR dest strcpy(buf,"STOR");if (pathDst != NULL){int i = strlen(buf);buf[i++] = ' ';if ((strlen(pathDst) + i) >= sizeof(buf)) return 0;strcpy(&buf[i],pathDst);}if (!dst->FtpSendCmd(buf, '1', dst->mp_ftphandle)) return 0;// RETR src strcpy(buf,"RETR");if (pathSrc != NULL){int i = strlen(buf);buf[i++] = ' ';if ((strlen(pathSrc) + i) >= sizeof(buf)) return 0;strcpy(&buf[i],pathSrc);}if (!src->FtpSendCmd(buf, '1', src->mp_ftphandle)){src->FtpSendCmd("PASV", '2', src->mp_ftphandle);dst->readresp('4', dst->mp_ftphandle);return 0;}// wait til its finished! retval = (src->readresp('2', src->mp_ftphandle)) & (dst->readresp('2', dst->mp_ftphandle));}return retval; }int ftplib::SetDataEncryption(dataencryption enc) { #ifdef NOSSL(void)enc;return 0; #elseif (!mp_ftphandle->tlsctrl) return 0;if (!FtpSendCmd("PBSZ 0",'2',mp_ftphandle)) return 0;switch(enc){case ftplib::unencrypted:mp_ftphandle->tlsdata = 0;if (!FtpSendCmd("PROT C",'2',mp_ftphandle)) return 0;break;case ftplib::secure:mp_ftphandle->tlsdata = 1;if (!FtpSendCmd("PROT P",'2',mp_ftphandle)) return 0;break;default:return 0;}return 1; #endif }int ftplib::NegotiateEncryption() { #ifdef NOSSLreturn 0; #elseint ret;if (!FtpSendCmd("AUTH TLS",'2',mp_ftphandle)) return 0;mp_ftphandle->sbio = BIO_new_socket(mp_ftphandle->handle, BIO_NOCLOSE);SSL_set_bio(mp_ftphandle->ssl,mp_ftphandle->sbio,mp_ftphandle->sbio);ret = SSL_connect(mp_ftphandle->ssl);if (ret == 1) mp_ftphandle->tlsctrl = 1;if (mp_ftphandle->certcb != NULL){X509 *cert = SSL_get_peer_certificate(mp_ftphandle->ssl);if (!mp_ftphandle->certcb(mp_ftphandle->cbarg, cert)) return 0;}if (ret < 1) return 0;return 1; #endif }void ftplib::SetCallbackCertFunction(FtpCallbackCert pointer) { #ifdef NOSSL(void)pointer; #elsemp_ftphandle->certcb = pointer; #endif }void ftplib::SetCallbackIdleFunction(FtpCallbackIdle pointer) {mp_ftphandle->idlecb = pointer; }void ftplib::SetCallbackXferFunction(FtpCallbackXfer pointer) {mp_ftphandle->xfercb = pointer; }void ftplib::SetCallbackLogFunction(FtpCallbackLog pointer) {mp_ftphandle->logcb = pointer; }void ftplib::SetCallbackArg(void *arg) {mp_ftphandle->cbarg = arg; }void ftplib::SetCallbackBytes(off64_t bytes) {mp_ftphandle->cbbytes = bytes; }void ftplib::SetCallbackIdletime(int time) {mp_ftphandle->idletime.tv_sec = time / 1000;mp_ftphandle->idletime.tv_usec = (time % 1000) * 1000; }void ftplib::SetConnmode(connmode mode) {mp_ftphandle->cmode = mode; }void ftplib::ClearHandle() {mp_ftphandle->dir = FTPLIB_CONTROL;mp_ftphandle->ctrl = NULL;mp_ftphandle->cmode = ftplib::pasv;mp_ftphandle->idlecb = NULL;mp_ftphandle->idletime.tv_sec = mp_ftphandle->idletime.tv_usec = 0;mp_ftphandle->cbarg = NULL;mp_ftphandle->xfered = 0;mp_ftphandle->xfered1 = 0;mp_ftphandle->cbbytes = 0; #ifndef NOSSL mp_ftphandle->tlsctrl = 0;mp_ftphandle->tlsdata = 0;mp_ftphandle->certcb = NULL; #endifmp_ftphandle->offset = 0;mp_ftphandle->handle = 0;mp_ftphandle->logcb = NULL;mp_ftphandle->xfercb = NULL;mp_ftphandle->correctpasv = false; }int ftplib::CorrectPasvResponse(unsigned char *v) {struct sockaddr ipholder;socklen_t ipholder_size = sizeof(ipholder);if (getpeername(mp_ftphandle->handle, &ipholder, &ipholder_size) == -1){perror("getpeername");net_close(mp_ftphandle->handle);return 0;}for (int i = 2; i < 6; i++) v[i] = ipholder.sa_data[i];return 1; }ftphandle* ftplib::RawOpen(const char *path, accesstype type, transfermode mode) {int ret;ftphandle* datahandle;ret = FtpAccess(path, type, mode, mp_ftphandle, &datahandle); if (ret) return datahandle;else return NULL; }int ftplib::RawClose(ftphandle* handle) {return FtpClose(handle); } int ftplib::RawWrite(void* buf, int len, ftphandle* handle) {return FtpWrite(buf, len, handle); }int ftplib::RawRead(void* buf, int max, ftphandle* handle) {return FtpRead(buf, max, handle); }
ftpdemo/src/ftptest.cpp

#include <iostream> #include <vector> #include <string> #include "elapse.h" #include <chrono> #include <thread> #include "ftplib.h" #include "Poco/Path.h"// 文件大小 145MB,ftp传输耗时: 23s static const std::string FTP_MEDIA_FILE1 = "/mnt/windows_share/media/VL_Alarm_20241107_092111063.mp4"; static const std::string FTP_MEDIA_FILE2 = "/mnt/windows_share/media/IR_Alarm_20241107_092111062.mp4"; static const std::string FTP_MEDIA_FILE3 = "/mnt/windows_share/media/VL_Alarm_20241107_09211162.jpg"; static const std::string FTP_MEDIA_FILE4 = "/mnt/windows_share/media/IR_Alarm_20241107_09211162.jpg"; static const std::string FTP_HOST_PORT = "192.168.23.22:21"; static const std::string FTP_USER_NAME = "henry"; static const std::string FTP_PASSWORD = "henry"; static const std::string FTP_FILE_PATH = "/test";void test1(std::string fileName){std::cout<<"==================================== test1 ===================================="<<std::endl;ElapseMillsec elapse("test1");ftplib m_ftp;if(0 == m_ftp.Connect(FTP_HOST_PORT.c_str())){std::cout<<"ftp connect error. FTP_HOST_PORT:" << FTP_HOST_PORT <<std::endl;}else{std::cout<<" ftp connect success."<<std::endl;}if(0 == m_ftp.Login(FTP_USER_NAME.c_str(), FTP_PASSWORD.c_str())){std::cout<<"ftp login error. FTP_USER_NAME:" << FTP_USER_NAME << " FTP_PASSWORD:" << FTP_PASSWORD <<std::endl;}else{std::cout<<" ftp login success."<<std::endl;}// m_ftp->Mkdir(tmpStr.data())) m_ftp.Chdir(FTP_FILE_PATH.c_str());Poco::Path pocoFile(fileName.c_str());if(m_ftp.Put(fileName.c_str(), pocoFile.getFileName().data(), ftplib::image, 0) == 0){std::cout<<"ftp put file error. fileName:" << fileName <<std::endl;}else{std::cout<<" ftp put file success."<<std::endl;}if(0 == m_ftp.Quit()){std::cout<<"ftp quit error."<<std::endl;}else{std::cout<<" ftp quit success."<<std::endl;}std::cout<<std::endl; }int main() {test1(FTP_MEDIA_FILE1);test1(FTP_MEDIA_FILE2);test1(FTP_MEDIA_FILE3);test1(FTP_MEDIA_FILE4);std::cout<<std::endl<<"==================================== end ===================================="<<std::endl;return 0; }
ftpdemo/CMakeLists.txt

1 project(ftptest) 2 3 message("----------cmake ${PROJECT_NAME}----------start") 4 5 # 设置构建类型为Release 6 # set(CMAKE_BUILD_TYPE Release) 7 8 set(CMAKE_VERBOSE_MAKEFILE ON) 9 #set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O0 -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations ") 10 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -Wreturn-type -fdata-sections -ffunction-sections -fstack-protector-strong -fPIC") 11 ## -Wno-unused-variable 12 13 include_directories(/usr/include) 14 include_directories(/usr/local/include) 15 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 16 17 link_directories(/usr/local/lib/) 18 link_directories(/usr/lib) 19 link_directories(/usr/lib32) 20 link_directories(/usr/lib64) 21 link_directories(/usr/local/lib64) 22 23 #输出目录重定向 24 SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 25 SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) 26 27 # 添加需要链接的库 28 set(OPENSSLLIB 29 ssl 30 crypto 31 ) 32 33 set(POCOLIB 34 PocoNet 35 PocoNetSSL 36 PocoCrypto 37 PocoUtil 38 PocoJSON 39 PocoXML 40 PocoFoundation 41 ) 42 43 set(LIBS 44 ${OPENSSLLIB} 45 ${POCOLIB} 46 pthread 47 ) 48 49 50 # 添加源文件 51 aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SOURCES) 52 53 # 添加可执行文件 54 add_executable(${PROJECT_NAME} ${SOURCES}) 55 56 target_link_libraries(${PROJECT_NAME} ${LIBS}) 57 message("----------cmake ${PROJECT_NAME}----------end")
1.需要安装 openssl库
2.需要安装 Poco 库;
ftp 核心代码
void test1(std::string fileName){std::cout<<"==================================== test1 ===================================="<<std::endl;ElapseMillsec elapse("test1");ftplib m_ftp;if(0 == m_ftp.Connect(FTP_HOST_PORT.c_str())){std::cout<<"ftp connect error. FTP_HOST_PORT:" << FTP_HOST_PORT <<std::endl;}else{std::cout<<" ftp connect success."<<std::endl;}if(0 == m_ftp.Login(FTP_USER_NAME.c_str(), FTP_PASSWORD.c_str())){std::cout<<"ftp login error. FTP_USER_NAME:" << FTP_USER_NAME << " FTP_PASSWORD:" << FTP_PASSWORD <<std::endl;}else{std::cout<<" ftp login success."<<std::endl;}// m_ftp->Mkdir(tmpStr.data())) m_ftp.Chdir(FTP_FILE_PATH.c_str());Poco::Path pocoFile(fileName.c_str());if(m_ftp.Put(fileName.c_str(), pocoFile.getFileName().data(), ftplib::image, 0) == 0){std::cout<<"ftp put file error. fileName:" << fileName <<std::endl;}else{std::cout<<" ftp put file success."<<std::endl;}if(0 == m_ftp.Quit()){std::cout<<"ftp quit error."<<std::endl;}else{std::cout<<" ftp quit success."<<std::endl;}std::cout<<std::endl; }