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)
78 sys::file_stat fs (directory);
80 if (! fs || ! fs.is_dir ())
83 int status =
sys::mkdir (directory, 0777, msg);
88 m_errmsg =
"__ftp_mget__: can not create directory '"
89 + target + sep + directory +
"': " + msg;
114 std::string realfile = target + directory + sep + sv(i);
118 std::ios::out | std::ios::binary);
120 if (! ofile.is_open ())
123 m_errmsg =
"__ftp_mget__: unable to open file";
126 int(*unlink_fptr)(
const std::string&) =
sys::unlink;
145 const std::string& directory)
170 std::string file = files (i);
172 if (file ==
"." || file ==
"..")
178 sys::file_stat fs (realfile);
183 m_errmsg =
"__ftp__mput: file '" + realfile
184 +
"' does not exist";
200 std::ios::in | std::ios::binary);
202 if (! ifile.is_open ())
205 m_errmsg =
"__ftp_mput__: unable to open file '"
217 file_list.
append (realfile);
223 m_errmsg =
"__ftp_mput__: can not read the directory '"
231 #if defined (HAVE_CURL)
234 write_data (
void *buffer, std::size_t size, std::size_t nmemb,
void *streamp)
236 std::ostream&
stream = *(
static_cast<std::ostream *
> (streamp));
237 stream.
write (
static_cast<const char *
> (buffer), size*nmemb);
238 return (
stream.fail () ? 0 : size * nmemb);
242 read_data (
void *buffer, std::size_t size, std::size_t nmemb,
void *streamp)
244 std::istream&
stream = *(
static_cast<std::istream *
> (streamp));
245 stream.
read (
static_cast<char *
> (buffer), size*nmemb);
249 return (
stream.fail () ? 0 : size * nmemb);
253 throw_away (
void *, std::size_t size, std::size_t nmemb,
void *)
255 return static_cast<std::size_t
> (size * nmemb);
261 #define SETOPT(option, parameter) \
264 CURLcode res = curl_easy_setopt (m_curl, option, parameter); \
265 if (res != CURLE_OK) \
268 m_errmsg = curl_easy_strerror (res); \
275 #define SETOPTR(option, parameter) \
278 CURLcode res = curl_easy_setopt (m_curl, option, parameter); \
279 if (res != CURLE_OK) \
282 m_errmsg = curl_easy_strerror (res); \
299 m_errmsg =
"can not create curl object";
303 const std::string& passwd, std::ostream& os)
311 m_errmsg =
"can not create curl object";
315 init (user_arg, passwd, std::cin, os);
317 m_url =
"ftp://" + host;
332 m_errmsg =
"can not create curl object";
336 init (
"",
"", std::cin, os);
338 std::string cainfo = sys::env::getenv (
"CURLOPT_CAINFO");
339 if (! cainfo.empty ())
340 SETOPT (CURLOPT_CAINFO, cainfo.c_str ());
342 std::string capath = sys::env::getenv (
"CURLOPT_CAPATH");
343 if (! capath.empty ())
344 SETOPT (CURLOPT_CAPATH, capath.c_str ());
346 SETOPT (CURLOPT_NOBODY, 0);
352 SETOPT (CURLOPT_HTTPGET, 1);
364 curl_easy_cleanup (
m_curl);
380 return std::string (curl_easy_strerror (
m_errnum));
402 SETOPT (CURLOPT_TRANSFERTEXT, 1);
408 SETOPT (CURLOPT_TRANSFERTEXT, 0);
411 void cwd (
const std::string& path)
416 void del (
const std::string& file)
421 void rmdir (
const std::string& path)
426 void mkdir (
const std::string& path)
431 void rename (
const std::string& oldname,
const std::string& newname)
433 struct curl_slist *slist =
nullptr;
435 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
437 std::string cmd =
"rnfr " + oldname;
438 slist = curl_slist_append (slist, cmd.c_str ());
439 cmd =
"rnto " + newname;
440 slist = curl_slist_append (slist, cmd.c_str ());
441 SETOPT (CURLOPT_POSTQUOTE, slist);
447 SETOPT (CURLOPT_POSTQUOTE, 0);
450 void put (
const std::string& file, std::istream& is)
454 SETOPT (CURLOPT_UPLOAD, 1);
455 SETOPT (CURLOPT_NOBODY, 0);
463 SETOPT (CURLOPT_NOBODY, 1);
464 SETOPT (CURLOPT_UPLOAD, 0);
469 void get (
const std::string& file, std::ostream& os)
473 SETOPT (CURLOPT_NOBODY, 0);
481 SETOPT (CURLOPT_NOBODY, 1);
490 SETOPT (CURLOPT_NOBODY, 0);
496 SETOPT (CURLOPT_NOBODY, 1);
505 std::ostringstream buf;
507 SETOPTR (CURLOPT_WRITEDATA,
static_cast<void *
> (&buf));
509 SETOPTR (CURLOPT_DIRLISTONLY, 1);
519 SETOPTR (CURLOPT_DIRLISTONLY, 0);
523 std::string str = buf.str ();
528 pos = str.find_first_of (
'\n', pos);
529 if (pos == std::string::npos)
538 std::size_t newpos = str.find_first_of (
'\n', pos);
539 if (newpos == std::string::npos)
542 retval(i) = str.substr(pos, newpos - pos);
550 OCTAVE_TIME_T& filetime,
bool& fileisdir)
552 std::string path =
pwd ();
556 SETOPT (CURLOPT_FILETIME, 1);
577 curl_easy_getinfo (
m_curl, CURLINFO_FILETIME, &ft);
580 curl_easy_getinfo (
m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs);
584 SETOPT (CURLOPT_HEADERFUNCTION, 0);
585 SETOPT (CURLOPT_FILETIME, 0);
600 struct curl_slist *slist =
nullptr;
602 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
604 slist = curl_slist_append (slist,
"pwd");
605 SETOPTR (CURLOPT_POSTQUOTE, slist);
608 std::ostringstream buf;
609 SETOPTR (CURLOPT_WRITEHEADER,
static_cast<void *
>(&buf));
618 std::size_t pos2 = retval.rfind (
'"');
619 std::size_t pos1 = retval.rfind (
'"', pos2 - 1);
620 retval = retval.substr (pos1 + 1, pos2 - pos1 - 1);
622 SETOPTR (CURLOPT_HEADERFUNCTION, 0);
623 SETOPTR (CURLOPT_WRITEHEADER, 0);
624 SETOPTR (CURLOPT_POSTQUOTE, 0);
643 std::string query_string;
647 if (action.empty () || action ==
"get")
649 if (! query_string.empty ())
650 m_url +=
'?' + query_string;
654 else if (action ==
"post" || action ==
"put" || action ==
"delete")
656 SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ());
660 SETOPT (CURLOPT_CUSTOMREQUEST,
"PUT");
663 if (action ==
"delete")
665 SETOPT (CURLOPT_CUSTOMREQUEST,
"DELETE");
673 m_errmsg =
"curl_transfer: unknown http action";
682 SETOPT (CURLOPT_COOKIEJAR, filename.c_str ());
684 SETOPT (CURLOPT_COOKIEFILE, filename.c_str ());
691 struct curl_slist *slist =
nullptr;
693 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
695 if (param.
numel () >= 2)
697 for (
int i = 0; i < param.
numel (); i += 2)
699 std::string header = param(i) +
": " + param(i+1);
701 slist = curl_slist_append (slist, header.c_str ());
704 SETOPT (CURLOPT_HTTPHEADER, slist);
715 struct curl_httppost *post =
nullptr;
716 struct curl_httppost *last =
nullptr;
720 unwind_action cleanup_httppost ([=] () { curl_formfree (post); });
722 if (param.
numel () >= 2)
724 for (
int i = 0; i < param.
numel (); i += 2)
726 std::string name = param(i);
727 std::string data = param(i+1);
730 curl_formadd (&post, &last, CURLFORM_COPYNAME, name.c_str (),
731 CURLFORM_FILE, data.c_str (), CURLFORM_END);
733 curl_formadd(&post, &last, CURLFORM_COPYNAME, name.c_str (),
734 CURLFORM_COPYCONTENTS, data.c_str (), CURLFORM_END);
737 SETOPT (CURLOPT_HTTPPOST, post);
747 std::string temp =
"";
761 SETOPT (CURLOPT_USERPWD, tmp.c_str ());
765 std::string tmp = options.
Username +
":";
766 SETOPT (CURLOPT_USERPWD, tmp.c_str ());
807 void init (
const std::string& user,
const std::string& passwd,
808 std::istream& is, std::ostream& os)
811 SETOPT (CURLOPT_NOBODY, 1);
815 if (! passwd.empty ())
824 SETOPT (CURLOPT_WRITEDATA,
static_cast<void *
> (&os));
830 SETOPT (CURLOPT_READDATA,
static_cast<void *
> (&is));
833 SETOPT (CURLOPT_FOLLOWLOCATION,
true);
838 SETOPT (CURLOPT_FTP_USE_EPSV,
false);
842 curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
843 const char *lib_ver = data->version;
844 std::string user_agent
847 +
" (https://www.gnu.org/software/octave/ ; help@octave.org) libcurl/"
848 + std::string (lib_ver));
850 SETOPT (CURLOPT_USERAGENT, user_agent.c_str ());
852 SETOPT (CURLOPT_NOPROGRESS,
true);
853 SETOPT (CURLOPT_FAILONERROR,
true);
855 SETOPT (CURLOPT_POSTQUOTE, 0);
856 SETOPT (CURLOPT_QUOTE, 0);
861 std::ostringstream query;
863 if (param.
numel () >= 2)
864 for (
int i = 0; i < param.
numel (); i += 2)
866 std::string name = param(i);
867 std::string text = param(i+1);
870 char *enc_name = curl_easy_escape (
m_curl, name.c_str (),
872 char *enc_text = curl_easy_escape (
m_curl, text.c_str (),
875 query << enc_name <<
'=' << enc_text;
877 curl_free (enc_name);
878 curl_free (enc_text);
880 if (i < param.
numel ()-2)
890 const std::string& action)
892 struct curl_slist *slist =
nullptr;
894 unwind_action cleanup_slist ([=] () { curl_slist_free_all (slist); });
896 std::string cmd = action +
' ' + file_or_dir;
898 slist = curl_slist_append (slist, cmd.c_str ());
900 SETOPT (CURLOPT_POSTQUOTE, slist);
907 SETOPT (CURLOPT_POSTQUOTE, 0);
915 #if defined (HAVE_CURL)
916 # define REP_CLASS curl_transfer
918 # define REP_CLASS base_url_transfer
925 const std::string& passwd, std::ostream& os)
926 : m_rep (new
REP_CLASS (host, user, passwd, os))
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
std::string m_host_or_url
virtual void get(const std::string &, std::ostream &)
virtual void put(const std::string &, std::istream &)
virtual void cwd(const std::string &)
std::istream * m_curr_istream
void mget_directory(const std::string &directory, const std::string &target)
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 string_vector list(void)
std::ostream * m_curr_ostream
virtual void mkdir(const std::string &)
curl_transfer & operator=(const curl_transfer &)=delete
std::ostream & set_ostream(std::ostream &os)
void rmdir(const std::string &path)
void del(const std::string &file)
void http_post(const Array< std::string > ¶m)
void set_header_fields(const Array< std::string > ¶m)
void form_data_post(const Array< std::string > ¶m)
void set_weboptions(const struct weboptions &options)
void http_action(const Array< std::string > ¶m, const std::string &action)
curl_transfer(const curl_transfer &)=delete
std::istream & set_istream(std::istream &is)
std::string form_query_string(const Array< std::string > ¶m)
curl_transfer(const std::string &host, const std::string &user_arg, const std::string &passwd, std::ostream &os)
void cookie_jar(const std::string &filename)
std::string lasterror(void) const
void ftp_file_or_dir_action(const std::string &file_or_dir, const std::string &action)
void http_get(const Array< std::string > ¶m)
void init(const std::string &user, const std::string &passwd, std::istream &is, std::ostream &os)
void mkdir(const std::string &path)
void put(const std::string &file, std::istream &is)
void cwd(const std::string &path)
void get(const std::string &file, std::ostream &os)
void get_fileinfo(const std::string &filename, double &filesize, OCTAVE_TIME_T &filetime, bool &fileisdir)
curl_transfer(const std::string &url_str, std::ostream &os)
void rename(const std::string &oldname, const std::string &newname)
OCTINTERP_API bool eof(void) const
OCTINTERP_API 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)
OCTINTERP_API 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(void) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
int unlink(const std::string &name)
std::string dir_sep_str(void)
int mkdir(const std::string &nm, mode_t md)
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)
std::string ContentReader
Array< std::string > HeaderFields
std::string CertificateFilename
#define SETOPT(option, parameter)
#define SETOPTR(option, parameter)
static int write_data(void *buffer, std::size_t size, std::size_t nmemb, void *streamp)
static int read_data(void *buffer, std::size_t size, std::size_t nmemb, void *streamp)
static std::size_t throw_away(void *, std::size_t size, std::size_t nmemb, void *)