/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
-#include "scoped_temporary.h"
+
#include "compose.hpp"
-#include "exceptions.h"
#include "cross.h"
+#include "exceptions.h"
+#include "scoped_temporary.h"
#include "util.h"
#include <curl/curl.h>
#include <zip.h>
-#include <boost/function.hpp>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "i18n.h"
-using std::string;
+
+using std::function;
using std::list;
-using boost::optional;
-using boost::function;
+using std::string;
using boost::algorithm::trim;
+using boost::optional;
+
+
+static size_t
+ls_url_data (void* buffer, size_t size, size_t nmemb, void* output)
+{
+ string* s = reinterpret_cast<string*>(output);
+ char* c = reinterpret_cast<char*>(buffer);
+ for (size_t i = 0; i < (size * nmemb); ++i) {
+ *s += c[i];
+ }
+ return nmemb;
+}
+
+
+list<string>
+ls_url (string url)
+{
+ auto curl = curl_easy_init ();
+ curl_easy_setopt (curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt (curl, CURLOPT_DIRLISTONLY, 1);
+
+ string ls;
+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ls_url_data);
+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &ls);
+ auto const cr = curl_easy_perform (curl);
+
+ if (cr != CURLE_OK) {
+ return {};
+ }
+
+ list<string> result;
+ result.push_back("");
+ for (size_t i = 0; i < ls.size(); ++i) {
+ if (ls[i] == '\n') {
+ result.push_back("");
+ } else {
+ result.back() += ls[i];
+ }
+ }
+
+ result.pop_back ();
+ return result;
+}
static size_t
get_from_url_data (void* buffer, size_t size, size_t nmemb, void* stream)
{
- FILE* f = reinterpret_cast<FILE*> (stream);
+ auto f = reinterpret_cast<FILE*> (stream);
return fwrite (buffer, size, nmemb, f);
}
+
optional<string>
-get_from_url (string url, bool pasv, ScopedTemporary& temp)
+get_from_url (string url, bool pasv, bool skip_pasv_ip, ScopedTemporary& temp)
{
- CURL* curl = curl_easy_init ();
+ auto curl = curl_easy_init ();
curl_easy_setopt (curl, CURLOPT_URL, url.c_str());
- FILE* f = temp.open ("wb");
+ auto f = temp.open ("wb");
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, get_from_url_data);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, f);
curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, 0);
curl_easy_setopt (curl, CURLOPT_FTP_USE_EPRT, 0);
+ if (skip_pasv_ip) {
+ curl_easy_setopt (curl, CURLOPT_FTP_SKIP_PASV_IP, 1);
+ }
if (!pasv) {
curl_easy_setopt (curl, CURLOPT_FTPPORT, "-");
}
/* Maximum time is 20s */
curl_easy_setopt (curl, CURLOPT_TIMEOUT, 20);
- CURLcode const cr = curl_easy_perform (curl);
+ auto const cr = curl_easy_perform (curl);
temp.close ();
curl_easy_cleanup (curl);
return String::compose (_("Download failed (%1 error %2)"), url, (int) cr);
}
- return optional<string>();
+ return {};
}
+
optional<string>
-get_from_url (string url, bool pasv, function<void (boost::filesystem::path)> load)
+get_from_url (string url, bool pasv, bool skip_pasv_ip, function<optional<string> (boost::filesystem::path, string)> load)
{
ScopedTemporary temp;
- optional<string> e = get_from_url (url, pasv, temp);
+ auto e = get_from_url (url, pasv, skip_pasv_ip, temp);
if (e) {
return e;
}
- load (temp.file());
- return optional<string>();
+ return load (temp.file(), url);
}
+
/** @param url URL of ZIP file.
* @param file Filename within ZIP file.
* @param load Function passed a (temporary) filesystem path of the unpacked file.
*/
optional<string>
-get_from_zip_url (string url, string file, bool pasv, function<void (boost::filesystem::path)> load)
+get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, function<optional<string> (boost::filesystem::path, string)> load)
{
/* Download the ZIP file to temp_zip */
ScopedTemporary temp_zip;
- optional<string> e = get_from_url (url, pasv, temp_zip);
+ auto e = get_from_url (url, pasv, skip_pasv_ip, temp_zip);
if (e) {
return e;
}
Centos 6, Centos 7, Debian 7 and Debian 8.
*/
- FILE* zip_file = fopen_boost (temp_zip.file (), "rb");
+ auto zip_file = fopen_boost (temp_zip.file (), "rb");
if (!zip_file) {
return optional<string> (_("Could not open downloaded ZIP file"));
}
- zip_source_t* zip_source = zip_source_filep_create (zip_file, 0, -1, 0);
+ auto zip_source = zip_source_filep_create (zip_file, 0, -1, 0);
if (!zip_source) {
return optional<string> (_("Could not open downloaded ZIP file"));
}
zip_error_t error;
zip_error_init (&error);
- zip_t* zip = zip_open_from_source (zip_source, ZIP_RDONLY, &error);
+ auto zip = zip_open_from_source (zip_source, ZIP_RDONLY, &error);
if (!zip) {
return String::compose (_("Could not open downloaded ZIP file (%1:%2: %3)"), error.zip_err, error.sys_err, error.str ? error.str : "");
}
}
ScopedTemporary temp_cert;
- FILE* f = temp_cert.open ("wb");
+ auto f = temp_cert.open ("wb");
char buffer[4096];
while (true) {
int const N = zip_fread (file_in_zip, buffer, sizeof (buffer));
zip_close (zip);
temp_cert.close ();
- load (temp_cert.file ());
- return optional<string> ();
+ return load (temp_cert.file(), url);
}