// // main.cpp // FTP // // Created by Saxon Nicholls on 4/7/19. // Copyright © 2019 Saxon Nicholls. All rights reserved. // #include #include // https://curl.haxx.se/libcurl/c/ftpget.html class FTP { public: struct FtpFile { const char *filename; FILE *stream; }; CURL *curl{nullptr}; CURLcode res; std::string url; // ftp location that we are downloading from std::string file_name; public: FTP( const std::string& myurl="ftp://:@hosted.datascope.reuters.com/reports/ASXPriceHistory20190703.csv", const std::string& myfile_name="/Development/FTP/FTP/ASXPriceHistory20190703.csv") : url{ myurl }, file_name{ myfile_name } {}; virtual ~FTP() {}; virtual void Instantiate() { if ( url.empty() || file_name.empty() ) return; struct FtpFile ftpfile = { file_name.c_str(), /* name to store the file as if successful */ NULL }; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { /* * You better replace the URL with one that works! */ curl_easy_setopt(curl, CURLOPT_URL, url.c_str() ); /* Define our callback to get called when there's data to be written */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); /* Switch on full protocol/debug output */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if(CURLE_OK != res) { /* we failed */ fprintf(stderr, "curl told us %d\n", res); } } if(ftpfile.stream) fclose(ftpfile.stream); /* close the local file */ curl_global_cleanup(); }; static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { struct FtpFile *out = (struct FtpFile *)stream; if(!out->stream) { /* open file for writing */ out->stream = fopen(out->filename, "wb"); if(!out->stream) return -1; /* failure, can't open file to write */ } return fwrite(buffer, size, nmemb, out->stream); } }; int main(int argc, const char * argv[]) { FTP ftp; ftp.Instantiate(); return 0; } * Trying 192.165.219.225... * TCP_NODELAY set * Connected to hosted.datascope.reuters.com (192.165.219.225) port 21 (#0) < 220 ProFTPD 1.3.3g Server ready. > USER < 331 Password required for > PASS < 230 User logged in > PWD < 257 "/" is the current directory * Entry path is '/' > CWD reports * ftp_perform ends with SECONDARY: 0 < 250 CWD command successful > EPSV * Connect data stream passively < 229 Entering Extended Passive Mode (|||49128|) * Trying 192.165.219.225... * TCP_NODELAY set * Connecting to 192.165.219.225 (192.165.219.225) port 49128 * Connection failed * connect to 192.165.219.225 port 21 failed: Operation timed out * Failed to connect to hosted.datascope.reuters.com port 21: Operation timed out * Failed EPSV attempt. Disabling EPSV > PASV < 227 Entering Passive Mode (192,165,219,225,210,106) * Trying 192.165.219.225... * TCP_NODELAY set * Connecting to 192.165.219.225 (192.165.219.225) port 53866 * Connected to hosted.datascope.reuters.com (192.165.219.225) port 21 (#0) > TYPE I < 200 Type set to I > SIZE ASXPriceHistory20190703.csv < 213 5473307 > RETR ASXPriceHistory20190703.csv < 150 Opening BINARY mode data connection for ASXPriceHistory20190703.csv (5473307 bytes) * Maxdownload = -1 * Getting file with size: 5473307 * Remembering we are in dir "reports/" < 226 Transfer complete * Connection #0 to host hosted.datascope.reuters.com left intact