GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
__ftp__.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2006-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <string>
31#include <fstream>
32#include <iomanip>
33
34#include "dir-ops.h"
35#include "file-ops.h"
36#include "file-stat.h"
37#include "lo-sysdep.h"
38#include "oct-env.h"
39#include "oct-handle.h"
40#include "glob-match.h"
41#include "url-transfer.h"
42
43#include "defun.h"
44#include "error.h"
45#include "interpreter.h"
46#include "oct-map.h"
47#include "oct-refcount.h"
48#include "ov-cell.h"
49#include "ov-classdef.h"
50#include "ovl.h"
51#include "pager.h"
52#include "unwind-prot.h"
53#include "url-handle-manager.h"
54
56
57DEFMETHOD (__ftp__, interp, args, ,
58 doc: /* -*- texinfo -*-
59@deftypefn {} {@var{handle} =} __ftp__ (@var{host})
60@deftypefnx {} {@var{handle} =} __ftp__ (@var{host}, @var{username}, @var{password})
61Undocumented internal function
62@end deftypefn */)
63{
64 int nargin = args.length ();
65
66 std::string host = args(0).xstring_value ("__ftp__: HOST must be a string");
67
68 std::string user = (nargin > 1)
69 ? args(1).xstring_value ("__ftp__: USER must be a string")
70 : "anonymous";
71
72 std::string passwd = (nargin > 2)
73 ? args(2).xstring_value ("__ftp__: PASSWD must be a string")
74 : "";
75
76 url_handle_manager& uhm = interp.get_url_handle_manager ();
77
78 url_handle uh = uhm.make_url_handle (host, user, passwd, octave_stdout);
79
80 return ovl (uh.value ());
81}
82
83DEFMETHOD (__ftp_pwd__, interp, args, ,
84 doc: /* -*- texinfo -*-
85@deftypefn {} {@var{pwd} =} __ftp_pwd__ (@var{handle})
86Undocumented internal function
87@end deftypefn */)
88{
89 url_handle_manager& uhm = interp.get_url_handle_manager ();
90
91 url_transfer url_xfer = uhm.get_object (args(0));
92
93 if (! url_xfer.is_valid ())
94 error ("__ftp_pwd__: invalid ftp handle");
95
96 return ovl (url_xfer.pwd ());
97}
98
99DEFMETHOD (__ftp_cwd__, interp, args, ,
100 doc: /* -*- texinfo -*-
101@deftypefn {} {} __ftp_cwd__ (@var{handle}, @var{path})
102Undocumented internal function
103@end deftypefn */)
104{
105 std::string path = "";
106 if (args.length () > 1)
107 path = args(1).xstring_value ("__ftp_cwd__: PATH must be a string");
108
109 url_handle_manager& uhm = interp.get_url_handle_manager ();
110
111 url_transfer url_xfer = uhm.get_object (args(0));
112
113 if (! url_xfer.is_valid ())
114 error ("__ftp_cwd__: invalid ftp handle");
115
116 url_xfer.cwd (path);
117
118 return ovl ();
119}
120
121DEFMETHOD (__ftp_dir__, interp, args, nargout,
122 doc: /* -*- texinfo -*-
123@deftypefn {} {} __ftp_dir__ (@var{handle})
124@deftypefnx {} {@var{S} =} __ftp_dir__ (@var{handle})
125Undocumented internal function
126@end deftypefn */)
127{
128 url_handle_manager& uhm = interp.get_url_handle_manager ();
129
130 url_transfer url_xfer = uhm.get_object (args(0));
131
132 if (! url_xfer.is_valid ())
133 error ("__ftp_dir__: invalid ftp handle");
134
135 octave_value retval;
136
137 if (nargout == 0)
138 url_xfer.dir ();
139 else
140 {
141 string_vector sv = url_xfer.list ();
142 octave_idx_type n = sv.numel ();
143
144 if (n == 0)
145 {
146 string_vector flds (5);
147
148 flds(0) = "name";
149 flds(1) = "date";
150 flds(2) = "bytes";
151 flds(3) = "isdir";
152 flds(4) = "datenum";
153
154 retval = octave_map (flds);
155 }
156 else
157 {
158 octave_map st;
159
160 Cell filectime (dim_vector (n, 1));
161 Cell filesize (dim_vector (n, 1));
162 Cell fileisdir (dim_vector (n, 1));
163 Cell filedatenum (dim_vector (n, 1));
164
165 st.assign ("name", Cell (sv));
166
167 for (octave_idx_type i = 0; i < n; i++)
168 {
169 OCTAVE_TIME_T ftime;
170 bool fisdir;
171 double fsize;
172
173 url_xfer.get_fileinfo (sv(i), fsize, ftime, fisdir);
174
175 fileisdir(i) = fisdir;
176 time_t ftime_t = ftime;
177 filectime(i) = ctime (&ftime_t);
178 filesize(i) = fsize;
179 filedatenum(i) = double (ftime);
180 }
181
182 st.assign ("date", filectime);
183 st.assign ("bytes", filesize);
184 st.assign ("isdir", fileisdir);
185 st.assign ("datenum", filedatenum);
186
187 retval = st;
188 }
189 }
190
191 return retval;
192}
193
194DEFMETHOD (__ftp_ascii__, interp, args, ,
195 doc: /* -*- texinfo -*-
196@deftypefn {} {} __ftp_ascii__ (@var{handle})
197Undocumented internal function
198@end deftypefn */)
199{
200 url_handle_manager& uhm = interp.get_url_handle_manager ();
201
202 url_transfer url_xfer = uhm.get_object (args(0));
203
204 if (! url_xfer.is_valid ())
205 error ("__ftp_ascii__: invalid ftp handle");
206
207 url_xfer.ascii ();
208
209 return ovl ();
210}
211
212DEFMETHOD (__ftp_binary__, interp, args, ,
213 doc: /* -*- texinfo -*-
214@deftypefn {} {} __ftp_binary__ (@var{handle})
215Undocumented internal function
216@end deftypefn */)
217{
218 url_handle_manager& uhm = interp.get_url_handle_manager ();
219
220 url_transfer url_xfer = uhm.get_object (args(0));
221
222 if (! url_xfer.is_valid ())
223 error ("__ftp_binary__: invalid ftp handle");
224
225 url_xfer.binary ();
226
227 return ovl ();
228}
229
230DEFMETHOD (__ftp_close__, interp, args, ,
231 doc: /* -*- texinfo -*-
232@deftypefn {} {} __ftp_close__ (@var{handle})
233Undocumented internal function
234@end deftypefn */)
235{
236 url_handle_manager& uhm = interp.get_url_handle_manager ();
237
238 url_handle h = uhm.lookup (args(0));
239
240 if (! h.ok ())
241 error ("__ftp_close__: invalid ftp handle");
242
243 uhm.free (h);
244
245 return ovl ();
246}
247
248DEFMETHOD (__ftp_mode__, interp, args, ,
249 doc: /* -*- texinfo -*-
250@deftypefn {} {@var{mode} =} __ftp_mode__ (@var{handle})
251Undocumented internal function
252@end deftypefn */)
253{
254 url_handle_manager& uhm = interp.get_url_handle_manager ();
255
256 url_transfer url_xfer = uhm.get_object (args(0));
257
258 if (! url_xfer.is_valid ())
259 error ("__ftp_binary__: invalid ftp handle");
260
261 return ovl (url_xfer.is_ascii () ? "ascii" : "binary");
262}
263
264DEFMETHOD (__ftp_delete__, interp, args, ,
265 doc: /* -*- texinfo -*-
266@deftypefn {} {} __ftp_delete__ (@var{handle}, @var{path})
267Undocumented internal function
268@end deftypefn */)
269{
270 std::string file = args(1).xstring_value ("__ftp_delete__: FILE must be a string");
271
272 url_handle_manager& uhm = interp.get_url_handle_manager ();
273
274 url_transfer url_xfer = uhm.get_object (args(0));
275
276 if (! url_xfer.is_valid ())
277 error ("__ftp_delete__: invalid ftp handle");
278
279 url_xfer.del (file);
280
281 return ovl ();
282}
283
284DEFMETHOD (__ftp_rmdir__, interp, args, ,
285 doc: /* -*- texinfo -*-
286@deftypefn {} {} __ftp_rmdir__ (@var{handle}, @var{path})
287Undocumented internal function
288@end deftypefn */)
289{
290 std::string dir = args(1).xstring_value ("__ftp_rmdir__: DIR must be a string");
291
292 url_handle_manager& uhm = interp.get_url_handle_manager ();
293
294 url_transfer url_xfer = uhm.get_object (args(0));
295
296 if (! url_xfer.is_valid ())
297 error ("__ftp_rmdir__: invalid ftp handle");
298
299 url_xfer.rmdir (dir);
300
301 return ovl ();
302}
303
304DEFMETHOD (__ftp_mkdir__, interp, args, ,
305 doc: /* -*- texinfo -*-
306@deftypefn {} {} __ftp_mkdir__ (@var{handle}, @var{path})
307Undocumented internal function
308@end deftypefn */)
309{
310 std::string dir = args(1).xstring_value ("__ftp_mkdir__: DIR must be a string");
311
312 url_handle_manager& uhm = interp.get_url_handle_manager ();
313
314 url_transfer url_xfer = uhm.get_object (args(0));
315
316 if (! url_xfer.is_valid ())
317 error ("__ftp_mkdir__: invalid ftp handle");
318
319 url_xfer.mkdir (dir);
320
321 return ovl ();
322}
323
324DEFMETHOD (__ftp_rename__, interp, args, ,
325 doc: /* -*- texinfo -*-
326@deftypefn {} {} __ftp_rename__ (@var{handle}, @var{path})
327Undocumented internal function
328@end deftypefn */)
329{
330 std::string oldname = args(1).xstring_value ("__ftp_rename__: OLDNAME must be a string");
331 std::string newname = args(2).xstring_value ("__ftp_rename__: NEWNAME must be a string");
332
333 url_handle_manager& uhm = interp.get_url_handle_manager ();
334
335 url_transfer url_xfer = uhm.get_object (args(0));
336
337 if (url_xfer.is_valid ())
338 error ("__ftp_rename__: invalid ftp handle");
339
340 url_xfer.rename (oldname, newname);
341
342 return ovl ();
343}
344
345DEFMETHOD (__ftp_mput__, interp, args, nargout,
346 doc: /* -*- texinfo -*-
347@deftypefn {} {} __ftp_mput__ (@var{handle}, @var{files})
348@deftypefnx {} {@var{filelist} =} __ftp_mput__ (@var{handle}, @var{files})
349Undocumented internal function
350@end deftypefn */)
351{
352 std::string pat = args(1).xstring_value ("__ftp_mput__: PATTERN must be a string");
353
354 url_handle_manager& uhm = interp.get_url_handle_manager ();
355
356 url_transfer url_xfer = uhm.get_object (args(0));
357
358 if (! url_xfer.is_valid ())
359 error ("__ftp_mput__: invalid ftp handle");
360
361 string_vector file_list;
362
363 glob_match pattern (sys::file_ops::tilde_expand (pat));
364 string_vector files = pattern.glob ();
365
366 for (octave_idx_type i = 0; i < files.numel (); i++)
367 {
368 std::string file = files(i);
369
370 if (! sys::file_exists (file))
371 error ("__ftp__mput: file does not exist");
372
373 if (sys::dir_exists (file))
374 {
375 file_list.append (url_xfer.mput_directory ("", file));
376
377 if (! url_xfer.good ())
378 error ("__ftp_mput__: %s", url_xfer.lasterror ().c_str ());
379 }
380 else
381 {
382 // FIXME: Does ascii mode need to be flagged here?
383 std::ifstream ifile =
384 sys::ifstream (file.c_str (),
385 std::ios::in | std::ios::binary);
386
387 if (! ifile.is_open ())
388 error ("__ftp_mput__: unable to open file");
389
390 url_xfer.put (file, ifile);
391
392 ifile.close ();
393
394 if (! url_xfer.good ())
395 error ("__ftp_mput__: %s", url_xfer.lasterror ().c_str ());
396
397 file_list.append (file);
398 }
399 }
400
401 if (nargout > 0)
402 return ovl (file_list);
403 else
404 return ovl ();
405}
406
407DEFMETHOD (__ftp_mget__, interp, args, ,
408 doc: /* -*- texinfo -*-
409@deftypefn {} {} __ftp_mget__ (@var{handle}, @var{pattern})
410@deftypefnx {} {} __ftp_mget__ (@var{handle}, @var{pattern}, @var{target})
411Undocumented internal function
412@end deftypefn */)
413{
414 std::string file = args(1).xstring_value ("__ftp_mget__: PATTERN must be a string");
415
416 std::string target;
417
418 if (args.length () == 3 && ! args(2).isempty ())
419 target = args(2).xstring_value ("__ftp_mget__: TARGET must be a string")
420 + sys::file_ops::dir_sep_str ();
421
422 url_handle_manager& uhm = interp.get_url_handle_manager ();
423
424 url_transfer url_xfer = uhm.get_object (args(0));
425
426 if (! url_xfer.is_valid ())
427 error ("__ftp_mget__: invalid ftp handle");
428
429 string_vector sv = url_xfer.list ();
430 octave_idx_type n = 0;
431 glob_match pattern (file);
432
433 for (octave_idx_type i = 0; i < sv.numel (); i++)
434 {
435 if (pattern.match (sv(i)))
436 {
437 n++;
438
439 OCTAVE_TIME_T ftime;
440 bool fisdir;
441 double fsize;
442
443 url_xfer.get_fileinfo (sv(i), fsize, ftime, fisdir);
444
445 if (fisdir)
446 url_xfer.mget_directory (sv(i), target);
447 else
448 {
449 std::ofstream ofile =
450 sys::ofstream ((target + sv(i)).c_str (),
451 std::ios::out | std::ios::binary);
452
453 if (! ofile.is_open ())
454 error ("__ftp_mget__: unable to open file");
455
456 int(*unlink_fptr)(const std::string&) = sys::unlink;
457 unwind_action_safe delete_file (unlink_fptr, target + sv(i));
458
459 url_xfer.get (sv(i), ofile);
460
461 ofile.close ();
462
463 if (url_xfer.good ())
464 delete_file.discard ();
465 }
466
467 if (! url_xfer.good ())
468 error ("__ftp_mget__: %s", url_xfer.lasterror ().c_str ());
469 }
470 }
471
472 if (n == 0)
473 error ("__ftp_mget__: file not found");
474
475 return ovl ();
476}
477
478OCTAVE_END_NAMESPACE(octave)
Definition Cell.h:41
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
string_vector glob() const
Definition glob-match.cc:41
bool match(const std::string &str) const
Definition glob-match.cc:35
double value() const
Definition oct-handle.h:78
bool ok() const
Definition oct-handle.h:113
void assign(const std::string &k, const Cell &val)
Definition oct-map.h:344
string_vector & append(const std::string &s)
Definition str-vec.cc:110
octave_idx_type numel() const
Definition str-vec.h:98
void free(const url_handle &h)
url_handle make_url_handle(const std::string &host, const std::string &user, const std::string &passwd, std::ostream &os)
url_handle lookup(double val)
url_transfer get_object(double val)
void put(const std::string &file, std::istream &is)
void get_fileinfo(const std::string &filename, double &filesize, OCTAVE_TIME_T &filetime, bool &fileisdir)
string_vector list()
void get(const std::string &file, std::ostream &os)
bool is_ascii() const
void cwd(const std::string &path)
bool is_valid() const
void mkdir(const std::string &path)
string_vector mput_directory(const std::string &base, const std::string &directory)
std::string lasterror() const
void mget_directory(const std::string &directory, const std::string &target)
std::string pwd()
void rmdir(const std::string &path)
void del(const std::string &file)
void rename(const std::string &oldname, const std::string &newname)
bool good() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition defun.h:111
void error(const char *fmt,...)
Definition error.cc:1003
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217
#define octave_stdout
Definition pager.h:301