GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
urlwrite.cc
Go to the documentation of this file.
1 // urlwrite and urlread, a curl front-end for octave
2 /*
3 
4 Copyright (C) 2006-2017 Alexander Barth
5 Copyright (C) 2009 David Bateman
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 // Author: Alexander Barth <abarth@marine.usf.edu>
26 // Adapted-By: jwe
27 
28 #if defined (HAVE_CONFIG_H)
29 # include "config.h"
30 #endif
31 
32 #include <string>
33 #include <fstream>
34 #include <iomanip>
35 #include <iostream>
36 
37 #include "dir-ops.h"
38 #include "file-ops.h"
39 #include "file-stat.h"
40 #include "oct-env.h"
41 #include "oct-handle.h"
42 #include "glob-match.h"
43 #include "singleton-cleanup.h"
44 #include "url-transfer.h"
45 
46 #include "defun.h"
47 #include "error.h"
48 #include "ovl.h"
49 #include "ov-cell.h"
50 #include "pager.h"
51 #include "oct-map.h"
52 #include "oct-refcount.h"
53 #include "unwind-prot.h"
54 
55 static void
57 {
58  octave::sys::unlink (file);
59 }
60 
62 
64 {
65 protected:
66 
67  ch_manager (void)
68  : handle_map (), handle_free_list (),
69  next_handle (-1.0 - (rand () + 1.0) / (RAND_MAX + 2.0)) { }
70 
71 public:
72 
73  static void create_instance (void);
74 
75  static bool instance_ok (void)
76  {
77  bool retval = true;
78 
79  if (! instance)
80  create_instance ();
81 
82  if (! instance)
83  error ("unable to create ch_manager!");
84 
85  return retval;
86  }
87 
88  static void cleanup_instance (void) { delete instance; instance = 0; }
89 
90  static curl_handle get_handle (void)
91  {
92  return instance_ok () ? instance->do_get_handle () : curl_handle ();
93  }
94 
95  static void free (const curl_handle& h)
96  {
97  if (instance_ok ())
98  instance->do_free (h);
99  }
100 
101  static curl_handle lookup (double val)
102  {
103  return instance_ok () ? instance->do_lookup (val) : curl_handle ();
104  }
105 
107  {
108  return val.is_real_scalar () ? lookup (val.double_value ())
109  : curl_handle ();
110  }
111 
113  {
114  return get_object (lookup (val));
115  }
116 
118  {
119  return get_object (lookup (val));
120  }
121 
123  {
124  return instance_ok () ? instance->do_get_object (h) : octave::url_transfer ();
125  }
126 
128  const std::string& user,
129  const std::string& passwd,
130  std::ostream& os)
131  {
132  return instance_ok ()
133  ? instance->do_make_curl_handle (host, user, passwd, os)
134  : curl_handle ();
135  }
136 
137  static Matrix handle_list (void)
138  {
139  return instance_ok () ? instance->do_handle_list () : Matrix ();
140  }
141 
142 private:
143 
145 
146  typedef std::map<curl_handle, octave::url_transfer>::iterator iterator;
147  typedef std::map<curl_handle, octave::url_transfer>::const_iterator const_iterator;
148 
149  typedef std::set<curl_handle>::iterator free_list_iterator;
150  typedef std::set<curl_handle>::const_iterator const_free_list_iterator;
151 
152  // A map of handles to curl objects.
153  std::map<curl_handle, octave::url_transfer> handle_map;
154 
155  // The available curl handles.
156  std::set<curl_handle> handle_free_list;
157 
158  // The next handle available if handle_free_list is empty.
159  double next_handle;
160 
161  curl_handle do_get_handle (void);
162 
163  void do_free (const curl_handle& h);
164 
166  {
167  iterator p = (octave::math::isnan (val) ? handle_map.end () : handle_map.find (val));
168 
169  return (p != handle_map.end ()) ? p->first : curl_handle ();
170  }
171 
173  {
174  iterator p = (h.ok () ? handle_map.find (h) : handle_map.end ());
175 
176  return (p != handle_map.end ()) ? p->second : octave::url_transfer ();
177  }
178 
180  const std::string& user,
181  const std::string& passwd,
182  std::ostream& os)
183  {
184  curl_handle h = get_handle ();
185 
186  octave::url_transfer obj (host, user, passwd, os);
187 
188  if (! obj.is_valid ())
189  error ("support for URL transfers was disabled when Octave was built");
190 
191  handle_map[h] = obj;
192 
193  return h;
194  }
195 
197  {
198  Matrix retval (1, handle_map.size ());
199 
200  octave_idx_type i = 0;
201  for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
202  {
203  curl_handle h = p->first;
204 
205  retval(i++) = h.value ();
206  }
207 
208  return retval;
209  }
210 };
211 
212 void
214 {
215  instance = new ch_manager ();
216 
217  if (instance)
219 }
220 
221 static double
223 {
224  static double maxrand = RAND_MAX + 2.0;
225 
226  return (rand () + 1.0) / maxrand;
227 }
228 
231 {
233 
234  // Curl handles are negative integers plus some random fractional
235  // part. To avoid running out of integers, we recycle the integer
236  // part but tack on a new random part each time.
237 
239 
240  if (p != handle_free_list.end ())
241  {
242  retval = *p;
243  handle_free_list.erase (p);
244  }
245  else
246  {
247  retval = curl_handle (next_handle);
248 
250  }
251 
252  return retval;
253 }
254 
255 void
257 {
258  if (h.ok ())
259  {
260  iterator p = handle_map.find (h);
261 
262  if (p == handle_map.end ())
263  error ("ch_manager::free: invalid object %g", h.value ());
264 
265  // Curl handles are negative integers plus some random
266  // fractional part. To avoid running out of integers, we
267  // recycle the integer part but tack on a new random part
268  // each time.
269 
270  handle_map.erase (p);
271 
272  if (h.value () < 0)
273  handle_free_list.insert
274  (std::ceil (h.value ()) - make_handle_fraction ());
275  }
276 }
277 
279 
280 DEFUN (urlwrite, args, nargout,
281  doc: /* -*- texinfo -*-
282 @deftypefn {} {} urlwrite (@var{url}, @var{localfile})
283 @deftypefnx {} {@var{f} =} urlwrite (@var{url}, @var{localfile})
284 @deftypefnx {} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})
285 @deftypefnx {} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})
286 Download a remote file specified by its @var{url} and save it as
287 @var{localfile}.
288 
289 For example:
290 
291 @example
292 @group
293 urlwrite ("ftp://ftp.octave.org/pub/README",
294  "README.txt");
295 @end group
296 @end example
297 
298 The full path of the downloaded file is returned in @var{f}.
299 
300 The variable @var{success} is 1 if the download was successful,
301 otherwise it is 0 in which case @var{message} contains an error message.
302 
303 If no output argument is specified and an error occurs, then the error is
304 signaled through Octave's error handling mechanism.
305 
306 This function uses libcurl. Curl supports, among others, the HTTP, FTP, and
307 FILE protocols. Username and password may be specified in the URL, for
308 example:
309 
310 @example
311 @group
312 urlwrite ("http://username:password@@example.com/file.txt",
313  "file.txt");
314 @end group
315 @end example
316 
317 GET and POST requests can be specified by @var{method} and @var{param}.
318 The parameter @var{method} is either @samp{get} or @samp{post} and
319 @var{param} is a cell array of parameter and value pairs.
320 For example:
321 
322 @example
323 @group
324 urlwrite ("http://www.google.com/search", "search.html",
325  "get", @{"query", "octave"@});
326 @end group
327 @end example
328 @seealso{urlread}
329 @end deftypefn */)
330 {
331  int nargin = args.length ();
332 
333  // verify arguments
334  if (nargin != 2 && nargin != 4)
335  print_usage ();
336 
337  std::string url = args(0).xstring_value ("urlwrite: URL must be a string");
338 
339  // name to store the file if download is successful
340  std::string filename = args(1).xstring_value ("urlwrite: LOCALFILE must be a string");
341 
344 
345  if (nargin == 4)
346  {
347  method = args(2).xstring_value ("urlwrite: METHOD must be a string");
348 
349  if (method != "get" && method != "post")
350  error ("urlwrite: METHOD must be \"get\" or \"post\"");
351 
352  param = args(3).xcellstr_value ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of strings");
353 
354  if (param.numel () % 2 == 1)
355  error ("urlwrite: number of elements in PARAM must be even");
356  }
357 
358  // The file should only be deleted if it doesn't initially exist, we
359  // create it, and the download fails. We use unwind_protect to do
360  // it so that the deletion happens no matter how we exit the function.
361 
362  octave::sys::file_stat fs (filename);
363 
364  std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary);
365 
366  if (! ofile.is_open ())
367  error ("urlwrite: unable to open file");
368 
370 
371  frame.add_fcn (delete_file, filename);
372 
374 
376 
377  if (! curl.is_valid ())
378  error ("support for URL transfers was disabled when Octave was built");
379 
380  curl.http_action (param, method);
381 
382  ofile.close ();
383 
384  if (curl.good ())
385  frame.discard ();
386 
387  if (nargout > 0)
388  {
389  if (curl.good ())
390  retval = ovl (octave::sys::env::make_absolute (filename), true, "");
391  else
392  retval = ovl ("", false, curl.lasterror ());
393  }
394 
395  if (nargout < 2 && ! curl.good ())
396  error ("urlwrite: %s", curl.lasterror ().c_str ());
397 
398  return retval;
399 }
400 
401 DEFUN (urlread, args, nargout,
402  doc: /* -*- texinfo -*-
403 @deftypefn {} {@var{s} =} urlread (@var{url})
404 @deftypefnx {} {[@var{s}, @var{success}] =} urlread (@var{url})
405 @deftypefnx {} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})
406 @deftypefnx {} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})
407 Download a remote file specified by its @var{url} and return its content
408 in string @var{s}.
409 
410 For example:
411 
412 @example
413 s = urlread ("ftp://ftp.octave.org/pub/README");
414 @end example
415 
416 The variable @var{success} is 1 if the download was successful,
417 otherwise it is 0 in which case @var{message} contains an error
418 message.
419 
420 If no output argument is specified and an error occurs, then the error is
421 signaled through Octave's error handling mechanism.
422 
423 This function uses libcurl. Curl supports, among others, the HTTP, FTP, and
424 FILE protocols. Username and password may be specified in the URL@. For
425 example:
426 
427 @example
428 s = urlread ("http://user:password@@example.com/file.txt");
429 @end example
430 
431 GET and POST requests can be specified by @var{method} and @var{param}.
432 The parameter @var{method} is either @samp{get} or @samp{post} and
433 @var{param} is a cell array of parameter and value pairs.
434 For example:
435 
436 @example
437 @group
438 s = urlread ("http://www.google.com/search", "get",
439  @{"query", "octave"@});
440 @end group
441 @end example
442 @seealso{urlwrite}
443 @end deftypefn */)
444 {
445  int nargin = args.length ();
446 
447  // verify arguments
448  if (nargin != 1 && nargin != 3)
449  print_usage ();
450 
451  std::string url = args(0).xstring_value ("urlread: URL must be a string");
452 
455 
456  if (nargin == 3)
457  {
458  method = args(1).xstring_value ("urlread: METHOD must be a string");
459 
460  if (method != "get" && method != "post")
461  error ("urlread: METHOD must be \"get\" or \"post\"");
462 
463  param = args(2).xcellstr_value ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of strings");
464 
465  if (param.numel () % 2 == 1)
466  error ("urlread: number of elements in PARAM must be even");
467  }
468 
469  std::ostringstream buf;
470 
471  octave::url_transfer curl = octave::url_transfer (url, buf);
472 
473  if (! curl.is_valid ())
474  error ("support for URL transfers was disabled when Octave was built");
475 
476  curl.http_action (param, method);
477 
479 
480  if (nargout > 0)
481  {
482  // Return empty string if no error occurred.
483  retval = ovl (buf.str (), curl.good (),
484  curl.good () ? "" : curl.lasterror ());
485  }
486 
487  if (nargout < 2 && ! curl.good ())
488  error ("urlread: %s", curl.lasterror ().c_str ());
489 
490  return retval;
491 }
492 
493 DEFUN (__ftp__, args, ,
494  doc: /* -*- texinfo -*-
495 @deftypefn {} {@var{handle} =} __ftp__ (@var{host})
496 @deftypefnx {} {@var{handle} =} __ftp__ (@var{host}, @var{username}, @var{password})
497 Undocumented internal function
498 @end deftypefn */)
499 {
500  int nargin = args.length ();
501 
502  if (nargin < 1 || nargin > 3)
503  print_usage ();
504 
505  std::string host = args(0).xstring_value ("__ftp__: HOST must be a string");
506 
507  std::string user = (nargin > 1)
508  ? args(1).xstring_value ("__ftp__: USER must be a string")
509  : std::string ("anonymous");
510 
511  std::string passwd = (nargin > 2)
512  ? args(2).xstring_value ("__ftp__: PASSWD must be a string")
513  : "";
514 
515  curl_handle ch
516  = ch_manager::make_curl_handle (host, user, passwd, octave_stdout);
517 
518  return ovl (ch.value ());
519 }
520 
521 DEFUN (__ftp_pwd__, args, ,
522  doc: /* -*- texinfo -*-
523 @deftypefn {} {} __ftp_pwd__ (@var{handle})
524 Undocumented internal function
525 @end deftypefn */)
526 {
527  if (args.length () != 1)
528  error ("__ftp_pwd__: incorrect number of arguments");
529 
531 
532  if (! curl.is_valid ())
533  error ("__ftp_pwd__: invalid ftp handle");
534 
535  return ovl (curl.pwd ());
536 }
537 
538 DEFUN (__ftp_cwd__, args, ,
539  doc: /* -*- texinfo -*-
540 @deftypefn {} {} __ftp_cwd__ (@var{handle}, @var{path})
541 Undocumented internal function
542 @end deftypefn */)
543 {
544  int nargin = args.length ();
545 
546  if (nargin != 1 && nargin != 2)
547  error ("__ftp_cwd__: incorrect number of arguments");
548 
549  std::string path = "";
550  if (nargin > 1)
551  path = args(1).xstring_value ("__ftp_cwd__: PATH must be a string");
552 
554 
555  if (! curl.is_valid ())
556  error ("__ftp_cwd__: invalid ftp handle");
557 
558  curl.cwd (path);
559 
560  return ovl ();
561 }
562 
563 DEFUN (__ftp_dir__, args, nargout,
564  doc: /* -*- texinfo -*-
565 @deftypefn {} {} __ftp_dir__ (@var{handle})
566 Undocumented internal function
567 @end deftypefn */)
568 {
569  if (args.length () != 1)
570  error ("__ftp_dir__: incorrect number of arguments");
571 
573 
574  if (! curl.is_valid ())
575  error ("__ftp_dir__: invalid ftp handle");
576 
578 
579  if (nargout == 0)
580  curl.dir ();
581  else
582  {
583  string_vector sv = curl.list ();
584  octave_idx_type n = sv.numel ();
585 
586  if (n == 0)
587  {
588  string_vector flds (5);
589 
590  flds(0) = "name";
591  flds(1) = "date";
592  flds(2) = "bytes";
593  flds(3) = "isdir";
594  flds(4) = "datenum";
595 
596  retval = octave_map (flds);
597  }
598  else
599  {
600  octave_map st;
601 
602  Cell filectime (dim_vector (n, 1));
603  Cell filesize (dim_vector (n, 1));
604  Cell fileisdir (dim_vector (n, 1));
605  Cell filedatenum (dim_vector (n, 1));
606 
607  st.assign ("name", Cell (sv));
608 
609  for (octave_idx_type i = 0; i < n; i++)
610  {
611  time_t ftime;
612  bool fisdir;
613  double fsize;
614 
615  curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
616 
617  fileisdir (i) = fisdir;
618  filectime (i) = ctime (&ftime);
619  filesize (i) = fsize;
620  filedatenum (i) = double (ftime);
621  }
622 
623  st.assign ("date", filectime);
624  st.assign ("bytes", filesize);
625  st.assign ("isdir", fileisdir);
626  st.assign ("datenum", filedatenum);
627 
628  retval = st;
629  }
630  }
631 
632  return retval;
633 }
634 
635 DEFUN (__ftp_ascii__, args, ,
636  doc: /* -*- texinfo -*-
637 @deftypefn {} {} __ftp_ascii__ (@var{handle})
638 Undocumented internal function
639 @end deftypefn */)
640 {
641  if (args.length () != 1)
642  error ("__ftp_ascii__: incorrect number of arguments");
643 
645 
646  if (! curl.is_valid ())
647  error ("__ftp_ascii__: invalid ftp handle");
648 
649  curl.ascii ();
650 
651  return ovl ();
652 }
653 
654 DEFUN (__ftp_binary__, args, ,
655  doc: /* -*- texinfo -*-
656 @deftypefn {} {} __ftp_binary__ (@var{handle})
657 Undocumented internal function
658 @end deftypefn */)
659 {
660  if (args.length () != 1)
661  error ("__ftp_binary__: incorrect number of arguments");
662 
664 
665  if (! curl.is_valid ())
666  error ("__ftp_binary__: invalid ftp handle");
667 
668  curl.binary ();
669 
670  return ovl ();
671 }
672 
673 DEFUN (__ftp_close__, args, ,
674  doc: /* -*- texinfo -*-
675 @deftypefn {} {} __ftp_close__ (@var{handle})
676 Undocumented internal function
677 @end deftypefn */)
678 {
679  if (args.length () != 1)
680  error ("__ftp_close__: incorrect number of arguments");
681 
683 
684  if (! h.ok ())
685  error ("__ftp_close__: invalid ftp handle");
686 
687  ch_manager::free (h);
688 
689  return ovl ();
690 }
691 
692 DEFUN (__ftp_mode__, args, ,
693  doc: /* -*- texinfo -*-
694 @deftypefn {} {} __ftp_mode__ (@var{handle})
695 Undocumented internal function
696 @end deftypefn */)
697 {
698  if (args.length () != 1)
699  error ("__ftp_mode__: incorrect number of arguments");
700 
702 
703  if (! curl.is_valid ())
704  error ("__ftp_binary__: invalid ftp handle");
705 
706  return ovl (curl.is_ascii () ? "ascii" : "binary");
707 }
708 
709 DEFUN (__ftp_delete__, args, ,
710  doc: /* -*- texinfo -*-
711 @deftypefn {} {} __ftp_delete__ (@var{handle}, @var{path})
712 Undocumented internal function
713 @end deftypefn */)
714 {
715  if (args.length () != 2)
716  error ("__ftp_delete__: incorrect number of arguments");
717 
718  std::string file = args(1).xstring_value ("__ftp_delete__: FILE must be a string");
719 
721 
722  if (! curl.is_valid ())
723  error ("__ftp_delete__: invalid ftp handle");
724 
725  curl.del (file);
726 
727  return ovl ();
728 }
729 
730 DEFUN (__ftp_rmdir__, args, ,
731  doc: /* -*- texinfo -*-
732 @deftypefn {} {} __ftp_rmdir__ (@var{handle}, @var{path})
733 Undocumented internal function
734 @end deftypefn */)
735 {
736  if (args.length () != 2)
737  error ("__ftp_rmdir__: incorrect number of arguments");
738 
739  std::string dir = args(1).xstring_value ("__ftp_rmdir__: DIR must be a string");
740 
742 
743  if (! curl.is_valid ())
744  error ("__ftp_rmdir__: invalid ftp handle");
745 
746  curl.rmdir (dir);
747 
748  return ovl ();
749 }
750 
751 DEFUN (__ftp_mkdir__, args, ,
752  doc: /* -*- texinfo -*-
753 @deftypefn {} {} __ftp_mkdir__ (@var{handle}, @var{path})
754 Undocumented internal function
755 @end deftypefn */)
756 {
757  if (args.length () != 2)
758  error ("__ftp_mkdir__: incorrect number of arguments");
759 
760  std::string dir = args(1).xstring_value ("__ftp_mkdir__: DIR must be a string");
761 
763 
764  if (! curl.is_valid ())
765  error ("__ftp_mkdir__: invalid ftp handle");
766 
767  curl.mkdir (dir);
768 
769  return ovl ();
770 }
771 
772 DEFUN (__ftp_rename__, args, ,
773  doc: /* -*- texinfo -*-
774 @deftypefn {} {} __ftp_rename__ (@var{handle}, @var{path})
775 Undocumented internal function
776 @end deftypefn */)
777 {
778  if (args.length () != 3)
779  error ("__ftp_rename__: incorrect number of arguments");
780 
781  std::string oldname = args(1).xstring_value ("__ftp_rename__: OLDNAME must be a string");
782  std::string newname = args(2).xstring_value ("__ftp_rename__: NEWNAME must be a string");
783 
785 
786  if (curl.is_valid ())
787  error ("__ftp_rename__: invalid ftp handle");
788 
789  curl.rename (oldname, newname);
790 
791  return ovl ();
792 }
793 
794 DEFUN (__ftp_mput__, args, nargout,
795  doc: /* -*- texinfo -*-
796 @deftypefn {} {} __ftp_mput__ (@var{handle}, @var{files})
797 Undocumented internal function
798 @end deftypefn */)
799 {
800  if (args.length () != 2)
801  error ("__ftp_mput__: incorrect number of arguments");
802 
803  std::string pat = args(1).xstring_value ("__ftp_mput__: PATTERN must be a string");
804 
806 
807  if (! curl.is_valid ())
808  error ("__ftp_mput__: invalid ftp handle");
809 
810  string_vector file_list;
811 
813  string_vector files = pattern.glob ();
814 
815  for (octave_idx_type i = 0; i < files.numel (); i++)
816  {
817  std::string file = files(i);
818 
819  octave::sys::file_stat fs (file);
820 
821  if (! fs.exists ())
822  error ("__ftp__mput: file does not exist");
823 
824  if (fs.is_dir ())
825  {
826  file_list.append (curl.mput_directory ("", file));
827 
828  if (! curl.good ())
829  error ("__ftp_mput__: %s", curl.lasterror ().c_str ());
830  }
831  else
832  {
833  // FIXME: Does ascii mode need to be flagged here?
834  std::ifstream ifile (file.c_str (), std::ios::in | std::ios::binary);
835 
836  if (! ifile.is_open ())
837  error ("__ftp_mput__: unable to open file");
838 
839  curl.put (file, ifile);
840 
841  ifile.close ();
842 
843  if (! curl.good ())
844  error ("__ftp_mput__: %s", curl.lasterror ().c_str ());
845 
846  file_list.append (file);
847  }
848  }
849 
850  if (nargout > 0)
851  return ovl (file_list);
852  else
853  return ovl ();
854 }
855 
856 DEFUN (__ftp_mget__, args, ,
857  doc: /* -*- texinfo -*-
858 @deftypefn {} {} __ftp_mget__ (@var{handle}, @var{pattern})
859 @deftypefnx {} {} __ftp_mget__ (@var{handle}, @var{pattern}, @var{target})
860 Undocumented internal function
861 @end deftypefn */)
862 {
863  int nargin = args.length ();
864 
865  if (nargin != 2 && nargin != 3)
866  error ("__ftp_mget__: incorrect number of arguments");
867 
868  std::string file = args(1).xstring_value ("__ftp_mget__: PATTERN must be a string");
869 
870  std::string target;
871 
872  if (nargin == 3 && ! args(2).is_empty ())
873  target = args(2).xstring_value ("__ftp_mget__: TARGET must be a string") + octave::sys::file_ops::dir_sep_str ();
874 
876 
877  if (! curl.is_valid ())
878  error ("__ftp_mget__: invalid ftp handle");
879 
880  string_vector sv = curl.list ();
881  octave_idx_type n = 0;
882  glob_match pattern (file);
883 
884  for (octave_idx_type i = 0; i < sv.numel (); i++)
885  {
886  if (pattern.match (sv(i)))
887  {
888  n++;
889 
890  time_t ftime;
891  bool fisdir;
892  double fsize;
893 
894  curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
895 
896  if (fisdir)
897  curl.mget_directory (sv(i), target);
898  else
899  {
900  std::ofstream ofile ((target + sv(i)).c_str (),
901  std::ios::out |
902  std::ios::binary);
903 
904  if (! ofile.is_open ())
905  error ("__ftp_mget__: unable to open file");
906 
908 
909  frame.add_fcn (delete_file, target + sv(i));
910 
911  curl.get (sv(i), ofile);
912 
913  ofile.close ();
914 
915  if (curl.good ())
916  frame.discard ();
917  }
918 
919  if (! curl.good ())
920  error ("__ftp_mget__: %s", curl.lasterror().c_str());
921  }
922  }
923 
924  if (n == 0)
925  error ("__ftp_mget__: file not found");
926 
927  return ovl ();
928 }
static std::string dir_sep_str(void)
Definition: file-ops.h:80
void discard(size_t num)
Definition: Cell.h:37
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:120
string_vector list(void)
Definition: url-transfer.h:265
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:347
static octave::url_transfer get_object(const octave_value &val)
Definition: urlwrite.cc:117
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
int unlink(const std::string &name)
Definition: file-ops.cc:648
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
void mkdir(const std::string &path)
Definition: url-transfer.h:234
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
curl_handle do_lookup(double val)
Definition: urlwrite.cc:165
static ch_manager * instance
Definition: urlwrite.cc:144
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
void rename(const std::string &oldname, const std::string &newname)
Definition: url-transfer.h:236
bool is_ascii(void) const
Definition: url-transfer.h:224
bool isnan(double x)
Definition: lo-mappers.cc:347
bool ok(void) const
Definition: oct-handle.h:109
bool is_valid(void) const
Definition: url-transfer.h:204
static Matrix handle_list(void)
Definition: urlwrite.cc:137
double ceil(double x)
Definition: lo-mappers.h:138
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
std::string filename
Definition: urlwrite.cc:340
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
std::map< curl_handle, octave::url_transfer >::iterator iterator
Definition: urlwrite.cc:146
static octave::url_transfer get_object(double val)
Definition: urlwrite.cc:112
void put(const std::string &file, std::istream &is)
Definition: url-transfer.h:241
static double make_handle_fraction(void)
Definition: urlwrite.cc:222
curl_handle do_get_handle(void)
Definition: urlwrite.cc:230
static std::string tilde_expand(const std::string &)
Definition: file-ops.cc:301
octave_handle curl_handle
Definition: urlwrite.cc:61
ch_manager(void)
Definition: urlwrite.cc:67
std::set< curl_handle >::const_iterator const_free_list_iterator
Definition: urlwrite.cc:150
void mget_directory(const std::string &directory, const std::string &target)
Definition: url-transfer.h:251
std::map< curl_handle, octave::url_transfer >::const_iterator const_iterator
Definition: urlwrite.cc:147
static octave::url_transfer get_object(const curl_handle &h)
Definition: urlwrite.cc:122
JNIEnv void * args
Definition: ov-java.cc:67
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:129
bool is_dir(void) const
Definition: file-stat.cc:57
double h
Definition: graphics.cc:11205
static curl_handle make_curl_handle(const std::string &host, const std::string &user, const std::string &passwd, std::ostream &os)
Definition: urlwrite.cc:127
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
void add_fcn(void(*fcn)(void))
#define OCTINTERP_API
Definition: mexproto.h:69
double value(void) const
Definition: oct-handle.h:74
static bool instance_ok(void)
Definition: urlwrite.cc:75
bool is_real_scalar(void) const
Definition: ov.h:551
double next_handle
Definition: urlwrite.cc:159
string_vector mput_directory(const std::string &base, const std::string &directory)
Definition: url-transfer.h:257
static void create_instance(void)
Definition: urlwrite.cc:213
static void add(fptr f)
std::string lasterror(void) const
Definition: url-transfer.h:208
std::set< curl_handle > handle_free_list
Definition: urlwrite.cc:156
int nargin
Definition: graphics.cc:10115
static curl_handle lookup(const octave_value &val)
Definition: urlwrite.cc:106
static void cleanup_instance(void)
Definition: urlwrite.cc:88
string_vector & append(const std::string &s)
Definition: str-vec.cc:107
void do_free(const curl_handle &h)
Definition: urlwrite.cc:256
octave_value retval
Definition: data.cc:6294
void rmdir(const std::string &path)
Definition: url-transfer.h:232
bool match(const std::string &str) const
Definition: glob-match.cc:32
void get_fileinfo(const std::string &filename, double &filesize, time_t &filetime, bool &fileisdir)
Definition: url-transfer.h:267
std::map< curl_handle, octave::url_transfer > handle_map
Definition: urlwrite.cc:153
Array< std::string > param
Definition: urlwrite.cc:343
bool exists(void) const
Definition: file-stat.h:144
Definition: dMatrix.h:37
bool good(void) const
Definition: url-transfer.h:206
static curl_handle get_handle(void)
Definition: urlwrite.cc:90
std::set< curl_handle >::iterator free_list_iterator
Definition: urlwrite.cc:149
octave::url_transfer do_get_object(const curl_handle &h)
Definition: urlwrite.cc:172
std::string url
Definition: urlwrite.cc:337
void get(const std::string &file, std::ostream &os)
Definition: url-transfer.h:246
octave::unwind_protect frame
Definition: graphics.cc:11584
std::ofstream ofile(filename.c_str(), std::ios::out|std::ios::binary)
static curl_handle lookup(double val)
Definition: urlwrite.cc:101
void cwd(const std::string &path)
Definition: url-transfer.h:228
#define octave_stdout
Definition: pager.h:146
void http_action(const Array< std::string > &param, const std::string &action)
Definition: url-transfer.h:279
void del(const std::string &file)
Definition: url-transfer.h:230
otherwise an error message is printed The permission mask is a UNIX concept used when creating new objects on a file system such as files
Definition: file-io.cc:2981
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
is longer than or if then or only for unique occurrences of the complete pattern(false).The default is true.If a cell array of strings ar
Definition: strfind.cc:192
p
Definition: lu.cc:138
static void delete_file(const std::string &file)
Definition: urlwrite.cc:56
issues an error eealso double
Definition: ov-bool-mat.cc:594
std::string method
Definition: urlwrite.cc:342
static void free(const curl_handle &h)
Definition: urlwrite.cc:95
octave::sys::file_stat fs(filename)
double double_value(bool frc_str_conv=false) const
Definition: ov.h:775
curl_handle do_make_curl_handle(const std::string &host, const std::string &user, const std::string &passwd, std::ostream &os)
Definition: urlwrite.cc:179
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
Matrix do_handle_list(void)
Definition: urlwrite.cc:196
std::string pwd(void)
Definition: url-transfer.h:273
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
string_vector glob(void) const
Definition: glob-match.cc:38