comparison src/DLD-FUNCTIONS/urlwrite.cc @ 10154:40dfc0c99116

DLD-FUNCTIONS/*.cc: untabify
author John W. Eaton <jwe@octave.org>
date Wed, 20 Jan 2010 17:33:41 -0500
parents 81e88250bf42
children 4d433bd2d4dc
comparison
equal deleted inserted replaced
10153:2c28f9d0360f 10154:40dfc0c99116
89 { 89 {
90 public: 90 public:
91 curl_handle_rep (void) : count (1), valid (true), ascii (false) 91 curl_handle_rep (void) : count (1), valid (true), ascii (false)
92 { 92 {
93 curl = curl_easy_init (); 93 curl = curl_easy_init ();
94 if (!curl) 94 if (!curl)
95 error ("can not create curl handle"); 95 error ("can not create curl handle");
96 } 96 }
97 97
98 ~curl_handle_rep (void) 98 ~curl_handle_rep (void)
99 { 99 {
100 if (curl) 100 if (curl)
101 curl_easy_cleanup (curl); 101 curl_easy_cleanup (curl);
102 } 102 }
103 103
104 bool is_valid (void) const 104 bool is_valid (void) const
105 { 105 {
106 return valid; 106 return valid;
107 } 107 }
108 108
109 bool perform (bool curlerror) const 109 bool perform (bool curlerror) const
110 { 110 {
111 bool retval = false; 111 bool retval = false;
112 if (!error_state) 112 if (!error_state)
113 { 113 {
114 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; 114 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
115 115
116 CURLcode res = curl_easy_perform (curl); 116 CURLcode res = curl_easy_perform (curl);
117 if (res != CURLE_OK) 117 if (res != CURLE_OK)
118 { 118 {
119 if (curlerror) 119 if (curlerror)
120 error ("%s", curl_easy_strerror (res)); 120 error ("%s", curl_easy_strerror (res));
121 } 121 }
122 else 122 else
123 retval = true; 123 retval = true;
124 124
125 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; 125 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
126 } 126 }
127 return retval; 127 return retval;
128 } 128 }
129 129
130 CURL* handle (void) const 130 CURL* handle (void) const
131 { 131 {
132 return curl; 132 return curl;
133 } 133 }
134 134
135 bool is_ascii (void) const 135 bool is_ascii (void) const
136 { 136 {
137 return ascii; 137 return ascii;
138 } 138 }
139 139
140 bool is_binary (void) const 140 bool is_binary (void) const
141 { 141 {
142 return !ascii; 142 return !ascii;
143 } 143 }
144 144
145 size_t count; 145 size_t count;
146 std::string host; 146 std::string host;
147 bool valid; 147 bool valid;
173 { 173 {
174 rep->valid = false; 174 rep->valid = false;
175 } 175 }
176 176
177 curl_handle (const std::string& _host, const std::string& user, 177 curl_handle (const std::string& _host, const std::string& user,
178 const std::string& passwd) : 178 const std::string& passwd) :
179 rep (new curl_handle_rep ()) 179 rep (new curl_handle_rep ())
180 { 180 {
181 rep->host = _host; 181 rep->host = _host;
182 init (user, passwd, std::cin, octave_stdout); 182 init (user, passwd, std::cin, octave_stdout);
183 183
184 std::string url = "ftp://" + _host; 184 std::string url = "ftp://" + _host;
185 setopt (CURLOPT_URL, url.c_str()); 185 setopt (CURLOPT_URL, url.c_str());
186 186
187 // Setup the link, with no transfer 187 // Setup the link, with no transfer
188 if (!error_state) 188 if (!error_state)
189 perform (); 189 perform ();
190 } 190 }
191 191
192 curl_handle (const std::string& url, const std::string& method, 192 curl_handle (const std::string& url, const std::string& method,
193 const Cell& param, std::ostream& os, bool& retval) : 193 const Cell& param, std::ostream& os, bool& retval) :
194 rep (new curl_handle_rep ()) 194 rep (new curl_handle_rep ())
195 { 195 {
196 retval = false; 196 retval = false;
197 197
198 init ("", "", std::cin, os); 198 init ("", "", std::cin, os);
202 // Don't need to store the parameters here as we can't change 202 // Don't need to store the parameters here as we can't change
203 // the URL after the handle is created 203 // the URL after the handle is created
204 std::string query_string = form_query_string (param); 204 std::string query_string = form_query_string (param);
205 205
206 if (method == "get") 206 if (method == "get")
207 { 207 {
208 query_string = url + "?" + query_string; 208 query_string = url + "?" + query_string;
209 setopt (CURLOPT_URL, query_string.c_str ()); 209 setopt (CURLOPT_URL, query_string.c_str ());
210 } 210 }
211 else if (method == "post") 211 else if (method == "post")
212 { 212 {
213 setopt (CURLOPT_URL, url.c_str ()); 213 setopt (CURLOPT_URL, url.c_str ());
214 setopt (CURLOPT_POSTFIELDS, query_string.c_str ()); 214 setopt (CURLOPT_POSTFIELDS, query_string.c_str ());
215 } 215 }
216 else 216 else
217 setopt (CURLOPT_URL, url.c_str()); 217 setopt (CURLOPT_URL, url.c_str());
218 218
219 if (!error_state) 219 if (!error_state)
220 retval = perform (false); 220 retval = perform (false);
221 } 221 }
222 222
223 curl_handle (const curl_handle& h) : rep (h.rep) 223 curl_handle (const curl_handle& h) : rep (h.rep)
224 { 224 {
225 rep->count++; 225 rep->count++;
226 } 226 }
227 227
228 ~curl_handle (void) 228 ~curl_handle (void)
229 { 229 {
230 if (--rep->count == 0) 230 if (--rep->count == 0)
231 delete rep; 231 delete rep;
232 } 232 }
233 233
234 curl_handle& operator = (const curl_handle& h) 234 curl_handle& operator = (const curl_handle& h)
235 { 235 {
236 if (this != &h) 236 if (this != &h)
237 { 237 {
238 if (--rep->count == 0) 238 if (--rep->count == 0)
239 delete rep; 239 delete rep;
240 240
241 rep = h.rep; 241 rep = h.rep;
242 rep->count++; 242 rep->count++;
243 } 243 }
244 return *this; 244 return *this;
245 } 245 }
246 246
247 bool is_valid (void) const 247 bool is_valid (void) const
248 { 248 {
295 struct curl_slist *slist = 0; 295 struct curl_slist *slist = 0;
296 std::string cmd = "cwd " + path; 296 std::string cmd = "cwd " + path;
297 slist = curl_slist_append (slist, cmd.c_str()); 297 slist = curl_slist_append (slist, cmd.c_str());
298 setopt (CURLOPT_POSTQUOTE, slist); 298 setopt (CURLOPT_POSTQUOTE, slist);
299 if (! error_state) 299 if (! error_state)
300 perform (); 300 perform ();
301 setopt (CURLOPT_POSTQUOTE, 0); 301 setopt (CURLOPT_POSTQUOTE, 0);
302 curl_slist_free_all (slist); 302 curl_slist_free_all (slist);
303 } 303 }
304 304
305 void del (const std::string& file) const 305 void del (const std::string& file) const
307 struct curl_slist *slist = 0; 307 struct curl_slist *slist = 0;
308 std::string cmd = "dele " + file; 308 std::string cmd = "dele " + file;
309 slist = curl_slist_append (slist, cmd.c_str()); 309 slist = curl_slist_append (slist, cmd.c_str());
310 setopt (CURLOPT_POSTQUOTE, slist); 310 setopt (CURLOPT_POSTQUOTE, slist);
311 if (! error_state) 311 if (! error_state)
312 perform (); 312 perform ();
313 setopt (CURLOPT_POSTQUOTE, 0); 313 setopt (CURLOPT_POSTQUOTE, 0);
314 curl_slist_free_all (slist); 314 curl_slist_free_all (slist);
315 } 315 }
316 316
317 void rmdir (const std::string& path) const 317 void rmdir (const std::string& path) const
319 struct curl_slist *slist = 0; 319 struct curl_slist *slist = 0;
320 std::string cmd = "rmd " + path; 320 std::string cmd = "rmd " + path;
321 slist = curl_slist_append (slist, cmd.c_str()); 321 slist = curl_slist_append (slist, cmd.c_str());
322 setopt (CURLOPT_POSTQUOTE, slist); 322 setopt (CURLOPT_POSTQUOTE, slist);
323 if (! error_state) 323 if (! error_state)
324 perform (); 324 perform ();
325 setopt (CURLOPT_POSTQUOTE, 0); 325 setopt (CURLOPT_POSTQUOTE, 0);
326 curl_slist_free_all (slist); 326 curl_slist_free_all (slist);
327 } 327 }
328 328
329 bool mkdir (const std::string& path, bool curlerror = true) const 329 bool mkdir (const std::string& path, bool curlerror = true) const
332 struct curl_slist *slist = 0; 332 struct curl_slist *slist = 0;
333 std::string cmd = "mkd " + path; 333 std::string cmd = "mkd " + path;
334 slist = curl_slist_append (slist, cmd.c_str()); 334 slist = curl_slist_append (slist, cmd.c_str());
335 setopt (CURLOPT_POSTQUOTE, slist); 335 setopt (CURLOPT_POSTQUOTE, slist);
336 if (! error_state) 336 if (! error_state)
337 retval = perform (curlerror); 337 retval = perform (curlerror);
338 setopt (CURLOPT_POSTQUOTE, 0); 338 setopt (CURLOPT_POSTQUOTE, 0);
339 curl_slist_free_all (slist); 339 curl_slist_free_all (slist);
340 return retval; 340 return retval;
341 } 341 }
342 342
347 slist = curl_slist_append (slist, cmd.c_str()); 347 slist = curl_slist_append (slist, cmd.c_str());
348 cmd = "rnto " + newname; 348 cmd = "rnto " + newname;
349 slist = curl_slist_append (slist, cmd.c_str()); 349 slist = curl_slist_append (slist, cmd.c_str());
350 setopt (CURLOPT_POSTQUOTE, slist); 350 setopt (CURLOPT_POSTQUOTE, slist);
351 if (! error_state) 351 if (! error_state)
352 perform (); 352 perform ();
353 setopt (CURLOPT_POSTQUOTE, 0); 353 setopt (CURLOPT_POSTQUOTE, 0);
354 curl_slist_free_all (slist); 354 curl_slist_free_all (slist);
355 } 355 }
356 356
357 void put (const std::string& file, std::istream& is) const 357 void put (const std::string& file, std::istream& is) const
360 setopt (CURLOPT_URL, url.c_str()); 360 setopt (CURLOPT_URL, url.c_str());
361 setopt (CURLOPT_UPLOAD, 1); 361 setopt (CURLOPT_UPLOAD, 1);
362 setopt (CURLOPT_NOBODY, 0); 362 setopt (CURLOPT_NOBODY, 0);
363 set_istream (is); 363 set_istream (is);
364 if (! error_state) 364 if (! error_state)
365 perform (); 365 perform ();
366 set_istream (std::cin); 366 set_istream (std::cin);
367 setopt (CURLOPT_NOBODY, 1); 367 setopt (CURLOPT_NOBODY, 1);
368 setopt (CURLOPT_UPLOAD, 0); 368 setopt (CURLOPT_UPLOAD, 0);
369 url = "ftp://" + rep->host; 369 url = "ftp://" + rep->host;
370 setopt (CURLOPT_URL, url.c_str()); 370 setopt (CURLOPT_URL, url.c_str());
375 std::string url = "ftp://" + rep->host + "/" + file; 375 std::string url = "ftp://" + rep->host + "/" + file;
376 setopt (CURLOPT_URL, url.c_str()); 376 setopt (CURLOPT_URL, url.c_str());
377 setopt (CURLOPT_NOBODY, 0); 377 setopt (CURLOPT_NOBODY, 0);
378 set_ostream (os); 378 set_ostream (os);
379 if (! error_state) 379 if (! error_state)
380 perform (); 380 perform ();
381 set_ostream (octave_stdout); 381 set_ostream (octave_stdout);
382 setopt (CURLOPT_NOBODY, 1); 382 setopt (CURLOPT_NOBODY, 1);
383 url = "ftp://" + rep->host; 383 url = "ftp://" + rep->host;
384 setopt (CURLOPT_URL, url.c_str()); 384 setopt (CURLOPT_URL, url.c_str());
385 } 385 }
388 { 388 {
389 std::string url = "ftp://" + rep->host + "/"; 389 std::string url = "ftp://" + rep->host + "/";
390 setopt (CURLOPT_URL, url.c_str()); 390 setopt (CURLOPT_URL, url.c_str());
391 setopt (CURLOPT_NOBODY, 0); 391 setopt (CURLOPT_NOBODY, 0);
392 if (! error_state) 392 if (! error_state)
393 perform (); 393 perform ();
394 setopt (CURLOPT_NOBODY, 1); 394 setopt (CURLOPT_NOBODY, 1);
395 url = "ftp://" + rep->host; 395 url = "ftp://" + rep->host;
396 setopt (CURLOPT_URL, url.c_str()); 396 setopt (CURLOPT_URL, url.c_str());
397 } 397 }
398 398
403 setopt (CURLOPT_WRITEDATA, static_cast<void*> (&buf)); 403 setopt (CURLOPT_WRITEDATA, static_cast<void*> (&buf));
404 setopt (CURLOPT_URL, url.c_str()); 404 setopt (CURLOPT_URL, url.c_str());
405 setopt (CURLOPT_DIRLISTONLY, 1); 405 setopt (CURLOPT_DIRLISTONLY, 1);
406 setopt (CURLOPT_NOBODY, 0); 406 setopt (CURLOPT_NOBODY, 0);
407 if (! error_state) 407 if (! error_state)
408 perform (); 408 perform ();
409 setopt (CURLOPT_NOBODY, 1); 409 setopt (CURLOPT_NOBODY, 1);
410 url = "ftp://" + rep->host; 410 url = "ftp://" + rep->host;
411 setopt (CURLOPT_WRITEDATA, static_cast<void*> (&octave_stdout)); 411 setopt (CURLOPT_WRITEDATA, static_cast<void*> (&octave_stdout));
412 setopt (CURLOPT_DIRLISTONLY, 0); 412 setopt (CURLOPT_DIRLISTONLY, 0);
413 setopt (CURLOPT_URL, url.c_str()); 413 setopt (CURLOPT_URL, url.c_str());
415 // Count number of directory entries 415 // Count number of directory entries
416 std::string str = buf.str (); 416 std::string str = buf.str ();
417 octave_idx_type n = 0; 417 octave_idx_type n = 0;
418 size_t pos = 0; 418 size_t pos = 0;
419 while (true) 419 while (true)
420 { 420 {
421 pos = str.find_first_of('\n', pos); 421 pos = str.find_first_of('\n', pos);
422 if (pos == std::string::npos) 422 if (pos == std::string::npos)
423 break; 423 break;
424 pos++; 424 pos++;
425 n++; 425 n++;
426 } 426 }
427 string_vector retval (n); 427 string_vector retval (n);
428 pos = 0; 428 pos = 0;
429 for (octave_idx_type i = 0; i < n; i++) 429 for (octave_idx_type i = 0; i < n; i++)
430 { 430 {
431 size_t newpos = str.find_first_of('\n', pos); 431 size_t newpos = str.find_first_of('\n', pos);
432 if (newpos == std::string::npos) 432 if (newpos == std::string::npos)
433 break; 433 break;
434 434
435 retval(i) = str.substr(pos, newpos - pos); 435 retval(i) = str.substr(pos, newpos - pos);
436 pos = newpos + 1; 436 pos = newpos + 1;
437 } 437 }
438 return retval; 438 return retval;
439 } 439 }
440 440
441 void get_fileinfo (const std::string& filename, double& filesize, 441 void get_fileinfo (const std::string& filename, double& filesize,
442 time_t& filetime, bool& fileisdir) const 442 time_t& filetime, bool& fileisdir) const
443 { 443 {
444 std::string path = pwd(); 444 std::string path = pwd();
445 445
446 std::string url = "ftp://" + rep->host + "/" + path + "/" + filename; 446 std::string url = "ftp://" + rep->host + "/" + path + "/" + filename;
447 setopt (CURLOPT_URL, url.c_str()); 447 setopt (CURLOPT_URL, url.c_str());
452 // FIXME 452 // FIXME
453 // The MDTM command fails for a directory on the servers I tested 453 // The MDTM command fails for a directory on the servers I tested
454 // so this is a means of testing for directories. It also means 454 // so this is a means of testing for directories. It also means
455 // I can't get the date of directories! 455 // I can't get the date of directories!
456 if (! error_state) 456 if (! error_state)
457 { 457 {
458 if (! perform (false)) 458 if (! perform (false))
459 { 459 {
460 fileisdir = true; 460 fileisdir = true;
461 filetime = -1; 461 filetime = -1;
462 filesize = 0; 462 filesize = 0;
463 } 463 }
464 else 464 else
465 { 465 {
466 fileisdir = false; 466 fileisdir = false;
467 time_t ft; 467 time_t ft;
468 curl_easy_getinfo(rep->handle (), CURLINFO_FILETIME, &ft); 468 curl_easy_getinfo(rep->handle (), CURLINFO_FILETIME, &ft);
469 filetime = ft; 469 filetime = ft;
470 double fs; 470 double fs;
471 curl_easy_getinfo(rep->handle (), 471 curl_easy_getinfo(rep->handle (),
472 CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs); 472 CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs);
473 filesize = fs; 473 filesize = fs;
474 } 474 }
475 } 475 }
476 476
477 setopt (CURLOPT_WRITEFUNCTION, write_data); 477 setopt (CURLOPT_WRITEFUNCTION, write_data);
478 setopt (CURLOPT_HEADERFUNCTION, 0); 478 setopt (CURLOPT_HEADERFUNCTION, 0);
479 setopt (CURLOPT_FILETIME, 0); 479 setopt (CURLOPT_FILETIME, 0);
480 url = "ftp://" + rep->host; 480 url = "ftp://" + rep->host;
497 setopt (CURLOPT_POSTQUOTE, slist); 497 setopt (CURLOPT_POSTQUOTE, slist);
498 setopt (CURLOPT_HEADERFUNCTION, write_data); 498 setopt (CURLOPT_HEADERFUNCTION, write_data);
499 setopt (CURLOPT_WRITEHEADER, static_cast<void *>(&buf)); 499 setopt (CURLOPT_WRITEHEADER, static_cast<void *>(&buf));
500 500
501 if (! error_state) 501 if (! error_state)
502 { 502 {
503 perform (); 503 perform ();
504 retval = buf.str(); 504 retval = buf.str();
505 505
506 // Can I assume that the path is alway in "" on the last line 506 // Can I assume that the path is alway in "" on the last line
507 size_t pos2 = retval.rfind ('"'); 507 size_t pos2 = retval.rfind ('"');
508 size_t pos1 = retval.rfind ('"', pos2 - 1); 508 size_t pos1 = retval.rfind ('"', pos2 - 1);
509 retval = retval.substr(pos1 + 1, pos2 - pos1 - 1); 509 retval = retval.substr(pos1 + 1, pos2 - pos1 - 1);
510 } 510 }
511 setopt (CURLOPT_HEADERFUNCTION, 0); 511 setopt (CURLOPT_HEADERFUNCTION, 0);
512 setopt (CURLOPT_WRITEHEADER, 0); 512 setopt (CURLOPT_WRITEHEADER, 0);
513 setopt (CURLOPT_POSTQUOTE, 0); 513 setopt (CURLOPT_POSTQUOTE, 0);
514 curl_slist_free_all (slist); 514 curl_slist_free_all (slist);
515 515
527 std::string form_query_string (const Cell& param) 527 std::string form_query_string (const Cell& param)
528 { 528 {
529 std::ostringstream query; 529 std::ostringstream query;
530 530
531 for (int i = 0; i < param.numel (); i += 2) 531 for (int i = 0; i < param.numel (); i += 2)
532 { 532 {
533 std::string name = param(i).string_value (); 533 std::string name = param(i).string_value ();
534 std::string text = param(i+1).string_value (); 534 std::string text = param(i+1).string_value ();
535 535
536 // Encode strings. 536 // Encode strings.
537 char *enc_name = curl_easy_escape (rep->handle(), name.c_str (), 537 char *enc_name = curl_easy_escape (rep->handle(), name.c_str (),
538 name.length ()); 538 name.length ());
539 char *enc_text = curl_easy_escape (rep->handle(), text.c_str (), 539 char *enc_text = curl_easy_escape (rep->handle(), text.c_str (),
540 text.length ()); 540 text.length ());
541 541
542 query << enc_name << "=" << enc_text; 542 query << enc_name << "=" << enc_text;
543 543
544 curl_free (enc_name); 544 curl_free (enc_name);
545 curl_free (enc_text); 545 curl_free (enc_text);
546 546
547 if (i < param.numel()-1) 547 if (i < param.numel()-1)
548 query << "&"; 548 query << "&";
549 } 549 }
550 550
551 query.flush (); 551 query.flush ();
552 552
553 return query.str (); 553 return query.str ();
554 } 554 }
555 555
556 void init (const std::string& user, const std::string& passwd, 556 void init (const std::string& user, const std::string& passwd,
557 std::istream& is, std::ostream& os) 557 std::istream& is, std::ostream& os)
558 { 558 {
559 // No data transfer by default 559 // No data transfer by default
560 setopt (CURLOPT_NOBODY, 1); 560 setopt (CURLOPT_NOBODY, 1);
561 561
562 // Set the username and password 562 // Set the username and password
563 std::string userpwd = user; 563 std::string userpwd = user;
564 if (! passwd.empty ()) 564 if (! passwd.empty ())
565 userpwd += ":" + passwd; 565 userpwd += ":" + passwd;
566 setopt (CURLOPT_USERPWD, userpwd.c_str ()); 566 setopt (CURLOPT_USERPWD, userpwd.c_str ());
567 567
568 // Define our callback to get called when there's data to be written. 568 // Define our callback to get called when there's data to be written.
569 setopt (CURLOPT_WRITEFUNCTION, write_data); 569 setopt (CURLOPT_WRITEFUNCTION, write_data);
570 570
611 ~curl_handles (void) 611 ~curl_handles (void)
612 { 612 {
613 // Remove the elements of the map explicitly as they should 613 // Remove the elements of the map explicitly as they should
614 // be deleted before the call to curl_global_cleanup 614 // be deleted before the call to curl_global_cleanup
615 for (iterator pa = begin (); pa != end (); pa++) 615 for (iterator pa = begin (); pa != end (); pa++)
616 map.erase (pa); 616 map.erase (pa);
617 617
618 curl_global_cleanup (); 618 curl_global_cleanup ();
619 } 619 }
620 620
621 iterator begin (void) { return iterator (map.begin ()); } 621 iterator begin (void) { return iterator (map.begin ()); }
649 void del (const std::string& k) 649 void del (const std::string& k)
650 { 650 {
651 iterator p = map.find (k); 651 iterator p = map.find (k);
652 652
653 if (p != map.end ()) 653 if (p != map.end ())
654 map.erase (p); 654 map.erase (p);
655 } 655 }
656 656
657 private: 657 private:
658 std::map<std::string, curl_handle> map; 658 std::map<std::string, curl_handle> map;
659 }; 659 };
767 error ("urlwrite: method can only be \"get\" or \"post\""); 767 error ("urlwrite: method can only be \"get\" or \"post\"");
768 return retval; 768 return retval;
769 } 769 }
770 770
771 if (method != "get" && method != "post") 771 if (method != "get" && method != "post")
772 { 772 {
773 error ("urlwrite: method can only be \"get\" or \"post\""); 773 error ("urlwrite: method can only be \"get\" or \"post\"");
774 return retval; 774 return retval;
775 } 775 }
776 776
777 param = args(3).cell_value(); 777 param = args(3).cell_value();
778 778
779 if (error_state) 779 if (error_state)
780 { 780 {
781 error ("urlwrite: parameters for get and post requests must be given as a cell"); 781 error ("urlwrite: parameters for get and post requests must be given as a cell");
782 return retval; 782 return retval;
783 } 783 }
784 784
785 785
786 if (param.numel () % 2 == 1 ) 786 if (param.numel () % 2 == 1 )
787 { 787 {
788 error ("urlwrite: number of elements in param must be even"); 788 error ("urlwrite: number of elements in param must be even");
789 return retval; 789 return retval;
790 } 790 }
791 } 791 }
792 792
793 // The file should only be deleted if it doesn't initially exist, we 793 // The file should only be deleted if it doesn't initially exist, we
794 // create it, and the download fails. We use unwind_protect to do 794 // create it, and the download fails. We use unwind_protect to do
795 // it so that the deletion happens no matter how we exit the function. 795 // it so that the deletion happens no matter how we exit the function.
819 frame.run (); 819 frame.run ();
820 820
821 if (nargout > 0) 821 if (nargout > 0)
822 { 822 {
823 if (res) 823 if (res)
824 { 824 {
825 retval(2) = std::string (); 825 retval(2) = std::string ();
826 retval(1) = true; 826 retval(1) = true;
827 retval(0) = octave_env::make_absolute (filename, octave_env::getcwd ()); 827 retval(0) = octave_env::make_absolute (filename, octave_env::getcwd ());
828 } 828 }
829 else 829 else
830 { 830 {
831 retval(2) = curl.lasterror (); 831 retval(2) = curl.lasterror ();
832 retval(1) = false; 832 retval(1) = false;
833 retval(0) = std::string (); 833 retval(0) = std::string ();
834 } 834 }
835 } 835 }
836 836
837 if (nargout < 2 && res) 837 if (nargout < 2 && res)
838 error ("urlwrite: curl: %s", curl.lasterror ().c_str ()); 838 error ("urlwrite: curl: %s", curl.lasterror ().c_str ());
839 839
912 if (nargin == 3) 912 if (nargin == 3)
913 { 913 {
914 method = args(1).string_value(); 914 method = args(1).string_value();
915 915
916 if (error_state) 916 if (error_state)
917 { 917 {
918 error ("urlread: method can only be \"get\" or \"post\""); 918 error ("urlread: method can only be \"get\" or \"post\"");
919 return retval; 919 return retval;
920 } 920 }
921 921
922 if (method != "get" && method != "post") 922 if (method != "get" && method != "post")
923 { 923 {
924 error ("urlread: method can only be \"get\" or \"post\""); 924 error ("urlread: method can only be \"get\" or \"post\"");
925 return retval; 925 return retval;
926 } 926 }
927 927
928 param = args(2).cell_value(); 928 param = args(2).cell_value();
929 929
930 if (error_state) 930 if (error_state)
931 { 931 {
932 error ("urlread: parameters for get and post requests must be given as a cell"); 932 error ("urlread: parameters for get and post requests must be given as a cell");
933 return retval; 933 return retval;
934 } 934 }
935 935
936 if (param.numel () % 2 == 1 ) 936 if (param.numel () % 2 == 1 )
937 { 937 {
938 error ("urlread: number of elements in param must be even"); 938 error ("urlread: number of elements in param must be even");
939 return retval; 939 return retval;
940 } 940 }
941 } 941 }
942 942
943 std::ostringstream buf; 943 std::ostringstream buf;
944 944
945 bool res; 945 bool res;
983 { 983 {
984 handle = args(0).string_value (); 984 handle = args(0).string_value ();
985 host = args(1).string_value (); 985 host = args(1).string_value ();
986 986
987 if (nargin > 1) 987 if (nargin > 1)
988 user = args(2).string_value (); 988 user = args(2).string_value ();
989 989
990 if (nargin > 2) 990 if (nargin > 2)
991 passwd = args(3).string_value (); 991 passwd = args(3).string_value ();
992 992
993 if (!error_state) 993 if (!error_state)
994 { 994 {
995 handles.contents (handle) = curl_handle (host, user, passwd); 995 handles.contents (handle) = curl_handle (host, user, passwd);
996 996
997 if (error_state) 997 if (error_state)
998 handles.del (handle); 998 handles.del (handle);
999 } 999 }
1000 } 1000 }
1001 #else 1001 #else
1002 error ("__ftp__: not available in this version of Octave"); 1002 error ("__ftp__: not available in this version of Octave");
1003 #endif 1003 #endif
1004 1004
1020 else 1020 else
1021 { 1021 {
1022 std::string handle = args(0).string_value (); 1022 std::string handle = args(0).string_value ();
1023 1023
1024 if (!error_state) 1024 if (!error_state)
1025 { 1025 {
1026 const curl_handle curl = handles.contents (handle); 1026 const curl_handle curl = handles.contents (handle);
1027 1027
1028 if (curl.is_valid ()) 1028 if (curl.is_valid ())
1029 retval = curl.pwd (); 1029 retval = curl.pwd ();
1030 else 1030 else
1031 error ("__ftp_pwd__: invalid ftp handle"); 1031 error ("__ftp_pwd__: invalid ftp handle");
1032 } 1032 }
1033 } 1033 }
1034 #else 1034 #else
1035 error ("__ftp_pwd__: not available in this version of Octave"); 1035 error ("__ftp_pwd__: not available in this version of Octave");
1036 #endif 1036 #endif
1037 1037
1053 { 1053 {
1054 std::string handle = args(0).string_value (); 1054 std::string handle = args(0).string_value ();
1055 std::string path = ""; 1055 std::string path = "";
1056 1056
1057 if (nargin > 1) 1057 if (nargin > 1)
1058 path = args(1).string_value (); 1058 path = args(1).string_value ();
1059 1059
1060 if (!error_state) 1060 if (!error_state)
1061 { 1061 {
1062 const curl_handle curl = handles.contents (handle); 1062 const curl_handle curl = handles.contents (handle);
1063 1063
1064 if (curl.is_valid ()) 1064 if (curl.is_valid ())
1065 curl.cwd (path); 1065 curl.cwd (path);
1066 else 1066 else
1067 error ("__ftp_cwd__: invalid ftp handle"); 1067 error ("__ftp_cwd__: invalid ftp handle");
1068 } 1068 }
1069 } 1069 }
1070 #else 1070 #else
1071 error ("__ftp_cwd__: not available in this version of Octave"); 1071 error ("__ftp_cwd__: not available in this version of Octave");
1072 #endif 1072 #endif
1073 1073
1089 else 1089 else
1090 { 1090 {
1091 std::string handle = args(0).string_value (); 1091 std::string handle = args(0).string_value ();
1092 1092
1093 if (!error_state) 1093 if (!error_state)
1094 { 1094 {
1095 const curl_handle curl = handles.contents (handle); 1095 const curl_handle curl = handles.contents (handle);
1096 1096
1097 if (curl.is_valid ()) 1097 if (curl.is_valid ())
1098 { 1098 {
1099 if (nargout == 0) 1099 if (nargout == 0)
1100 curl.dir (); 1100 curl.dir ();
1101 else 1101 else
1102 { 1102 {
1103 string_vector sv = curl.list (); 1103 string_vector sv = curl.list ();
1104 octave_idx_type n = sv.length (); 1104 octave_idx_type n = sv.length ();
1105 if (n == 0) 1105 if (n == 0)
1106 { 1106 {
1107 string_vector flds (5); 1107 string_vector flds (5);
1108 flds(0) = "name"; 1108 flds(0) = "name";
1109 flds(1) = "date"; 1109 flds(1) = "date";
1110 flds(2) = "bytes"; 1110 flds(2) = "bytes";
1111 flds(3) = "isdir"; 1111 flds(3) = "isdir";
1112 flds(4) = "datenum"; 1112 flds(4) = "datenum";
1113 retval = Octave_map (flds); 1113 retval = Octave_map (flds);
1114 } 1114 }
1115 else 1115 else
1116 { 1116 {
1117 Octave_map st; 1117 Octave_map st;
1118 Cell filectime (dim_vector (n, 1)); 1118 Cell filectime (dim_vector (n, 1));
1119 Cell filesize (dim_vector (n, 1)); 1119 Cell filesize (dim_vector (n, 1));
1120 Cell fileisdir (dim_vector (n, 1)); 1120 Cell fileisdir (dim_vector (n, 1));
1121 Cell filedatenum (dim_vector (n, 1)); 1121 Cell filedatenum (dim_vector (n, 1));
1122 1122
1123 st.assign ("name", Cell (sv)); 1123 st.assign ("name", Cell (sv));
1124 1124
1125 for (octave_idx_type i = 0; i < n; i++) 1125 for (octave_idx_type i = 0; i < n; i++)
1126 { 1126 {
1127 time_t ftime; 1127 time_t ftime;
1128 bool fisdir; 1128 bool fisdir;
1129 double fsize; 1129 double fsize;
1130 1130
1131 curl.get_fileinfo (sv(i), fsize, ftime, fisdir); 1131 curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
1132 1132
1133 fileisdir (i) = fisdir; 1133 fileisdir (i) = fisdir;
1134 filectime (i) = ctime (&ftime); 1134 filectime (i) = ctime (&ftime);
1135 filesize (i) = fsize; 1135 filesize (i) = fsize;
1136 filedatenum (i) = double (ftime); 1136 filedatenum (i) = double (ftime);
1137 } 1137 }
1138 st.assign ("date", filectime); 1138 st.assign ("date", filectime);
1139 st.assign ("bytes", filesize); 1139 st.assign ("bytes", filesize);
1140 st.assign ("isdir", fileisdir); 1140 st.assign ("isdir", fileisdir);
1141 st.assign ("datenum", filedatenum); 1141 st.assign ("datenum", filedatenum);
1142 retval = st; 1142 retval = st;
1143 } 1143 }
1144 } 1144 }
1145 } 1145 }
1146 else 1146 else
1147 error ("__ftp_dir__: invalid ftp handle"); 1147 error ("__ftp_dir__: invalid ftp handle");
1148 } 1148 }
1149 } 1149 }
1150 #else 1150 #else
1151 error ("__ftp_dir__: not available in this version of Octave"); 1151 error ("__ftp_dir__: not available in this version of Octave");
1152 #endif 1152 #endif
1153 1153
1168 else 1168 else
1169 { 1169 {
1170 std::string handle = args(0).string_value (); 1170 std::string handle = args(0).string_value ();
1171 1171
1172 if (!error_state) 1172 if (!error_state)
1173 { 1173 {
1174 const curl_handle curl = handles.contents (handle); 1174 const curl_handle curl = handles.contents (handle);
1175 1175
1176 if (curl.is_valid ()) 1176 if (curl.is_valid ())
1177 curl.ascii (); 1177 curl.ascii ();
1178 else 1178 else
1179 error ("__ftp_ascii__: invalid ftp handle"); 1179 error ("__ftp_ascii__: invalid ftp handle");
1180 } 1180 }
1181 } 1181 }
1182 #else 1182 #else
1183 error ("__ftp_ascii__: not available in this version of Octave"); 1183 error ("__ftp_ascii__: not available in this version of Octave");
1184 #endif 1184 #endif
1185 1185
1200 else 1200 else
1201 { 1201 {
1202 std::string handle = args(0).string_value (); 1202 std::string handle = args(0).string_value ();
1203 1203
1204 if (!error_state) 1204 if (!error_state)
1205 { 1205 {
1206 const curl_handle curl = handles.contents (handle); 1206 const curl_handle curl = handles.contents (handle);
1207 1207
1208 if (curl.is_valid ()) 1208 if (curl.is_valid ())
1209 curl.binary (); 1209 curl.binary ();
1210 else 1210 else
1211 error ("__ftp_binary__: invalid ftp handle"); 1211 error ("__ftp_binary__: invalid ftp handle");
1212 } 1212 }
1213 } 1213 }
1214 #else 1214 #else
1215 error ("__ftp_binary__: not available in this version of Octave"); 1215 error ("__ftp_binary__: not available in this version of Octave");
1216 #endif 1216 #endif
1217 1217
1232 else 1232 else
1233 { 1233 {
1234 std::string handle = args(0).string_value (); 1234 std::string handle = args(0).string_value ();
1235 1235
1236 if (!error_state) 1236 if (!error_state)
1237 handles.del (handle); 1237 handles.del (handle);
1238 } 1238 }
1239 #else 1239 #else
1240 error ("__ftp_close__: not available in this version of Octave"); 1240 error ("__ftp_close__: not available in this version of Octave");
1241 #endif 1241 #endif
1242 1242
1259 { 1259 {
1260 std::string handle = args(0).string_value (); 1260 std::string handle = args(0).string_value ();
1261 1261
1262 1262
1263 if (!error_state) 1263 if (!error_state)
1264 { 1264 {
1265 const curl_handle curl = handles.contents (handle); 1265 const curl_handle curl = handles.contents (handle);
1266 1266
1267 if (curl.is_valid ()) 1267 if (curl.is_valid ())
1268 retval = (curl.is_ascii() ? "ascii" : "binary"); 1268 retval = (curl.is_ascii() ? "ascii" : "binary");
1269 else 1269 else
1270 error ("__ftp_binary__: invalid ftp handle"); 1270 error ("__ftp_binary__: invalid ftp handle");
1271 } 1271 }
1272 } 1272 }
1273 #else 1273 #else
1274 error ("__ftp_mode__: not available in this version of Octave"); 1274 error ("__ftp_mode__: not available in this version of Octave");
1275 #endif 1275 #endif
1276 1276
1292 { 1292 {
1293 std::string handle = args(0).string_value (); 1293 std::string handle = args(0).string_value ();
1294 std::string file = args(1).string_value (); 1294 std::string file = args(1).string_value ();
1295 1295
1296 if (!error_state) 1296 if (!error_state)
1297 { 1297 {
1298 const curl_handle curl = handles.contents (handle); 1298 const curl_handle curl = handles.contents (handle);
1299 1299
1300 if (curl.is_valid ()) 1300 if (curl.is_valid ())
1301 curl.del (file); 1301 curl.del (file);
1302 else 1302 else
1303 error ("__ftp_delete__: invalid ftp handle"); 1303 error ("__ftp_delete__: invalid ftp handle");
1304 } 1304 }
1305 } 1305 }
1306 #else 1306 #else
1307 error ("__ftp_delete__: not available in this version of Octave"); 1307 error ("__ftp_delete__: not available in this version of Octave");
1308 #endif 1308 #endif
1309 1309
1325 { 1325 {
1326 std::string handle = args(0).string_value (); 1326 std::string handle = args(0).string_value ();
1327 std::string dir = args(1).string_value (); 1327 std::string dir = args(1).string_value ();
1328 1328
1329 if (!error_state) 1329 if (!error_state)
1330 { 1330 {
1331 const curl_handle curl = handles.contents (handle); 1331 const curl_handle curl = handles.contents (handle);
1332 1332
1333 if (curl.is_valid ()) 1333 if (curl.is_valid ())
1334 curl.rmdir (dir); 1334 curl.rmdir (dir);
1335 else 1335 else
1336 error ("__ftp_rmdir__: invalid ftp handle"); 1336 error ("__ftp_rmdir__: invalid ftp handle");
1337 } 1337 }
1338 } 1338 }
1339 #else 1339 #else
1340 error ("__ftp_rmdir__: not available in this version of Octave"); 1340 error ("__ftp_rmdir__: not available in this version of Octave");
1341 #endif 1341 #endif
1342 1342
1358 { 1358 {
1359 std::string handle = args(0).string_value (); 1359 std::string handle = args(0).string_value ();
1360 std::string dir = args(1).string_value (); 1360 std::string dir = args(1).string_value ();
1361 1361
1362 if (!error_state) 1362 if (!error_state)
1363 { 1363 {
1364 const curl_handle curl = handles.contents (handle); 1364 const curl_handle curl = handles.contents (handle);
1365 1365
1366 if (curl.is_valid ()) 1366 if (curl.is_valid ())
1367 curl.mkdir (dir); 1367 curl.mkdir (dir);
1368 else 1368 else
1369 error ("__ftp_mkdir__: invalid ftp handle"); 1369 error ("__ftp_mkdir__: invalid ftp handle");
1370 } 1370 }
1371 } 1371 }
1372 #else 1372 #else
1373 error ("__ftp_mkdir__: not available in this version of Octave"); 1373 error ("__ftp_mkdir__: not available in this version of Octave");
1374 #endif 1374 #endif
1375 1375
1392 std::string handle = args(0).string_value (); 1392 std::string handle = args(0).string_value ();
1393 std::string oldname = args(1).string_value (); 1393 std::string oldname = args(1).string_value ();
1394 std::string newname = args(2).string_value (); 1394 std::string newname = args(2).string_value ();
1395 1395
1396 if (!error_state) 1396 if (!error_state)
1397 { 1397 {
1398 const curl_handle curl = handles.contents (handle); 1398 const curl_handle curl = handles.contents (handle);
1399 1399
1400 if (curl.is_valid ()) 1400 if (curl.is_valid ())
1401 curl.rename (oldname, newname); 1401 curl.rename (oldname, newname);
1402 else 1402 else
1403 error ("__ftp_rename__: invalid ftp handle"); 1403 error ("__ftp_rename__: invalid ftp handle");
1404 } 1404 }
1405 } 1405 }
1406 #else 1406 #else
1407 error ("__ftp_rename__: not available in this version of Octave"); 1407 error ("__ftp_rename__: not available in this version of Octave");
1408 #endif 1408 #endif
1409 1409
1411 } 1411 }
1412 1412
1413 #ifdef HAVE_CURL 1413 #ifdef HAVE_CURL
1414 static string_vector 1414 static string_vector
1415 mput_directory (const curl_handle& curl, const std::string& base, 1415 mput_directory (const curl_handle& curl, const std::string& base,
1416 const std::string& dir) 1416 const std::string& dir)
1417 { 1417 {
1418 string_vector retval; 1418 string_vector retval;
1419 1419
1420 if (! curl.mkdir (dir, false)) 1420 if (! curl.mkdir (dir, false))
1421 warning ("__ftp_mput__: can not create the remote directory ""%s""", 1421 warning ("__ftp_mput__: can not create the remote directory ""%s""",
1422 (base.length() == 0 ? dir : base + 1422 (base.length() == 0 ? dir : base +
1423 file_ops::dir_sep_str () + dir).c_str ()); 1423 file_ops::dir_sep_str () + dir).c_str ());
1424 1424
1425 curl.cwd (dir); 1425 curl.cwd (dir);
1426 1426
1427 if (! error_state) 1427 if (! error_state)
1428 { 1428 {
1429 unwind_protect_safe frame; 1429 unwind_protect_safe frame;
1430 1430
1431 frame.add_fcn (reset_path, curl); 1431 frame.add_fcn (reset_path, curl);
1432 1432
1433 std::string realdir = base.length() == 0 ? dir : base + 1433 std::string realdir = base.length() == 0 ? dir : base +
1434 file_ops::dir_sep_str () + dir; 1434 file_ops::dir_sep_str () + dir;
1435 1435
1436 dir_entry dirlist (realdir); 1436 dir_entry dirlist (realdir);
1437 1437
1438 if (dirlist) 1438 if (dirlist)
1439 { 1439 {
1440 string_vector files = dirlist.read (); 1440 string_vector files = dirlist.read ();
1441 1441
1442 for (octave_idx_type i = 0; i < files.length (); i++) 1442 for (octave_idx_type i = 0; i < files.length (); i++)
1443 { 1443 {
1444 std::string file = files (i); 1444 std::string file = files (i);
1445 1445
1446 if (file == "." || file == "..") 1446 if (file == "." || file == "..")
1447 continue; 1447 continue;
1448 1448
1449 std::string realfile = realdir + file_ops::dir_sep_str () + file; 1449 std::string realfile = realdir + file_ops::dir_sep_str () + file;
1450 file_stat fs (realfile); 1450 file_stat fs (realfile);
1451 1451
1452 if (! fs.exists ()) 1452 if (! fs.exists ())
1453 { 1453 {
1454 error ("__ftp__mput: file ""%s"" does not exist", 1454 error ("__ftp__mput: file ""%s"" does not exist",
1455 realfile.c_str ()); 1455 realfile.c_str ());
1456 break; 1456 break;
1457 } 1457 }
1458 1458
1459 if (fs.is_dir ()) 1459 if (fs.is_dir ())
1460 { 1460 {
1461 retval.append (mput_directory (curl, realdir, file)); 1461 retval.append (mput_directory (curl, realdir, file));
1462 1462
1463 if (error_state) 1463 if (error_state)
1464 break; 1464 break;
1465 } 1465 }
1466 else 1466 else
1467 { 1467 {
1468 // FIXME Does ascii mode need to be flagged here? 1468 // FIXME Does ascii mode need to be flagged here?
1469 std::ifstream ifile (realfile.c_str(), std::ios::in | 1469 std::ifstream ifile (realfile.c_str(), std::ios::in |
1470 std::ios::binary); 1470 std::ios::binary);
1471 1471
1472 if (! ifile.is_open ()) 1472 if (! ifile.is_open ())
1473 { 1473 {
1474 error ("__ftp_mput__: unable to open file ""%s""", 1474 error ("__ftp_mput__: unable to open file ""%s""",
1475 realfile.c_str ()); 1475 realfile.c_str ());
1476 break; 1476 break;
1477 } 1477 }
1478 1478
1479 curl.put (file, ifile); 1479 curl.put (file, ifile);
1480 1480
1481 ifile.close (); 1481 ifile.close ();
1482 1482
1483 if (error_state) 1483 if (error_state)
1484 break; 1484 break;
1485 1485
1486 retval.append (realfile); 1486 retval.append (realfile);
1487 } 1487 }
1488 } 1488 }
1489 } 1489 }
1490 else 1490 else
1491 error ("__ftp_mput__: can not read the directory ""%s""", 1491 error ("__ftp_mput__: can not read the directory ""%s""",
1492 realdir.c_str()); 1492 realdir.c_str());
1493 } 1493 }
1494 1494
1495 return retval; 1495 return retval;
1496 } 1496 }
1497 #endif 1497 #endif
1513 { 1513 {
1514 std::string handle = args(0).string_value (); 1514 std::string handle = args(0).string_value ();
1515 std::string pat = args(1).string_value (); 1515 std::string pat = args(1).string_value ();
1516 1516
1517 if (!error_state) 1517 if (!error_state)
1518 { 1518 {
1519 const curl_handle curl = handles.contents (handle); 1519 const curl_handle curl = handles.contents (handle);
1520 1520
1521 if (curl.is_valid ()) 1521 if (curl.is_valid ())
1522 { 1522 {
1523 glob_match pattern (file_ops::tilde_expand (pat)); 1523 glob_match pattern (file_ops::tilde_expand (pat));
1524 string_vector files = pattern.glob (); 1524 string_vector files = pattern.glob ();
1525 1525
1526 for (octave_idx_type i = 0; i < files.length (); i++) 1526 for (octave_idx_type i = 0; i < files.length (); i++)
1527 { 1527 {
1528 std::string file = files (i); 1528 std::string file = files (i);
1529 1529
1530 file_stat fs (file); 1530 file_stat fs (file);
1531 1531
1532 if (! fs.exists ()) 1532 if (! fs.exists ())
1533 { 1533 {
1534 error ("__ftp__mput: file does not exist"); 1534 error ("__ftp__mput: file does not exist");
1535 break; 1535 break;
1536 } 1536 }
1537 1537
1538 if (fs.is_dir ()) 1538 if (fs.is_dir ())
1539 { 1539 {
1540 retval.append (mput_directory (curl, "", file)); 1540 retval.append (mput_directory (curl, "", file));
1541 if (error_state) 1541 if (error_state)
1542 break; 1542 break;
1543 } 1543 }
1544 else 1544 else
1545 { 1545 {
1546 // FIXME Does ascii mode need to be flagged here? 1546 // FIXME Does ascii mode need to be flagged here?
1547 std::ifstream ifile (file.c_str(), std::ios::in | 1547 std::ifstream ifile (file.c_str(), std::ios::in |
1548 std::ios::binary); 1548 std::ios::binary);
1549 1549
1550 if (! ifile.is_open ()) 1550 if (! ifile.is_open ())
1551 { 1551 {
1552 error ("__ftp_mput__: unable to open file"); 1552 error ("__ftp_mput__: unable to open file");
1553 break; 1553 break;
1554 } 1554 }
1555 1555
1556 curl.put (file, ifile); 1556 curl.put (file, ifile);
1557 1557
1558 ifile.close (); 1558 ifile.close ();
1559 1559
1560 if (error_state) 1560 if (error_state)
1561 break; 1561 break;
1562 1562
1563 retval.append (file); 1563 retval.append (file);
1564 } 1564 }
1565 } 1565 }
1566 } 1566 }
1567 else 1567 else
1568 error ("__ftp_mput__: invalid ftp handle"); 1568 error ("__ftp_mput__: invalid ftp handle");
1569 } 1569 }
1570 } 1570 }
1571 #else 1571 #else
1572 error ("__ftp_mput__: not available in this version of Octave"); 1572 error ("__ftp_mput__: not available in this version of Octave");
1573 #endif 1573 #endif
1574 1574
1576 } 1576 }
1577 1577
1578 #ifdef HAVE_CURL 1578 #ifdef HAVE_CURL
1579 static void 1579 static void
1580 getallfiles (const curl_handle& curl, const std::string& dir, 1580 getallfiles (const curl_handle& curl, const std::string& dir,
1581 const std::string& target) 1581 const std::string& target)
1582 { 1582 {
1583 std::string sep = file_ops::dir_sep_str (); 1583 std::string sep = file_ops::dir_sep_str ();
1584 file_stat fs (dir); 1584 file_stat fs (dir);
1585 1585
1586 if (!fs || !fs.is_dir ()) 1586 if (!fs || !fs.is_dir ())
1587 { 1587 {
1588 std::string msg; 1588 std::string msg;
1589 int status = file_ops::mkdir (dir, 0777, msg); 1589 int status = file_ops::mkdir (dir, 0777, msg);
1590 1590
1591 if (status < 0) 1591 if (status < 0)
1592 error ("__ftp_mget__: can't create directory %s%s%s. %s", 1592 error ("__ftp_mget__: can't create directory %s%s%s. %s",
1593 target.c_str(), sep.c_str(), dir.c_str(), msg.c_str()); 1593 target.c_str(), sep.c_str(), dir.c_str(), msg.c_str());
1594 } 1594 }
1595 1595
1596 if (! error_state) 1596 if (! error_state)
1597 { 1597 {
1598 curl.cwd (dir); 1598 curl.cwd (dir);
1599 1599
1600 if (! error_state) 1600 if (! error_state)
1601 { 1601 {
1602 unwind_protect_safe frame; 1602 unwind_protect_safe frame;
1603 1603
1604 frame.add_fcn (reset_path, curl); 1604 frame.add_fcn (reset_path, curl);
1605 1605
1606 string_vector sv = curl.list (); 1606 string_vector sv = curl.list ();
1607 1607
1608 for (octave_idx_type i = 0; i < sv.length (); i++) 1608 for (octave_idx_type i = 0; i < sv.length (); i++)
1609 { 1609 {
1610 time_t ftime; 1610 time_t ftime;
1611 bool fisdir; 1611 bool fisdir;
1612 double fsize; 1612 double fsize;
1613 1613
1614 curl.get_fileinfo (sv(i), fsize, ftime, fisdir); 1614 curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
1615 1615
1616 if (fisdir) 1616 if (fisdir)
1617 getallfiles (curl, sv(i), target + dir + sep); 1617 getallfiles (curl, sv(i), target + dir + sep);
1618 else 1618 else
1619 { 1619 {
1620 std::string realfile = target + dir + sep + sv(i); 1620 std::string realfile = target + dir + sep + sv(i);
1621 std::ofstream ofile (realfile.c_str(), 1621 std::ofstream ofile (realfile.c_str(),
1622 std::ios::out | 1622 std::ios::out |
1623 std::ios::binary); 1623 std::ios::binary);
1624 1624
1625 if (! ofile.is_open ()) 1625 if (! ofile.is_open ())
1626 { 1626 {
1627 error ("__ftp_mget__: unable to open file"); 1627 error ("__ftp_mget__: unable to open file");
1628 break; 1628 break;
1629 } 1629 }
1630 1630
1631 unwind_protect_safe frame2; 1631 unwind_protect_safe frame2;
1632 1632
1633 frame2.add_fcn (delete_file, realfile); 1633 frame2.add_fcn (delete_file, realfile);
1634 1634
1635 curl.get (sv(i), ofile); 1635 curl.get (sv(i), ofile);
1636 1636
1637 ofile.close (); 1637 ofile.close ();
1638 1638
1639 if (!error_state) 1639 if (!error_state)
1640 frame2.discard (); 1640 frame2.discard ();
1641 else 1641 else
1642 frame2.run (); 1642 frame2.run ();
1643 } 1643 }
1644 1644
1645 if (error_state) 1645 if (error_state)
1646 break; 1646 break;
1647 } 1647 }
1648 } 1648 }
1649 } 1649 }
1650 } 1650 }
1651 #endif 1651 #endif
1652 1652
1653 DEFUN_DLD (__ftp_mget__, args, , 1653 DEFUN_DLD (__ftp_mget__, args, ,
1666 std::string handle = args(0).string_value (); 1666 std::string handle = args(0).string_value ();
1667 std::string file = args(1).string_value (); 1667 std::string file = args(1).string_value ();
1668 std::string target; 1668 std::string target;
1669 1669
1670 if (nargin == 3) 1670 if (nargin == 3)
1671 target = args(2).string_value () + file_ops::dir_sep_str (); 1671 target = args(2).string_value () + file_ops::dir_sep_str ();
1672 1672
1673 if (! error_state) 1673 if (! error_state)
1674 { 1674 {
1675 const curl_handle curl = handles.contents (handle); 1675 const curl_handle curl = handles.contents (handle);
1676 1676
1677 if (curl.is_valid ()) 1677 if (curl.is_valid ())
1678 { 1678 {
1679 string_vector sv = curl.list (); 1679 string_vector sv = curl.list ();
1680 octave_idx_type n = 0; 1680 octave_idx_type n = 0;
1681 glob_match pattern (file); 1681 glob_match pattern (file);
1682 1682
1683 for (octave_idx_type i = 0; i < sv.length (); i++) 1683 for (octave_idx_type i = 0; i < sv.length (); i++)
1684 { 1684 {
1685 if (pattern.match (sv(i))) 1685 if (pattern.match (sv(i)))
1686 { 1686 {
1687 n++; 1687 n++;
1688 1688
1689 time_t ftime; 1689 time_t ftime;
1690 bool fisdir; 1690 bool fisdir;
1691 double fsize; 1691 double fsize;
1692 1692
1693 curl.get_fileinfo (sv(i), fsize, ftime, fisdir); 1693 curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
1694 1694
1695 if (fisdir) 1695 if (fisdir)
1696 getallfiles (curl, sv(i), target); 1696 getallfiles (curl, sv(i), target);
1697 else 1697 else
1698 { 1698 {
1699 std::ofstream ofile ((target + sv(i)).c_str(), 1699 std::ofstream ofile ((target + sv(i)).c_str(),
1700 std::ios::out | 1700 std::ios::out |
1701 std::ios::binary); 1701 std::ios::binary);
1702 1702
1703 if (! ofile.is_open ()) 1703 if (! ofile.is_open ())
1704 { 1704 {
1705 error ("__ftp_mget__: unable to open file"); 1705 error ("__ftp_mget__: unable to open file");
1706 break; 1706 break;
1707 } 1707 }
1708 1708
1709 unwind_protect_safe frame; 1709 unwind_protect_safe frame;
1710 1710
1711 frame.add_fcn (delete_file, target + sv(i)); 1711 frame.add_fcn (delete_file, target + sv(i));
1712 1712
1713 curl.get (sv(i), ofile); 1713 curl.get (sv(i), ofile);
1714 1714
1715 ofile.close (); 1715 ofile.close ();
1716 1716
1717 if (!error_state) 1717 if (!error_state)
1718 frame.discard (); 1718 frame.discard ();
1719 else 1719 else
1720 frame.run (); 1720 frame.run ();
1721 } 1721 }
1722 1722
1723 if (error_state) 1723 if (error_state)
1724 break; 1724 break;
1725 } 1725 }
1726 } 1726 }
1727 if (n == 0) 1727 if (n == 0)
1728 error ("__ftp_mget__: file not found"); 1728 error ("__ftp_mget__: file not found");
1729 } 1729 }
1730 } 1730 }
1731 } 1731 }
1732 #else 1732 #else
1733 error ("__ftp_mget__: not available in this version of Octave"); 1733 error ("__ftp_mget__: not available in this version of Octave");
1734 #endif 1734 #endif
1735 1735