GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
__ftp__.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2006-2022 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
55OCTAVE_NAMESPACE_BEGIN
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 {} {} __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 int nargin = args.length ();
106
107 std::string path = "";
108 if (nargin > 1)
109 path = args(1).xstring_value ("__ftp_cwd__: PATH must be a string");
110
111 url_handle_manager& uhm = interp.get_url_handle_manager ();
112
113 url_transfer url_xfer = uhm.get_object (args(0));
114
115 if (! url_xfer.is_valid ())
116 error ("__ftp_cwd__: invalid ftp handle");
117
118 url_xfer.cwd (path);
119
120 return ovl ();
121}
122
123DEFMETHOD (__ftp_dir__, interp, args, nargout,
124 doc: /* -*- texinfo -*-
125@deftypefn {} {} __ftp_dir__ (@var{handle})
126Undocumented internal function
127@end deftypefn */)
128{
129 url_handle_manager& uhm = interp.get_url_handle_manager ();
130
131 url_transfer url_xfer = uhm.get_object (args(0));
132
133 if (! url_xfer.is_valid ())
134 error ("__ftp_dir__: invalid ftp handle");
135
136 octave_value retval;
137
138 if (nargout == 0)
139 url_xfer.dir ();
140 else
141 {
142 string_vector sv = url_xfer.list ();
143 octave_idx_type n = sv.numel ();
144
145 if (n == 0)
146 {
147 string_vector flds (5);
148
149 flds(0) = "name";
150 flds(1) = "date";
151 flds(2) = "bytes";
152 flds(3) = "isdir";
153 flds(4) = "datenum";
154
155 retval = octave_map (flds);
156 }
157 else
158 {
159 octave_map st;
160
161 Cell filectime (dim_vector (n, 1));
162 Cell filesize (dim_vector (n, 1));
163 Cell fileisdir (dim_vector (n, 1));
164 Cell filedatenum (dim_vector (n, 1));
165
166 st.assign ("name", Cell (sv));
167
168 for (octave_idx_type i = 0; i < n; i++)
169 {
170 OCTAVE_TIME_T ftime;
171 bool fisdir;
172 double fsize;
173
174 url_xfer.get_fileinfo (sv(i), fsize, ftime, fisdir);
175
176 fileisdir(i) = fisdir;
177 time_t ftime_t = ftime;
178 filectime(i) = ctime (&ftime_t);
179 filesize(i) = fsize;
180 filedatenum(i) = double (ftime);
181 }
182
183 st.assign ("date", filectime);
184 st.assign ("bytes", filesize);
185 st.assign ("isdir", fileisdir);
186 st.assign ("datenum", filedatenum);
187
188 retval = st;
189 }
190 }
191
192 return retval;
193}
194
195DEFMETHOD (__ftp_ascii__, interp, args, ,
196 doc: /* -*- texinfo -*-
197@deftypefn {} {} __ftp_ascii__ (@var{handle})
198Undocumented internal function
199@end deftypefn */)
200{
201 url_handle_manager& uhm = interp.get_url_handle_manager ();
202
203 url_transfer url_xfer = uhm.get_object (args(0));
204
205 if (! url_xfer.is_valid ())
206 error ("__ftp_ascii__: invalid ftp handle");
207
208 url_xfer.ascii ();
209
210 return ovl ();
211}
212
213DEFMETHOD (__ftp_binary__, interp, args, ,
214 doc: /* -*- texinfo -*-
215@deftypefn {} {} __ftp_binary__ (@var{handle})
216Undocumented internal function
217@end deftypefn */)
218{
219 url_handle_manager& uhm = interp.get_url_handle_manager ();
220
221 url_transfer url_xfer = uhm.get_object (args(0));
222
223 if (! url_xfer.is_valid ())
224 error ("__ftp_binary__: invalid ftp handle");
225
226 url_xfer.binary ();
227
228 return ovl ();
229}
230
231DEFMETHOD (__ftp_close__, interp, args, ,
232 doc: /* -*- texinfo -*-
233@deftypefn {} {} __ftp_close__ (@var{handle})
234Undocumented internal function
235@end deftypefn */)
236{
237 url_handle_manager& uhm = interp.get_url_handle_manager ();
238
239 url_handle h = uhm.lookup (args(0));
240
241 if (! h.ok ())
242 error ("__ftp_close__: invalid ftp handle");
243
244 uhm.free (h);
245
246 return ovl ();
247}
248
249DEFMETHOD (__ftp_mode__, interp, args, ,
250 doc: /* -*- texinfo -*-
251@deftypefn {} {} __ftp_mode__ (@var{handle})
252Undocumented internal function
253@end deftypefn */)
254{
255 url_handle_manager& uhm = interp.get_url_handle_manager ();
256
257 url_transfer url_xfer = uhm.get_object (args(0));
258
259 if (! url_xfer.is_valid ())
260 error ("__ftp_binary__: invalid ftp handle");
261
262 return ovl (url_xfer.is_ascii () ? "ascii" : "binary");
263}
264
265DEFMETHOD (__ftp_delete__, interp, args, ,
266 doc: /* -*- texinfo -*-
267@deftypefn {} {} __ftp_delete__ (@var{handle}, @var{path})
268Undocumented internal function
269@end deftypefn */)
270{
271 std::string file = args(1).xstring_value ("__ftp_delete__: FILE must be a string");
272
273 url_handle_manager& uhm = interp.get_url_handle_manager ();
274
275 url_transfer url_xfer = uhm.get_object (args(0));
276
277 if (! url_xfer.is_valid ())
278 error ("__ftp_delete__: invalid ftp handle");
279
280 url_xfer.del (file);
281
282 return ovl ();
283}
284
285DEFMETHOD (__ftp_rmdir__, interp, args, ,
286 doc: /* -*- texinfo -*-
287@deftypefn {} {} __ftp_rmdir__ (@var{handle}, @var{path})
288Undocumented internal function
289@end deftypefn */)
290{
291 std::string dir = args(1).xstring_value ("__ftp_rmdir__: DIR must be a string");
292
293 url_handle_manager& uhm = interp.get_url_handle_manager ();
294
295 url_transfer url_xfer = uhm.get_object (args(0));
296
297 if (! url_xfer.is_valid ())
298 error ("__ftp_rmdir__: invalid ftp handle");
299
300 url_xfer.rmdir (dir);
301
302 return ovl ();
303}
304
305DEFMETHOD (__ftp_mkdir__, interp, args, ,
306 doc: /* -*- texinfo -*-
307@deftypefn {} {} __ftp_mkdir__ (@var{handle}, @var{path})
308Undocumented internal function
309@end deftypefn */)
310{
311 std::string dir = args(1).xstring_value ("__ftp_mkdir__: DIR must be a string");
312
313 url_handle_manager& uhm = interp.get_url_handle_manager ();
314
315 url_transfer url_xfer = uhm.get_object (args(0));
316
317 if (! url_xfer.is_valid ())
318 error ("__ftp_mkdir__: invalid ftp handle");
319
320 url_xfer.mkdir (dir);
321
322 return ovl ();
323}
324
325DEFMETHOD (__ftp_rename__, interp, args, ,
326 doc: /* -*- texinfo -*-
327@deftypefn {} {} __ftp_rename__ (@var{handle}, @var{path})
328Undocumented internal function
329@end deftypefn */)
330{
331 std::string oldname = args(1).xstring_value ("__ftp_rename__: OLDNAME must be a string");
332 std::string newname = args(2).xstring_value ("__ftp_rename__: NEWNAME must be a string");
333
334 url_handle_manager& uhm = interp.get_url_handle_manager ();
335
336 url_transfer url_xfer = uhm.get_object (args(0));
337
338 if (url_xfer.is_valid ())
339 error ("__ftp_rename__: invalid ftp handle");
340
341 url_xfer.rename (oldname, newname);
342
343 return ovl ();
344}
345
346DEFMETHOD (__ftp_mput__, interp, args, nargout,
347 doc: /* -*- texinfo -*-
348@deftypefn {} {} __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
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 sys::file_stat fs (file);
371
372 if (! fs.exists ())
373 error ("__ftp__mput: file does not exist");
374
375 if (fs.is_dir ())
376 {
377 file_list.append (url_xfer.mput_directory ("", file));
378
379 if (! url_xfer.good ())
380 error ("__ftp_mput__: %s", url_xfer.lasterror ().c_str ());
381 }
382 else
383 {
384 // FIXME: Does ascii mode need to be flagged here?
385 std::ifstream ifile =
386 sys::ifstream (file.c_str (),
387 std::ios::in | std::ios::binary);
388
389 if (! ifile.is_open ())
390 error ("__ftp_mput__: unable to open file");
391
392 url_xfer.put (file, ifile);
393
394 ifile.close ();
395
396 if (! url_xfer.good ())
397 error ("__ftp_mput__: %s", url_xfer.lasterror ().c_str ());
398
399 file_list.append (file);
400 }
401 }
402
403 if (nargout > 0)
404 return ovl (file_list);
405 else
406 return ovl ();
407}
408
409DEFMETHOD (__ftp_mget__, interp, args, ,
410 doc: /* -*- texinfo -*-
411@deftypefn {} {} __ftp_mget__ (@var{handle}, @var{pattern})
412@deftypefnx {} {} __ftp_mget__ (@var{handle}, @var{pattern}, @var{target})
413Undocumented internal function
414@end deftypefn */)
415{
416 int nargin = args.length ();
417
418 std::string file = args(1).xstring_value ("__ftp_mget__: PATTERN must be a string");
419
420 std::string target;
421
422 if (nargin == 3 && ! args(2).isempty ())
423 target = args(2).xstring_value ("__ftp_mget__: TARGET must be a string")
425
426 url_handle_manager& uhm = interp.get_url_handle_manager ();
427
428 url_transfer url_xfer = uhm.get_object (args(0));
429
430 if (! url_xfer.is_valid ())
431 error ("__ftp_mget__: invalid ftp handle");
432
433 string_vector sv = url_xfer.list ();
434 octave_idx_type n = 0;
435 glob_match pattern (file);
436
437 for (octave_idx_type i = 0; i < sv.numel (); i++)
438 {
439 if (pattern.match (sv(i)))
440 {
441 n++;
442
443 OCTAVE_TIME_T ftime;
444 bool fisdir;
445 double fsize;
446
447 url_xfer.get_fileinfo (sv(i), fsize, ftime, fisdir);
448
449 if (fisdir)
450 url_xfer.mget_directory (sv(i), target);
451 else
452 {
453 std::ofstream ofile =
454 sys::ofstream ((target + sv(i)).c_str (),
455 std::ios::out | std::ios::binary);
456
457 if (! ofile.is_open ())
458 error ("__ftp_mget__: unable to open file");
459
460 int(*unlink_fptr)(const std::string&) = sys::unlink;
461 unwind_action_safe delete_file (unlink_fptr, target + sv(i));
462
463 url_xfer.get (sv(i), ofile);
464
465 ofile.close ();
466
467 if (url_xfer.good ())
468 delete_file.discard ();
469 }
470
471 if (! url_xfer.good ())
472 error ("__ftp_mget__: %s", url_xfer.lasterror ().c_str ());
473 }
474 }
475
476 if (n == 0)
477 error ("__ftp_mget__: file not found");
478
479 return ovl ();
480}
481
482OCTAVE_NAMESPACE_END
Definition: Cell.h:43
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
string_vector glob(void) const
Definition: glob-match.cc:41
bool match(const std::string &str) const
Definition: glob-match.cc:35
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:365
string_vector & append(const std::string &s)
Definition: str-vec.cc:110
octave_idx_type numel(void) const
Definition: str-vec.h:100
#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:980
QString path
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:281
std::string dir_sep_str(void)
Definition: file-ops.cc:238
std::ifstream ifstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:400
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:414
int unlink(const std::string &name)
Definition: file-ops.cc:621
octave_handle url_handle
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
#define octave_stdout
Definition: pager.h:314