26 #if defined (HAVE_CONFIG_H)
43 #if defined (HAVE_CURL)
44 # include <curl/curl.h>
45 # include <curl/curlver.h>
46 # include <curl/easy.h>
52 : m_host_or_url (), m_valid (false), m_ftp (false),
53 m_ascii_mode (false), m_ok (true), m_errmsg (),
54 m_curr_istream (&std::cin), m_curr_ostream (&std::cout)
61 : m_host_or_url (host), m_valid (false), m_ftp (true),
62 m_ascii_mode (false), m_ok (true), m_errmsg (),
63 m_curr_istream (&std::cin), m_curr_ostream (&os)
68 : m_host_or_url (url), m_valid (false), m_ftp (false),
69 m_ascii_mode (false), m_ok (true), m_errmsg (),
70 m_curr_istream (&std::cin), m_curr_ostream (&os)
75 const std::string& target)
82 int status =
sys::mkdir (directory, 0777, msg);
87 m_errmsg =
"__ftp_mget__: can not create directory '"
88 + target + sep + directory +
"': " + msg;
113 std::string realfile = target + directory + sep + sv(i);
117 std::ios::out | std::ios::binary);
119 if (! ofile.is_open ())
122 m_errmsg =
"__ftp_mget__: unable to open file";
125 int(*unlink_fptr)(
const std::string&) =
sys::unlink;
144 const std::string& directory)
169 std::string file = files (i);
171 if (file ==
"." || file ==
"..")
180 m_errmsg =
"__ftp__mput: file '" + realfile
181 +
"' does not exist";
197 std::ios::in | std::ios::binary);
199 if (! ifile.is_open ())
202 m_errmsg =
"__ftp_mput__: unable to open file '"
214 file_list.
append (realfile);
220 m_errmsg =
"__ftp_mput__: can not read the directory '"
228 #if defined (HAVE_CURL)
231 write_data (
void *buffer, std::size_t size, std::size_t nmemb,
void *streamp)
233 std::ostream&
stream = *(
static_cast<std::ostream *
> (streamp));
234 stream.
write (
static_cast<const char *
> (buffer), size*nmemb);
235 return (
stream.fail () ? 0 : size * nmemb);
239 read_data (
void *buffer, std::size_t size, std::size_t nmemb,
void *streamp)
241 std::istream&
stream = *(
static_cast<std::istream *
> (streamp));
242 stream.
read (
static_cast<char *
> (buffer), size*nmemb);
246 return (
stream.fail () ? 0 : size * nmemb);
250 throw_away (
void *, std::size_t size, std::size_t nmemb,
void *)
252 return static_cast<std::size_t
> (size * nmemb);
258 #define SETOPT(option, parameter) \
261 CURLcode res = curl_easy_setopt (m_curl, option, parameter); \
262 if (res != CURLE_OK) \
265 m_errmsg = curl_easy_strerror (res); \
272 #define SETOPTR(option, parameter) \
275 CURLcode res = curl_easy_setopt (m_curl, option, parameter); \
276 if (res != CURLE_OK) \
279 m_errmsg = curl_easy_strerror (res); \
296 m_errmsg =
"can not create curl object";
299 curl_transfer (
const std::string& host,
const std::string& user_arg,
300 const std::string& passwd, std::ostream& os)
302 m_curl (curl_easy_init ()), m_errnum (), m_url (), m_userpwd ()
308 m_errmsg =
"can not create curl object";
312 init (user_arg, passwd, std::cin, os);
314 m_url =
"ftp://" + host;
315 SETOPT (CURLOPT_URL, m_url.c_str ());
321 curl_transfer (
const std::string& url_str, std::ostream& os)
323 m_errnum (), m_url (), m_userpwd ()
329 m_errmsg =
"can not create curl object";
333 init (
"",
"", std::cin, os);
335 std::string cainfo = sys::env::getenv (
"CURLOPT_CAINFO");
336 if (! cainfo.empty ())
337 SETOPT (CURLOPT_CAINFO, cainfo.c_str ());
339 std::string capath = sys::env::getenv (
"CURLOPT_CAPATH");
340 if (! capath.empty ())
341 SETOPT (CURLOPT_CAPATH, capath.c_str ());
343 SETOPT (CURLOPT_NOBODY, 0);
349 SETOPT (CURLOPT_HTTPGET, 1);
352 OCTAVE_DISABLE_COPY_MOVE (curl_transfer)
357 curl_easy_cleanup (m_curl);
362 m_errnum = curl_easy_perform (m_curl);
364 if (m_errnum != CURLE_OK)
367 m_errmsg = curl_easy_strerror (m_errnum);
373 return std::string (curl_easy_strerror (m_errnum));
379 m_curr_ostream = &os;
380 SETOPTR (CURLOPT_WRITEDATA,
static_cast<void *
> (m_curr_ostream));
387 m_curr_istream = &is;
388 SETOPTR (CURLOPT_READDATA,
static_cast<void *
> (m_curr_istream));
395 SETOPT (CURLOPT_TRANSFERTEXT, 1);
400 m_ascii_mode =
false;
401 SETOPT (CURLOPT_TRANSFERTEXT, 0);
404 void cwd (
const std::string& path)
406 ftp_file_or_dir_action (path,
"cwd");
409 void del (
const std::string& file)
411 ftp_file_or_dir_action (file,
"dele");
414 void rmdir (
const std::string& path)
416 ftp_file_or_dir_action (path,
"rmd");
419 void mkdir (
const std::string& path)
421 ftp_file_or_dir_action (path,
"mkd");
424 void rename (
const std::string& oldname,
const std::string& newname)
426 struct curl_slist *slist =
nullptr;
428 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
430 std::string cmd =
"rnfr " + oldname;
431 slist = curl_slist_append (slist, cmd.c_str ());
432 cmd =
"rnto " + newname;
433 slist = curl_slist_append (slist, cmd.c_str ());
434 SETOPT (CURLOPT_POSTQUOTE, slist);
440 SETOPT (CURLOPT_POSTQUOTE, 0);
443 void put (
const std::string& file, std::istream& is)
445 m_url =
"ftp://" + m_host_or_url +
'/' + file;
446 SETOPT (CURLOPT_URL, m_url.c_str ());
447 SETOPT (CURLOPT_UPLOAD, 1);
448 SETOPT (CURLOPT_NOBODY, 0);
456 SETOPT (CURLOPT_NOBODY, 1);
457 SETOPT (CURLOPT_UPLOAD, 0);
459 SETOPT (CURLOPT_URL, m_url.c_str ());
462 void get (
const std::string& file, std::ostream& os)
464 m_url =
"ftp://" + m_host_or_url +
'/' + file;
465 SETOPT (CURLOPT_URL, m_url.c_str ());
466 SETOPT (CURLOPT_NOBODY, 0);
474 SETOPT (CURLOPT_NOBODY, 1);
476 SETOPT (CURLOPT_URL, m_url.c_str ());
481 m_url =
"ftp://" + m_host_or_url +
'/';
482 SETOPT (CURLOPT_URL, m_url.c_str ());
483 SETOPT (CURLOPT_NOBODY, 0);
489 SETOPT (CURLOPT_NOBODY, 1);
491 SETOPT (CURLOPT_URL, m_url.c_str ());
498 std::ostringstream buf;
499 m_url =
"ftp://" + m_host_or_url +
'/';
500 SETOPTR (CURLOPT_WRITEDATA,
static_cast<void *
> (&buf));
501 SETOPTR (CURLOPT_URL, m_url.c_str ());
502 SETOPTR (CURLOPT_DIRLISTONLY, 1);
511 SETOPTR (CURLOPT_WRITEDATA,
static_cast<void *
> (m_curr_ostream));
512 SETOPTR (CURLOPT_DIRLISTONLY, 0);
513 SETOPTR (CURLOPT_URL, m_url.c_str ());
516 std::string str = buf.str ();
521 pos = str.find_first_of (
'\n', pos);
522 if (pos == std::string::npos)
531 std::size_t newpos = str.find_first_of (
'\n', pos);
532 if (newpos == std::string::npos)
535 std::string name = str.substr (pos, newpos - pos);
537 if (name.length () > 0 && name.back () ==
'\r')
547 void get_fileinfo (
const std::string& filename,
double& filesize,
548 OCTAVE_TIME_T& filetime,
bool& fileisdir)
550 std::string path =
pwd ();
552 m_url =
"ftp://" + m_host_or_url +
'/' + path +
'/' + filename;
553 SETOPT (CURLOPT_URL, m_url.c_str ());
554 SETOPT (CURLOPT_FILETIME, 1);
555 SETOPT (CURLOPT_HEADERFUNCTION, throw_away);
556 SETOPT (CURLOPT_WRITEFUNCTION, throw_away);
575 curl_easy_getinfo (m_curl, CURLINFO_FILETIME, &ft);
578 curl_easy_getinfo (m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &fs);
581 SETOPT (CURLOPT_WRITEFUNCTION, write_data);
582 SETOPT (CURLOPT_HEADERFUNCTION, 0);
583 SETOPT (CURLOPT_FILETIME, 0);
585 SETOPT (CURLOPT_URL, m_url.c_str ());
598 struct curl_slist *slist =
nullptr;
600 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
602 slist = curl_slist_append (slist,
"pwd");
603 SETOPTR (CURLOPT_POSTQUOTE, slist);
604 SETOPTR (CURLOPT_HEADERFUNCTION, write_data);
606 std::ostringstream buf;
607 SETOPTR (CURLOPT_WRITEHEADER,
static_cast<void *
> (&buf));
616 std::size_t pos2 = retval.rfind (
'"');
617 std::size_t pos1 = retval.rfind (
'"', pos2 - 1);
618 retval = retval.substr (pos1 + 1, pos2 - pos1 - 1);
620 SETOPTR (CURLOPT_HEADERFUNCTION, 0);
621 SETOPTR (CURLOPT_WRITEHEADER, 0);
622 SETOPTR (CURLOPT_POSTQUOTE, 0);
641 std::string query_string;
643 query_string = form_query_string (param);
645 if (action.empty () || action ==
"get")
647 if (! query_string.empty ())
648 m_url +=
'?' + query_string;
650 SETOPT (CURLOPT_URL, m_url.c_str ());
652 else if (action ==
"post" || action ==
"put" || action ==
"delete")
654 SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ());
658 SETOPT (CURLOPT_CUSTOMREQUEST,
"PUT");
661 if (action ==
"delete")
663 SETOPT (CURLOPT_CUSTOMREQUEST,
"DELETE");
666 SETOPT (CURLOPT_URL, m_url.c_str ());
671 m_errmsg =
"curl_transfer: unknown http action";
680 SETOPT (CURLOPT_COOKIEJAR, filename.c_str ());
682 SETOPT (CURLOPT_COOKIEFILE, filename.c_str ());
689 struct curl_slist *slist =
nullptr;
691 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
693 if (param.
numel () >= 2)
695 for (
int i = 0; i < param.
numel (); i += 2)
697 std::string header = param(i) +
": " + param(i+1);
699 slist = curl_slist_append (slist, header.c_str ());
702 SETOPT (CURLOPT_HTTPHEADER, slist);
713 curl_mime *mime =
nullptr;
714 curl_mimepart *part =
nullptr;
716 SETOPT (CURLOPT_URL, m_host_or_url.c_str ());
718 unwind_action cleanup_mime ([=] () { curl_mime_free (mime); });
720 if (param.
numel () >= 2)
722 for (
int i = 0; i < param.
numel (); i += 2)
724 std::string name = param(i);
725 std::string data = param(i+1);
727 part = curl_mime_addpart (mime);
728 curl_mime_name (part, name.c_str ());
730 curl_mime_filedata (part, data.c_str ());
732 curl_mime_data (part, data.c_str (), CURL_ZERO_TERMINATED);
735 SETOPT (CURLOPT_MIMEPOST, mime);
745 std::string temp =
"";
760 SETOPT (CURLOPT_USERPWD, tmp.c_str ());
764 std::string tmp = options.
Username +
":";
765 SETOPT (CURLOPT_USERPWD, tmp.c_str ());
804 std::string m_userpwd;
806 void init (
const std::string& user,
const std::string& passwd,
807 std::istream& is, std::ostream& os)
810 SETOPT (CURLOPT_NOBODY, 1);
814 if (! passwd.empty ())
815 m_userpwd +=
':' + passwd;
816 if (! m_userpwd.empty ())
817 SETOPT (CURLOPT_USERPWD, m_userpwd.c_str ());
820 SETOPT (CURLOPT_WRITEFUNCTION, write_data);
823 SETOPT (CURLOPT_WRITEDATA,
static_cast<void *
> (&os));
826 SETOPT (CURLOPT_READFUNCTION, read_data);
829 SETOPT (CURLOPT_READDATA,
static_cast<void *
> (&is));
832 SETOPT (CURLOPT_FOLLOWLOCATION,
true);
837 SETOPT (CURLOPT_FTP_USE_EPSV,
false);
841 curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
842 const char *lib_ver = data->version;
843 std::string user_agent
846 +
" (https://www.gnu.org/software/octave/ ; help@octave.org) libcurl/"
847 + std::string (lib_ver));
849 SETOPT (CURLOPT_USERAGENT, user_agent.c_str ());
851 SETOPT (CURLOPT_NOPROGRESS,
true);
852 SETOPT (CURLOPT_FAILONERROR,
true);
854 SETOPT (CURLOPT_POSTQUOTE, 0);
855 SETOPT (CURLOPT_QUOTE, 0);
860 std::ostringstream query;
862 if (param.
numel () >= 2)
863 for (
int i = 0; i < param.
numel (); i += 2)
865 std::string name = param(i);
866 std::string
text = param(i+1);
869 char *enc_name = curl_easy_escape (m_curl, name.c_str (),
871 char *enc_text = curl_easy_escape (m_curl,
text.c_str (),
874 query << enc_name <<
'=' << enc_text;
876 curl_free (enc_name);
877 curl_free (enc_text);
879 if (i < param.
numel ()-2)
888 void ftp_file_or_dir_action (
const std::string& file_or_dir,
889 const std::string& action)
891 struct curl_slist *slist =
nullptr;
893 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
895 std::string cmd = action +
' ' + file_or_dir;
897 slist = curl_slist_append (slist, cmd.c_str ());
899 SETOPT (CURLOPT_POSTQUOTE, slist);
906 SETOPT (CURLOPT_POSTQUOTE, 0);
914 #if defined (HAVE_CURL)
915 # define REP_CLASS curl_transfer
917 # define REP_CLASS base_url_transfer
924 const std::string& passwd, std::ostream& os)
925 : m_rep (new
REP_CLASS (host, user, passwd, os))
934 OCTAVE_END_NAMESPACE(
octave)
octave_idx_type numel() const
Number of elements in the array.
virtual void http_get(const Array< std::string > &)
virtual void rename(const std::string &, const std::string &)
std::string m_host_or_url
virtual void form_data_post(const Array< std::string > &)
virtual void get(const std::string &, std::ostream &)
virtual void set_weboptions(const struct weboptions &)
virtual void put(const std::string &, std::istream &)
virtual void set_header_fields(const Array< std::string > &)
virtual void cwd(const std::string &)
virtual std::string pwd()
virtual void cookie_jar(const std::string &)
virtual void del(const std::string &)
std::istream * m_curr_istream
virtual string_vector list()
void mget_directory(const std::string &directory, const std::string &target)
virtual std::istream & set_istream(std::istream &)
virtual void http_post(const Array< std::string > &)
string_vector mput_directory(const std::string &base, const std::string &directory)
virtual void get_fileinfo(const std::string &, double &, OCTAVE_TIME_T &, bool &)
virtual std::ostream & set_ostream(std::ostream &)
std::ostream * m_curr_ostream
virtual void http_action(const Array< std::string > &, const std::string &)
virtual void rmdir(const std::string &)
virtual void mkdir(const std::string &)
virtual std::string lasterror() const
octave_value read(const Array< double > &size, octave_idx_type block_size, oct_data_conv::data_type input_type, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt, octave_idx_type &count)
octave_idx_type write(const octave_value &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
string_vector & append(const std::string &s)
void resize(octave_idx_type n, const std::string &rfv="")
octave_idx_type numel() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string dir_sep_str()
bool dir_exists(const std::string &dirname)
bool file_exists(const std::string &filename, bool is_dir)
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
std::ifstream ifstream(const std::string &filename, const std::ios::openmode mode)
bool get_dirlist(const std::string &dirname, string_vector &dirlist, std::string &msg)
int mkdir(const std::string &nm, mode_t md)
int unlink(const std::string &name)
std::string ContentReader
Array< std::string > HeaderFields
std::string CertificateFilename
#define SETOPT(option, parameter)
#define SETOPTR(option, parameter)