# HG changeset patch # User John W. Eaton # Date 1463677289 14400 # Node ID e1be0b36fbedc92b6a86a559003c3700f202fbf0 # Parent f4d7d0eb5b0cf83d02b98c8cb10b95d399a836be use namespace for url_transfer class * url-transfer.h, url-transfer.cc: Put url_transfer in octave namespace. Change all uses. diff -r f4d7d0eb5b0c -r e1be0b36fbed libgui/src/main-window.cc --- a/libgui/src/main-window.cc Thu May 19 12:56:47 2016 -0400 +++ b/libgui/src/main-window.cc Thu May 19 13:01:29 2016 -0400 @@ -433,7 +433,7 @@ QString url = base_url + "/" + page; std::ostringstream buf; - url_transfer octave_dot_org (url.toStdString (), buf); + octave::url_transfer octave_dot_org (url.toStdString (), buf); if (octave_dot_org.is_valid ()) { diff -r f4d7d0eb5b0c -r e1be0b36fbed libinterp/corefcn/urlwrite.cc --- a/libinterp/corefcn/urlwrite.cc Thu May 19 12:56:47 2016 -0400 +++ b/libinterp/corefcn/urlwrite.cc Thu May 19 13:01:29 2016 -0400 @@ -109,19 +109,19 @@ : curl_handle (); } - static url_transfer get_object (double val) + static octave::url_transfer get_object (double val) { return get_object (lookup (val)); } - static url_transfer get_object (const octave_value& val) + static octave::url_transfer get_object (const octave_value& val) { return get_object (lookup (val)); } - static url_transfer get_object (const curl_handle& h) + static octave::url_transfer get_object (const curl_handle& h) { - return instance_ok () ? instance->do_get_object (h) : url_transfer (); + return instance_ok () ? instance->do_get_object (h) : octave::url_transfer (); } static curl_handle make_curl_handle (const std::string& host, @@ -143,14 +143,14 @@ static ch_manager *instance; - typedef std::map::iterator iterator; - typedef std::map::const_iterator const_iterator; + typedef std::map::iterator iterator; + typedef std::map::const_iterator const_iterator; typedef std::set::iterator free_list_iterator; typedef std::set::const_iterator const_free_list_iterator; // A map of handles to curl objects. - std::map handle_map; + std::map handle_map; // The available curl handles. std::set handle_free_list; @@ -169,11 +169,11 @@ return (p != handle_map.end ()) ? p->first : curl_handle (); } - url_transfer do_get_object (const curl_handle& h) + octave::url_transfer do_get_object (const curl_handle& h) { iterator p = (h.ok () ? handle_map.find (h) : handle_map.end ()); - return (p != handle_map.end ()) ? p->second : url_transfer (); + return (p != handle_map.end ()) ? p->second : octave::url_transfer (); } curl_handle do_make_curl_handle (const std::string& host, @@ -183,7 +183,7 @@ { curl_handle h = get_handle (); - url_transfer obj (host, user, passwd, os); + octave::url_transfer obj (host, user, passwd, os); if (! obj.is_valid ()) error ("support for URL transfers was disabled when Octave was built"); @@ -370,7 +370,7 @@ frame.add_fcn (delete_file, filename); - url_transfer curl = url_transfer (url, ofile); + octave::url_transfer curl = octave::url_transfer (url, ofile); octave_value_list retval; @@ -468,7 +468,7 @@ std::ostringstream buf; - url_transfer curl = url_transfer (url, buf); + octave::url_transfer curl = octave::url_transfer (url, buf); if (! curl.is_valid ()) error ("support for URL transfers was disabled when Octave was built"); @@ -527,7 +527,7 @@ if (args.length () != 1) error ("__ftp_pwd__: incorrect number of arguments"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_pwd__: invalid ftp handle"); @@ -550,7 +550,7 @@ if (nargin > 1) path = args(1).xstring_value ("__ftp_cwd__: PATH must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_cwd__: invalid ftp handle"); @@ -569,7 +569,7 @@ if (args.length () != 1) error ("__ftp_dir__: incorrect number of arguments"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_dir__: invalid ftp handle"); @@ -641,7 +641,7 @@ if (args.length () != 1) error ("__ftp_ascii__: incorrect number of arguments"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_ascii__: invalid ftp handle"); @@ -660,7 +660,7 @@ if (args.length () != 1) error ("__ftp_binary__: incorrect number of arguments"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_binary__: invalid ftp handle"); @@ -698,7 +698,7 @@ if (args.length () != 1) error ("__ftp_mode__: incorrect number of arguments"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_binary__: invalid ftp handle"); @@ -717,7 +717,7 @@ std::string file = args(1).xstring_value ("__ftp_delete__: FILE must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_delete__: invalid ftp handle"); @@ -738,7 +738,7 @@ std::string dir = args(1).xstring_value ("__ftp_rmdir__: DIR must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_rmdir__: invalid ftp handle"); @@ -759,7 +759,7 @@ std::string dir = args(1).xstring_value ("__ftp_mkdir__: DIR must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_mkdir__: invalid ftp handle"); @@ -781,7 +781,7 @@ std::string oldname = args(1).xstring_value ("__ftp_rename__: OLDNAME must be a string"); std::string newname = args(2).xstring_value ("__ftp_rename__: NEWNAME must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (curl.is_valid ()) error ("__ftp_rename__: invalid ftp handle"); @@ -802,7 +802,7 @@ std::string pat = args(1).xstring_value ("__ftp_mput__: PATTERN must be a string"); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_mput__: invalid ftp handle"); @@ -872,7 +872,7 @@ if (nargin == 3 && ! args(2).is_empty ()) target = args(2).xstring_value ("__ftp_mget__: TARGET must be a string") + octave::sys::file_ops::dir_sep_str (); - url_transfer curl = ch_manager::get_object (args(0)); + octave::url_transfer curl = ch_manager::get_object (args(0)); if (! curl.is_valid ()) error ("__ftp_mget__: invalid ftp handle"); diff -r f4d7d0eb5b0c -r e1be0b36fbed liboctave/util/url-transfer.cc --- a/liboctave/util/url-transfer.cc Thu May 19 12:56:47 2016 -0400 +++ b/liboctave/util/url-transfer.cc Thu May 19 13:01:29 2016 -0400 @@ -45,725 +45,727 @@ # include #endif -void -base_url_transfer::delete_file (const std::string& file) -{ - octave::sys::unlink (file); -} - -void -base_url_transfer::mget_directory (const std::string& directory, - const std::string& target) -{ - std::string sep = octave::sys::file_ops::dir_sep_str (); - octave::sys::file_stat fs (directory); - - if (! fs || ! fs.is_dir ()) - { - std::string msg; - int status = octave::sys::mkdir (directory, 0777, msg); - - if (status < 0) - { - ok = false; - errmsg = "__ftp_mget__: can not create directory '" - + target + sep + directory + "': " + msg; - return; - } - } - - cwd (directory); - - if (good ()) - { - octave::unwind_protect_safe frame; - - frame.add_fcn (reset_path, this); - - string_vector sv = list (); - - for (octave_idx_type i = 0; i < sv.numel (); i++) - { - time_t ftime; - bool fisdir; - double fsize; - - get_fileinfo (sv(i), fsize, ftime, fisdir); - - if (fisdir) - mget_directory (sv(i), target + directory + sep); - else - { - std::string realfile = target + directory + sep + sv(i); - - std::ofstream ofile (realfile.c_str (), - std::ios::out | std::ios::binary); - - if (! ofile.is_open ()) - { - ok = false; - errmsg = "__ftp_mget__: unable to open file"; - break; - } - - octave::unwind_protect_safe frame2; - - frame2.add_fcn (delete_file, realfile); - - get (sv(i), ofile); - - ofile.close (); - - if (good ()) - frame2.discard (); - } - - if (! good ()) - break; - } - } -} - -string_vector -base_url_transfer::mput_directory (const std::string& base, - const std::string& directory) +namespace octave { - string_vector file_list; + void + base_url_transfer::delete_file (const std::string& file) + { + octave::sys::unlink (file); + } - std::string realdir - = (base.length () == 0 - ? directory : base + octave::sys::file_ops::dir_sep_str () + directory); + void + base_url_transfer::mget_directory (const std::string& directory, + const std::string& target) + { + std::string sep = octave::sys::file_ops::dir_sep_str (); + octave::sys::file_stat fs (directory); - mkdir (directory); + if (! fs || ! fs.is_dir ()) + { + std::string msg; + int status = octave::sys::mkdir (directory, 0777, msg); - if (! good ()) - return file_list; - - cwd (directory); + if (status < 0) + { + ok = false; + errmsg = "__ftp_mget__: can not create directory '" + + target + sep + directory + "': " + msg; + return; + } + } - if (good ()) - { - octave::unwind_protect_safe frame; + cwd (directory); - frame.add_fcn (reset_path, this); + if (good ()) + { + octave::unwind_protect_safe frame; - octave::sys::dir_entry dirlist (realdir); + frame.add_fcn (reset_path, this); + + string_vector sv = list (); - if (dirlist) - { - string_vector files = dirlist.read (); + for (octave_idx_type i = 0; i < sv.numel (); i++) + { + time_t ftime; + bool fisdir; + double fsize; + + get_fileinfo (sv(i), fsize, ftime, fisdir); - for (octave_idx_type i = 0; i < files.numel (); i++) - { - std::string file = files (i); + if (fisdir) + mget_directory (sv(i), target + directory + sep); + else + { + std::string realfile = target + directory + sep + sv(i); - if (file == "." || file == "..") - continue; + std::ofstream ofile (realfile.c_str (), + std::ios::out | std::ios::binary); - std::string realfile = realdir + octave::sys::file_ops::dir_sep_str () + file; - octave::sys::file_stat fs (realfile); + if (! ofile.is_open ()) + { + ok = false; + errmsg = "__ftp_mget__: unable to open file"; + break; + } + + octave::unwind_protect_safe frame2; + + frame2.add_fcn (delete_file, realfile); - if (! fs.exists ()) - { - ok = false; - errmsg = "__ftp__mput: file '" + realfile - + "' does not exist"; - break; - } + get (sv(i), ofile); + + ofile.close (); + + if (good ()) + frame2.discard (); + } + + if (! good ()) + break; + } + } + } - if (fs.is_dir ()) - { - file_list.append (mput_directory (realdir, file)); + string_vector + base_url_transfer::mput_directory (const std::string& base, + const std::string& directory) + { + string_vector file_list; + + std::string realdir + = (base.length () == 0 + ? directory : base + octave::sys::file_ops::dir_sep_str () + directory); + + mkdir (directory); + + if (! good ()) + return file_list; + + cwd (directory); - if (! good ()) - break; - } - else - { - // FIXME: Does ascii mode need to be flagged here? - std::ifstream ifile (realfile.c_str (), std::ios::in | - std::ios::binary); + if (good ()) + { + octave::unwind_protect_safe frame; + + frame.add_fcn (reset_path, this); + + octave::sys::dir_entry dirlist (realdir); - if (! ifile.is_open ()) - { - ok = false; - errmsg = "__ftp_mput__: unable to open file '" - + realfile + "'"; - break; - } + if (dirlist) + { + string_vector files = dirlist.read (); + + for (octave_idx_type i = 0; i < files.numel (); i++) + { + std::string file = files (i); + + if (file == "." || file == "..") + continue; + + std::string realfile = realdir + octave::sys::file_ops::dir_sep_str () + file; + octave::sys::file_stat fs (realfile); - put (file, ifile); + if (! fs.exists ()) + { + ok = false; + errmsg = "__ftp__mput: file '" + realfile + + "' does not exist"; + break; + } - ifile.close (); + if (fs.is_dir ()) + { + file_list.append (mput_directory (realdir, file)); - if (! good ()) - break; + if (! good ()) + break; + } + else + { + // FIXME: Does ascii mode need to be flagged here? + std::ifstream ifile (realfile.c_str (), std::ios::in | + std::ios::binary); - file_list.append (realfile); - } - } - } - else - { - ok = false; - errmsg = "__ftp_mput__: can not read the directory '" - + realdir + "'"; - } - } + if (! ifile.is_open ()) + { + ok = false; + errmsg = "__ftp_mput__: unable to open file '" + + realfile + "'"; + break; + } + + put (file, ifile); + + ifile.close (); + + if (! good ()) + break; - return file_list; -} + file_list.append (realfile); + } + } + } + else + { + ok = false; + errmsg = "__ftp_mput__: can not read the directory '" + + realdir + "'"; + } + } + + return file_list; + } #if defined (HAVE_CURL) -static int -write_data (void *buffer, size_t size, size_t nmemb, void *streamp) -{ - std::ostream& stream = *(static_cast (streamp)); - stream.write (static_cast (buffer), size*nmemb); - return (stream.fail () ? 0 : size * nmemb); -} - -static int -read_data (void *buffer, size_t size, size_t nmemb, void *streamp) -{ - std::istream& stream = *(static_cast (streamp)); - stream.read (static_cast (buffer), size*nmemb); - if (stream.eof ()) - return stream.gcount (); - else + static int + write_data (void *buffer, size_t size, size_t nmemb, void *streamp) + { + std::ostream& stream = *(static_cast (streamp)); + stream.write (static_cast (buffer), size*nmemb); return (stream.fail () ? 0 : size * nmemb); -} - -static size_t -throw_away (void *, size_t size, size_t nmemb, void *) -{ - return static_cast(size * nmemb); -} - -// I'd love to rewrite this as a private method of the url_transfer -// class, but you can't pass the va_list from the wrapper SETOPT to -// the curl_easy_setopt function. -#define SETOPT(option, parameter) \ - do \ - { \ - CURLcode res = curl_easy_setopt (curl, option, parameter); \ - if (res != CURLE_OK) \ - { \ - ok = false; \ - errmsg = curl_easy_strerror (res); \ - return; \ - } \ - } \ - while (0) - -// Same as above but with a return value. -#define SETOPTR(option, parameter) \ - do \ - { \ - CURLcode res = curl_easy_setopt (curl, option, parameter); \ - if (res != CURLE_OK) \ - { \ - ok = false; \ - errmsg = curl_easy_strerror (res); \ - return retval; \ - } \ - } \ - while (0) - -class curl_transfer : public base_url_transfer -{ -public: - - curl_transfer (void) - : base_url_transfer (), curl (curl_easy_init ()), errnum (), url (), - userpwd () - { - if (curl) - valid = true; - else - errmsg = "can not create curl object"; - } - - curl_transfer (const std::string& host, const std::string& user_arg, - const std::string& passwd, std::ostream& os) - : base_url_transfer (host, user_arg, passwd, os), - curl (curl_easy_init ()), errnum (), url (), userpwd () - { - if (curl) - valid = true; - else - { - errmsg = "can not create curl object"; - return; - } - - init (user_arg, passwd, std::cin, os); - - url = "ftp://" + host; - SETOPT (CURLOPT_URL, url.c_str ()); - - // Set up the link, with no transfer. - perform (); - } - - curl_transfer (const std::string& url_str, std::ostream& os) - : base_url_transfer (url_str, os), curl (curl_easy_init ()), errnum (), - url (), userpwd () - { - if (curl) - valid = true; - else - { - errmsg = "can not create curl object"; - return; - } - - init ("", "", std::cin, os); - - SETOPT (CURLOPT_NOBODY, 0); - - // Restore the default HTTP request method to GET after setting - // NOBODY to true (in the init method) and back to false (above). - // This is needed for backward compatibility with versions of - // libcurl < 7.18.2. - SETOPT (CURLOPT_HTTPGET, 1); - } - - ~curl_transfer (void) - { - if (curl) - curl_easy_cleanup (curl); } - void perform (void) - { - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - - errnum = curl_easy_perform (curl); - - if (errnum != CURLE_OK) - { - ok = false; - errmsg = curl_easy_strerror (errnum); - } - - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - } - - std::string lasterror (void) const - { - return std::string (curl_easy_strerror (errnum)); - } - - std::ostream& set_ostream (std::ostream& os) - { - std::ostream& retval = *curr_ostream; - curr_ostream = &os; - SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); - return retval; - } - - std::istream& set_istream (std::istream& is) + static int + read_data (void *buffer, size_t size, size_t nmemb, void *streamp) { - std::istream& retval = *curr_istream; - curr_istream = &is; - SETOPTR (CURLOPT_READDATA, static_cast (curr_istream)); - return retval; - } - - void ascii (void) - { - ascii_mode = true; - SETOPT (CURLOPT_TRANSFERTEXT, 1); - } - - void binary (void) - { - ascii_mode = false; - SETOPT (CURLOPT_TRANSFERTEXT, 0); - } - - void cwd (const std::string& path) - { - ftp_file_or_dir_action (path, "cwd"); - } - - void del (const std::string& file) - { - ftp_file_or_dir_action (file, "dele"); - } - - void rmdir (const std::string& path) - { - ftp_file_or_dir_action (path, "rmd"); - } - - void mkdir (const std::string& path) - { - ftp_file_or_dir_action (path, "mkd"); + std::istream& stream = *(static_cast (streamp)); + stream.read (static_cast (buffer), size*nmemb); + if (stream.eof ()) + return stream.gcount (); + else + return (stream.fail () ? 0 : size * nmemb); } - void rename (const std::string& oldname, const std::string& newname) - { - struct curl_slist *slist = 0; - - octave::unwind_protect frame; - frame.add_fcn (curl_slist_free_all, slist); - - std::string cmd = "rnfr " + oldname; - slist = curl_slist_append (slist, cmd.c_str ()); - cmd = "rnto " + newname; - slist = curl_slist_append (slist, cmd.c_str ()); - SETOPT (CURLOPT_POSTQUOTE, slist); - - perform (); - if (! good ()) - return; - - SETOPT (CURLOPT_POSTQUOTE, 0); - } - - void put (const std::string& file, std::istream& is) + static size_t + throw_away (void *, size_t size, size_t nmemb, void *) { - url = "ftp://" + host_or_url + "/" + file; - SETOPT (CURLOPT_URL, url.c_str ()); - SETOPT (CURLOPT_UPLOAD, 1); - SETOPT (CURLOPT_NOBODY, 0); - std::istream& old_is = set_istream (is); - - perform (); - if (! good ()) - return; - - set_istream (old_is); - SETOPT (CURLOPT_NOBODY, 1); - SETOPT (CURLOPT_UPLOAD, 0); - url = "ftp://" + host_or_url; - SETOPT (CURLOPT_URL, url.c_str ()); - } - - void get (const std::string& file, std::ostream& os) - { - url = "ftp://" + host_or_url + "/" + file; - SETOPT (CURLOPT_URL, url.c_str ()); - SETOPT (CURLOPT_NOBODY, 0); - std::ostream& old_os = set_ostream (os); - - perform (); - if (! good ()) - return; - - set_ostream (old_os); - SETOPT (CURLOPT_NOBODY, 1); - url = "ftp://" + host_or_url; - SETOPT (CURLOPT_URL, url.c_str ()); - } - - void dir (void) - { - url = "ftp://" + host_or_url + "/"; - SETOPT (CURLOPT_URL, url.c_str ()); - SETOPT (CURLOPT_NOBODY, 0); - - perform (); - if (! good ()) - return; - - SETOPT (CURLOPT_NOBODY, 1); - url = "ftp://" + host_or_url; - SETOPT (CURLOPT_URL, url.c_str ()); + return static_cast(size * nmemb); } - string_vector list (void) - { - string_vector retval; - - std::ostringstream buf; - url = "ftp://" + host_or_url + "/"; - SETOPTR (CURLOPT_WRITEDATA, static_cast (&buf)); - SETOPTR (CURLOPT_URL, url.c_str ()); - SETOPTR (CURLOPT_DIRLISTONLY, 1); - SETOPTR (CURLOPT_NOBODY, 0); - - perform (); - if (! good ()) - return retval; - - SETOPTR (CURLOPT_NOBODY, 1); - url = "ftp://" + host_or_url; - SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); - SETOPTR (CURLOPT_DIRLISTONLY, 0); - SETOPTR (CURLOPT_URL, url.c_str ()); - - // Count number of directory entries - std::string str = buf.str (); - octave_idx_type n = 0; - size_t pos = 0; - while (true) - { - pos = str.find_first_of ('\n', pos); - if (pos == std::string::npos) - break; - pos++; - n++; - } - retval.resize (n); - pos = 0; - for (octave_idx_type i = 0; i < n; i++) - { - size_t newpos = str.find_first_of ('\n', pos); - if (newpos == std::string::npos) - break; - - retval(i) = str.substr(pos, newpos - pos); - pos = newpos + 1; - } - - return retval; - } - - void get_fileinfo (const std::string& filename, double& filesize, - time_t& filetime, bool& fileisdir) - { - std::string path = pwd (); - - url = "ftp://" + host_or_url + "/" + path + "/" + filename; - SETOPT (CURLOPT_URL, url.c_str ()); - SETOPT (CURLOPT_FILETIME, 1); - SETOPT (CURLOPT_HEADERFUNCTION, throw_away); - SETOPT (CURLOPT_WRITEFUNCTION, throw_away); - - // FIXME - // The MDTM command fails for a directory on the servers I tested - // so this is a means of testing for directories. It also means - // I can't get the date of directories! - - perform (); - if (! good ()) - { - fileisdir = true; - filetime = -1; - filesize = 0; + // I'd love to rewrite this as a private method of the url_transfer + // class, but you can't pass the va_list from the wrapper SETOPT to + // the curl_easy_setopt function. +#define SETOPT(option, parameter) \ + do \ + { \ + CURLcode res = curl_easy_setopt (curl, option, parameter); \ + if (res != CURLE_OK) \ + { \ + ok = false; \ + errmsg = curl_easy_strerror (res); \ + return; \ + } \ + } \ + while (0) - return; - } - - fileisdir = false; - time_t ft; - curl_easy_getinfo (curl, CURLINFO_FILETIME, &ft); - filetime = ft; - double fs; - curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs); - filesize = fs; - - SETOPT (CURLOPT_WRITEFUNCTION, write_data); - SETOPT (CURLOPT_HEADERFUNCTION, 0); - SETOPT (CURLOPT_FILETIME, 0); - url = "ftp://" + host_or_url; - SETOPT (CURLOPT_URL, url.c_str ()); - - // The MDTM command seems to reset the path to the root with the - // servers I tested with, so cd again into the correct path. Make - // the path absolute so that this will work even with servers that - // don't end up in the root after an MDTM command. - cwd ("/" + path); - } - - std::string pwd (void) - { - std::string retval; - - struct curl_slist *slist = 0; - - octave::unwind_protect frame; - frame.add_fcn (curl_slist_free_all, slist); - - slist = curl_slist_append (slist, "pwd"); - SETOPTR (CURLOPT_POSTQUOTE, slist); - SETOPTR (CURLOPT_HEADERFUNCTION, write_data); + // Same as above but with a return value. +#define SETOPTR(option, parameter) \ + do \ + { \ + CURLcode res = curl_easy_setopt (curl, option, parameter); \ + if (res != CURLE_OK) \ + { \ + ok = false; \ + errmsg = curl_easy_strerror (res); \ + return retval; \ +} \ +} \ + while (0) - std::ostringstream buf; - SETOPTR (CURLOPT_WRITEHEADER, static_cast(&buf)); - - perform (); - if (! good ()) - return retval; - - retval = buf.str (); - - // Can I assume that the path is alway in "" on the last line - size_t pos2 = retval.rfind ('"'); - size_t pos1 = retval.rfind ('"', pos2 - 1); - retval = retval.substr (pos1 + 1, pos2 - pos1 - 1); - - SETOPTR (CURLOPT_HEADERFUNCTION, 0); - SETOPTR (CURLOPT_WRITEHEADER, 0); - SETOPTR (CURLOPT_POSTQUOTE, 0); - - return retval; - } - - void http_get (const Array& param) - { - url = host_or_url; - - std::string query_string = form_query_string (param); - - if (! query_string.empty ()) - url += "?" + query_string; - - SETOPT (CURLOPT_URL, url.c_str ()); - - perform (); - } - - void http_post (const Array& param) + class curl_transfer : public base_url_transfer { - SETOPT (CURLOPT_URL, host_or_url.c_str ()); + public: + + curl_transfer (void) + : base_url_transfer (), curl (curl_easy_init ()), errnum (), url (), + userpwd () + { + if (curl) + valid = true; + else + errmsg = "can not create curl object"; + } - std::string query_string = form_query_string (param); + curl_transfer (const std::string& host, const std::string& user_arg, + const std::string& passwd, std::ostream& os) + : base_url_transfer (host, user_arg, passwd, os), + curl (curl_easy_init ()), errnum (), url (), userpwd () + { + if (curl) + valid = true; + else + { + errmsg = "can not create curl object"; + return; + } + + init (user_arg, passwd, std::cin, os); - SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ()); + url = "ftp://" + host; + SETOPT (CURLOPT_URL, url.c_str ()); + + // Set up the link, with no transfer. + perform (); + } - perform (); - } + curl_transfer (const std::string& url_str, std::ostream& os) + : base_url_transfer (url_str, os), curl (curl_easy_init ()), errnum (), + url (), userpwd () + { + if (curl) + valid = true; + else + { + errmsg = "can not create curl object"; + return; + } + + init ("", "", std::cin, os); + + SETOPT (CURLOPT_NOBODY, 0); + + // Restore the default HTTP request method to GET after setting + // NOBODY to true (in the init method) and back to false (above). + // This is needed for backward compatibility with versions of + // libcurl < 7.18.2. + SETOPT (CURLOPT_HTTPGET, 1); + } - void http_action (const Array& param, const std::string& action) - { - if (action.empty () || action == "get") - http_get (param); - else if (action == "post") - http_post (param); - else - { - ok = false; - errmsg = "curl_transfer: unknown http action"; - } - } + ~curl_transfer (void) + { + if (curl) + curl_easy_cleanup (curl); + } + + void perform (void) + { + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + errnum = curl_easy_perform (curl); + + if (errnum != CURLE_OK) + { + ok = false; + errmsg = curl_easy_strerror (errnum); + } + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + } + + std::string lasterror (void) const + { + return std::string (curl_easy_strerror (errnum)); + } -private: + std::ostream& set_ostream (std::ostream& os) + { + std::ostream& retval = *curr_ostream; + curr_ostream = &os; + SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); + return retval; + } + + std::istream& set_istream (std::istream& is) + { + std::istream& retval = *curr_istream; + curr_istream = &is; + SETOPTR (CURLOPT_READDATA, static_cast (curr_istream)); + return retval; + } - // Pointer to cURL object. - CURL *curl; + void ascii (void) + { + ascii_mode = true; + SETOPT (CURLOPT_TRANSFERTEXT, 1); + } - // cURL error code. - CURLcode errnum; + void binary (void) + { + ascii_mode = false; + SETOPT (CURLOPT_TRANSFERTEXT, 0); + } + + void cwd (const std::string& path) + { + ftp_file_or_dir_action (path, "cwd"); + } + + void del (const std::string& file) + { + ftp_file_or_dir_action (file, "dele"); + } - // The cURL library changed the curl_easy_setopt call to make an - // internal copy of string parameters in version 7.17.0. Prior - // versions only held a pointer to a string provided by the caller - // that must persist for the lifetime of the CURL handle. - // - // The associated API did not change, only the behavior of the library - // implementing the function call. - // - // To be compatible with any version of cURL, the caller must keep a - // copy of all string parameters associated with a CURL handle until - // the handle is released. The curl_handle::curl_handle_rep class - // contains the pointer to the CURL handle and so is the best - // candidate for storing the strings as well. (bug #36717) - std::string url; - std::string userpwd; + void rmdir (const std::string& path) + { + ftp_file_or_dir_action (path, "rmd"); + } + + void mkdir (const std::string& path) + { + ftp_file_or_dir_action (path, "mkd"); + } + + void rename (const std::string& oldname, const std::string& newname) + { + struct curl_slist *slist = 0; + + octave::unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "rnfr " + oldname; + slist = curl_slist_append (slist, cmd.c_str ()); + cmd = "rnto " + newname; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } - // No copying! + void put (const std::string& file, std::istream& is) + { + url = "ftp://" + host_or_url + "/" + file; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_UPLOAD, 1); + SETOPT (CURLOPT_NOBODY, 0); + std::istream& old_is = set_istream (is); + + perform (); + if (! good ()) + return; - curl_transfer (const curl_transfer&); + set_istream (old_is); + SETOPT (CURLOPT_NOBODY, 1); + SETOPT (CURLOPT_UPLOAD, 0); + url = "ftp://" + host_or_url; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + void get (const std::string& file, std::ostream& os) + { + url = "ftp://" + host_or_url + "/" + file; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_NOBODY, 0); + std::ostream& old_os = set_ostream (os); + + perform (); + if (! good ()) + return; - curl_transfer& operator = (const curl_transfer&); + set_ostream (old_os); + SETOPT (CURLOPT_NOBODY, 1); + url = "ftp://" + host_or_url; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + void dir (void) + { + url = "ftp://" + host_or_url + "/"; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_NOBODY, 0); - void init (const std::string& user, const std::string& passwd, - std::istream& is, std::ostream& os) - { - // No data transfer by default - SETOPT (CURLOPT_NOBODY, 1); + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_NOBODY, 1); + url = "ftp://" + host_or_url; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + string_vector list (void) + { + string_vector retval; - // Set the username and password - userpwd = user; - if (! passwd.empty ()) - userpwd += ":" + passwd; - if (! userpwd.empty ()) - SETOPT (CURLOPT_USERPWD, userpwd.c_str ()); + std::ostringstream buf; + url = "ftp://" + host_or_url + "/"; + SETOPTR (CURLOPT_WRITEDATA, static_cast (&buf)); + SETOPTR (CURLOPT_URL, url.c_str ()); + SETOPTR (CURLOPT_DIRLISTONLY, 1); + SETOPTR (CURLOPT_NOBODY, 0); + + perform (); + if (! good ()) + return retval; + + SETOPTR (CURLOPT_NOBODY, 1); + url = "ftp://" + host_or_url; + SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); + SETOPTR (CURLOPT_DIRLISTONLY, 0); + SETOPTR (CURLOPT_URL, url.c_str ()); - // Define our callback to get called when there's data to be written. - SETOPT (CURLOPT_WRITEFUNCTION, write_data); - - // Set a pointer to our struct to pass to the callback. - SETOPT (CURLOPT_WRITEDATA, static_cast (&os)); + // Count number of directory entries + std::string str = buf.str (); + octave_idx_type n = 0; + size_t pos = 0; + while (true) + { + pos = str.find_first_of ('\n', pos); + if (pos == std::string::npos) + break; + pos++; + n++; + } + retval.resize (n); + pos = 0; + for (octave_idx_type i = 0; i < n; i++) + { + size_t newpos = str.find_first_of ('\n', pos); + if (newpos == std::string::npos) + break; - // Define our callback to get called when there's data to be read - SETOPT (CURLOPT_READFUNCTION, read_data); + retval(i) = str.substr(pos, newpos - pos); + pos = newpos + 1; + } + + return retval; + } - // Set a pointer to our struct to pass to the callback. - SETOPT (CURLOPT_READDATA, static_cast (&is)); + void get_fileinfo (const std::string& filename, double& filesize, + time_t& filetime, bool& fileisdir) + { + std::string path = pwd (); + + url = "ftp://" + host_or_url + "/" + path + "/" + filename; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_FILETIME, 1); + SETOPT (CURLOPT_HEADERFUNCTION, throw_away); + SETOPT (CURLOPT_WRITEFUNCTION, throw_away); + + // FIXME + // The MDTM command fails for a directory on the servers I tested + // so this is a means of testing for directories. It also means + // I can't get the date of directories! - // Follow redirects. - SETOPT (CURLOPT_FOLLOWLOCATION, true); + perform (); + if (! good ()) + { + fileisdir = true; + filetime = -1; + filesize = 0; + + return; + } - // Don't use EPSV since connecting to sites that don't support it - // will hang for some time (3 minutes?) before moving on to try PASV - // instead. - SETOPT (CURLOPT_FTP_USE_EPSV, false); + fileisdir = false; + time_t ft; + curl_easy_getinfo (curl, CURLINFO_FILETIME, &ft); + filetime = ft; + double fs; + curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs); + filesize = fs; - SETOPT (CURLOPT_NOPROGRESS, true); - SETOPT (CURLOPT_FAILONERROR, true); + SETOPT (CURLOPT_WRITEFUNCTION, write_data); + SETOPT (CURLOPT_HEADERFUNCTION, 0); + SETOPT (CURLOPT_FILETIME, 0); + url = "ftp://" + host_or_url; + SETOPT (CURLOPT_URL, url.c_str ()); + + // The MDTM command seems to reset the path to the root with the + // servers I tested with, so cd again into the correct path. Make + // the path absolute so that this will work even with servers that + // don't end up in the root after an MDTM command. + cwd ("/" + path); + } - SETOPT (CURLOPT_POSTQUOTE, 0); - SETOPT (CURLOPT_QUOTE, 0); - } + std::string pwd (void) + { + std::string retval; + + struct curl_slist *slist = 0; + + octave::unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + slist = curl_slist_append (slist, "pwd"); + SETOPTR (CURLOPT_POSTQUOTE, slist); + SETOPTR (CURLOPT_HEADERFUNCTION, write_data); - std::string form_query_string (const Array& param) - { - std::ostringstream query; + std::ostringstream buf; + SETOPTR (CURLOPT_WRITEHEADER, static_cast(&buf)); + + perform (); + if (! good ()) + return retval; + + retval = buf.str (); + + // Can I assume that the path is alway in "" on the last line + size_t pos2 = retval.rfind ('"'); + size_t pos1 = retval.rfind ('"', pos2 - 1); + retval = retval.substr (pos1 + 1, pos2 - pos1 - 1); - for (int i = 0; i < param.numel (); i += 2) - { - std::string name = param(i); - std::string text = param(i+1); + SETOPTR (CURLOPT_HEADERFUNCTION, 0); + SETOPTR (CURLOPT_WRITEHEADER, 0); + SETOPTR (CURLOPT_POSTQUOTE, 0); + + return retval; + } + + void http_get (const Array& param) + { + url = host_or_url; + + std::string query_string = form_query_string (param); + + if (! query_string.empty ()) + url += "?" + query_string; - // Encode strings. - char *enc_name = curl_easy_escape (curl, name.c_str (), - name.length ()); - char *enc_text = curl_easy_escape (curl, text.c_str (), - text.length ()); + SETOPT (CURLOPT_URL, url.c_str ()); + + perform (); + } + + void http_post (const Array& param) + { + SETOPT (CURLOPT_URL, host_or_url.c_str ()); + + std::string query_string = form_query_string (param); + + SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ()); + + perform (); + } - query << enc_name << "=" << enc_text; + void http_action (const Array& param, const std::string& action) + { + if (action.empty () || action == "get") + http_get (param); + else if (action == "post") + http_post (param); + else + { + ok = false; + errmsg = "curl_transfer: unknown http action"; + } + } - curl_free (enc_name); - curl_free (enc_text); + private: - if (i < param.numel ()-1) - query << "&"; - } + // Pointer to cURL object. + CURL *curl; + + // cURL error code. + CURLcode errnum; - query.flush (); + // The cURL library changed the curl_easy_setopt call to make an + // internal copy of string parameters in version 7.17.0. Prior + // versions only held a pointer to a string provided by the caller + // that must persist for the lifetime of the CURL handle. + // + // The associated API did not change, only the behavior of the library + // implementing the function call. + // + // To be compatible with any version of cURL, the caller must keep a + // copy of all string parameters associated with a CURL handle until + // the handle is released. The curl_handle::curl_handle_rep class + // contains the pointer to the CURL handle and so is the best + // candidate for storing the strings as well. (bug #36717) + std::string url; + std::string userpwd; - return query.str (); - } + // No copying! + + curl_transfer (const curl_transfer&); + + curl_transfer& operator = (const curl_transfer&); - void ftp_file_or_dir_action (const std::string& file_or_dir, - const std::string& action) - { - struct curl_slist *slist = 0; + void init (const std::string& user, const std::string& passwd, + std::istream& is, std::ostream& os) + { + // No data transfer by default + SETOPT (CURLOPT_NOBODY, 1); + + // Set the username and password + userpwd = user; + if (! passwd.empty ()) + userpwd += ":" + passwd; + if (! userpwd.empty ()) + SETOPT (CURLOPT_USERPWD, userpwd.c_str ()); + + // Define our callback to get called when there's data to be written. + SETOPT (CURLOPT_WRITEFUNCTION, write_data); + + // Set a pointer to our struct to pass to the callback. + SETOPT (CURLOPT_WRITEDATA, static_cast (&os)); + + // Define our callback to get called when there's data to be read + SETOPT (CURLOPT_READFUNCTION, read_data); + + // Set a pointer to our struct to pass to the callback. + SETOPT (CURLOPT_READDATA, static_cast (&is)); - octave::unwind_protect frame; + // Follow redirects. + SETOPT (CURLOPT_FOLLOWLOCATION, true); - frame.add_fcn (curl_slist_free_all, slist); + // Don't use EPSV since connecting to sites that don't support it + // will hang for some time (3 minutes?) before moving on to try PASV + // instead. + SETOPT (CURLOPT_FTP_USE_EPSV, false); + + SETOPT (CURLOPT_NOPROGRESS, true); + SETOPT (CURLOPT_FAILONERROR, true); + + SETOPT (CURLOPT_POSTQUOTE, 0); + SETOPT (CURLOPT_QUOTE, 0); + } - std::string cmd = action + " " + file_or_dir; + std::string form_query_string (const Array& param) + { + std::ostringstream query; - slist = curl_slist_append (slist, cmd.c_str ()); + for (int i = 0; i < param.numel (); i += 2) + { + std::string name = param(i); + std::string text = param(i+1); + + // Encode strings. + char *enc_name = curl_easy_escape (curl, name.c_str (), + name.length ()); + char *enc_text = curl_easy_escape (curl, text.c_str (), + text.length ()); + + query << enc_name << "=" << enc_text; - SETOPT (CURLOPT_POSTQUOTE, slist); + curl_free (enc_name); + curl_free (enc_text); + + if (i < param.numel ()-1) + query << "&"; + } - perform (); + query.flush (); + + return query.str (); + } + + void ftp_file_or_dir_action (const std::string& file_or_dir, + const std::string& action) + { + struct curl_slist *slist = 0; - if (! good ()) - return; + octave::unwind_protect frame; + + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = action + " " + file_or_dir; + + slist = curl_slist_append (slist, cmd.c_str ()); - SETOPT (CURLOPT_POSTQUOTE, 0); - } -}; + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + }; #undef SETOPT @@ -775,16 +777,18 @@ # define REP_CLASS base_url_transfer #endif -url_transfer::url_transfer (void) : rep (new REP_CLASS ()) -{ } + url_transfer::url_transfer (void) : rep (new REP_CLASS ()) + { } -url_transfer::url_transfer (const std::string& host, const std::string& user, - const std::string& passwd, std::ostream& os) - : rep (new REP_CLASS (host, user, passwd, os)) -{ } + url_transfer::url_transfer (const std::string& host, const std::string& user, + const std::string& passwd, std::ostream& os) + : rep (new REP_CLASS (host, user, passwd, os)) + { } -url_transfer::url_transfer (const std::string& url, std::ostream& os) - : rep (new REP_CLASS (url, os)) -{ } + url_transfer::url_transfer (const std::string& url, std::ostream& os) + : rep (new REP_CLASS (url, os)) + { } #undef REP_CLASS + +} diff -r f4d7d0eb5b0c -r e1be0b36fbed liboctave/util/url-transfer.h --- a/liboctave/util/url-transfer.h Thu May 19 12:56:47 2016 -0400 +++ b/liboctave/util/url-transfer.h Thu May 19 13:01:29 2016 -0400 @@ -33,257 +33,270 @@ #include #include -class -OCTAVE_API -base_url_transfer +namespace octave { -private: - - static void delete_file (const std::string& file); - - static void reset_path (base_url_transfer *curl_xfer) + class + OCTAVE_API + base_url_transfer { - curl_xfer->cwd (".."); - } + private: -public: + static void delete_file (const std::string& file); - friend class url_transfer; + static void reset_path (base_url_transfer *curl_xfer) + { + curl_xfer->cwd (".."); + } - base_url_transfer (void) - : count (1), host_or_url (), valid (false), ftp (false), + public: + + friend class url_transfer; + + base_url_transfer (void) + : count (1), host_or_url (), valid (false), ftp (false), ascii_mode (false), ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&std::cout) - { } + { } - base_url_transfer (const std::string& host, - const std::string& /* user_arg */, - const std::string& /* passwd */, - std::ostream& os) - : count (1), host_or_url (host), valid (false), ftp (true), + base_url_transfer (const std::string& host, + const std::string& /* user_arg */, + const std::string& /* passwd */, + std::ostream& os) + : count (1), host_or_url (host), valid (false), ftp (true), ascii_mode (false), ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&os) { } - base_url_transfer (const std::string& url, std::ostream& os) - : count (1), host_or_url (url), valid (false), ftp (false), + base_url_transfer (const std::string& url, std::ostream& os) + : count (1), host_or_url (url), valid (false), ftp (false), ascii_mode (false), ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&os) { } - virtual ~base_url_transfer (void) { } + virtual ~base_url_transfer (void) { } - bool is_valid (void) const { return valid; } - - bool good (void) const { return valid && ok; } + bool is_valid (void) const { return valid; } - virtual void perform (void) { } - - virtual std::string lasterror (void) const { return errmsg; } + bool good (void) const { return valid && ok; } - virtual std::ostream& set_ostream (std::ostream& /* os */) - { - return *curr_ostream; - } + virtual void perform (void) { } + + virtual std::string lasterror (void) const { return errmsg; } - virtual std::istream& set_istream (std::istream& /* is */) - { - return *curr_istream; - } - - virtual void ascii (void) { } + virtual std::ostream& set_ostream (std::ostream& /* os */) + { + return *curr_ostream; + } - virtual void binary (void) { } - - bool is_ascii (void) const { return ascii_mode; } + virtual std::istream& set_istream (std::istream& /* is */) + { + return *curr_istream; + } - bool is_binary (void) const { return ! ascii_mode; } + virtual void ascii (void) { } - virtual void cwd (const std::string& /* path */) { } + virtual void binary (void) { } + + bool is_ascii (void) const { return ascii_mode; } - virtual void del (const std::string& /* file */) { } + bool is_binary (void) const { return ! ascii_mode; } - virtual void rmdir (const std::string& /* path */) { } + virtual void cwd (const std::string& /* path */) { } - virtual void mkdir (const std::string& /* path */) { } + virtual void del (const std::string& /* file */) { } - virtual void rename (const std::string& /* oldname */, - const std::string& /* newname */) { } + virtual void rmdir (const std::string& /* path */) { } - virtual void put (const std::string& /* file */, - std::istream& /* is */) { } + virtual void mkdir (const std::string& /* path */) { } - virtual void get (const std::string& /* file */, - std::ostream& /* os */) { } + virtual void rename (const std::string& /* oldname */, + const std::string& /* newname */) { } - void mget_directory (const std::string& directory, - const std::string& target); + virtual void put (const std::string& /* file */, + std::istream& /* is */) { } - string_vector mput_directory (const std::string& base, - const std::string& directory); + virtual void get (const std::string& /* file */, + std::ostream& /* os */) { } - virtual void dir (void) { } - - virtual string_vector list (void) { return string_vector (); } + void mget_directory (const std::string& directory, + const std::string& target); - virtual void get_fileinfo (const std::string& /* filename */, - double& /* filesize */, - time_t& /* filetime */, - bool& /* fileisdir */) { } + string_vector mput_directory (const std::string& base, + const std::string& directory); + + virtual void dir (void) { } + + virtual string_vector list (void) { return string_vector (); } - virtual std::string pwd (void) { return ""; } + virtual void get_fileinfo (const std::string& /* filename */, + double& /* filesize */, + time_t& /* filetime */, + bool& /* fileisdir */) { } - virtual void http_get (const Array& /* param */) { } - - virtual void http_post (const Array& /* param */) { } + virtual std::string pwd (void) { return ""; } - virtual void http_action (const Array& /* param */, - const std::string& /* action */) { } + virtual void http_get (const Array& /* param */) { } -protected: + virtual void http_post (const Array& /* param */) { } - // Reference count. - octave_refcount count; + virtual void http_action (const Array& /* param */, + const std::string& /* action */) { } - // Host for ftp transfers or full URL for http requests. - std::string host_or_url; - bool valid; - bool ftp; - bool ascii_mode; - bool ok; - std::string errmsg; - std::istream *curr_istream; - std::ostream *curr_ostream; + protected: + + // Reference count. + octave_refcount count; -private: - - // No copying! - - base_url_transfer (const base_url_transfer&); + // Host for ftp transfers or full URL for http requests. + std::string host_or_url; + bool valid; + bool ftp; + bool ascii_mode; + bool ok; + std::string errmsg; + std::istream *curr_istream; + std::ostream *curr_ostream; - base_url_transfer& operator = (const base_url_transfer&); -}; + private: + + // No copying! -class -OCTAVE_API -url_transfer -{ -public: + base_url_transfer (const base_url_transfer&); - url_transfer (void); - - url_transfer (const std::string& host, const std::string& user, - const std::string& passwd, std::ostream& os); + base_url_transfer& operator = (const base_url_transfer&); + }; - url_transfer (const std::string& url, std::ostream& os); + class + OCTAVE_API + url_transfer + { + public: - url_transfer (const url_transfer& h) : rep (h.rep) - { - rep->count++; - } + url_transfer (void); - ~url_transfer (void) - { - if (--rep->count == 0) - delete rep; - } + url_transfer (const std::string& host, const std::string& user, + const std::string& passwd, std::ostream& os); + + url_transfer (const std::string& url, std::ostream& os); - url_transfer& operator = (const url_transfer& h) - { - if (this != &h) + url_transfer (const url_transfer& h) : rep (h.rep) + { + rep->count++; + } + + ~url_transfer (void) { if (--rep->count == 0) delete rep; + } - rep = h.rep; - rep->count++; + url_transfer& operator = (const url_transfer& h) + { + if (this != &h) + { + if (--rep->count == 0) + delete rep; + + rep = h.rep; + rep->count++; + } + + return *this; } - return *this; - } + bool is_valid (void) const { return rep->is_valid (); } + + bool good (void) const { return rep->good (); } - bool is_valid (void) const { return rep->is_valid (); } + std::string lasterror (void) const { return rep->lasterror (); } - bool good (void) const { return rep->good (); } - - std::string lasterror (void) const { return rep->lasterror (); } + std::ostream& set_ostream (std::ostream& os) + { + return rep->set_ostream (os); + } - std::ostream& set_ostream (std::ostream& os) - { - return rep->set_ostream (os); - } + std::istream& set_istream (std::istream& is) + { + return rep->set_istream (is); + } - std::istream& set_istream (std::istream& is) - { - return rep->set_istream (is); - } + void ascii (void) { rep->ascii (); } + + void binary (void) { rep->binary (); } + + bool is_ascii (void) const { return rep->is_ascii (); } - void ascii (void) { rep->ascii (); } + bool is_binary (void) const { return rep->is_binary (); } - void binary (void) { rep->binary (); } + void cwd (const std::string& path) { rep->cwd (path); } - bool is_ascii (void) const { return rep->is_ascii (); } + void del (const std::string& file) { rep->del (file); } - bool is_binary (void) const { return rep->is_binary (); } + void rmdir (const std::string& path) { rep->rmdir (path); } - void cwd (const std::string& path) { rep->cwd (path); } + void mkdir (const std::string& path) { rep->mkdir (path); } - void del (const std::string& file) { rep->del (file); } - - void rmdir (const std::string& path) { rep->rmdir (path); } + void rename (const std::string& oldname, const std::string& newname) + { + rep->rename (oldname, newname); + } - void mkdir (const std::string& path) { rep->mkdir (path); } + void put (const std::string& file, std::istream& is) + { + rep->put (file, is); + } - void rename (const std::string& oldname, const std::string& newname) - { - rep->rename (oldname, newname); - } + void get (const std::string& file, std::ostream& os) + { + rep->get (file, os); + } - void put (const std::string& file, std::istream& is) - { - rep->put (file, is); - } + void mget_directory (const std::string& directory, + const std::string& target) + { + rep->mget_directory (directory, target); + } - void get (const std::string& file, std::ostream& os) - { - rep->get (file, os); - } + string_vector mput_directory (const std::string& base, + const std::string& directory) + { + return rep->mput_directory (base, directory); + } - void mget_directory (const std::string& directory, - const std::string& target) - { - rep->mget_directory (directory, target); - } + void dir (void) { rep->dir (); } + + string_vector list (void) { return rep->list (); } - string_vector mput_directory (const std::string& base, - const std::string& directory) - { - return rep->mput_directory (base, directory); - } + void get_fileinfo (const std::string& filename, double& filesize, + time_t& filetime, bool& fileisdir) + { + rep->get_fileinfo (filename, filesize, filetime, fileisdir); + } - void dir (void) { rep->dir (); } + std::string pwd (void) { return rep->pwd (); } - string_vector list (void) { return rep->list (); } + void http_get (const Array& param) { rep->http_get (param); } + + void http_post (const Array& param) { rep->http_post (param); } - void get_fileinfo (const std::string& filename, double& filesize, - time_t& filetime, bool& fileisdir) - { - rep->get_fileinfo (filename, filesize, filetime, fileisdir); - } + void http_action (const Array& param, + const std::string& action) + { + rep->http_action (param, action); + } - std::string pwd (void) { return rep->pwd (); } - - void http_get (const Array& param) { rep->http_get (param); } + private: - void http_post (const Array& param) { rep->http_post (param); } + base_url_transfer *rep; + }; +} + +#if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS) - void http_action (const Array& param, - const std::string& action) - { - rep->http_action (param, action); - } +OCTAVE_DEPRECATED ("use octave::base_url_transfer instead") +typedef octave::base_url_transfer base_url_transfer; -private: - - base_url_transfer *rep; -}; +OCTAVE_DEPRECATED ("use octave::url_transfer instead") +typedef octave::url_transfer url_transfer; #endif + +#endif