[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
front-end of libcurl
From: |
Alexander Barth |
Subject: |
front-end of libcurl |
Date: |
Wed, 27 Sep 2006 12:08:23 -0400 |
User-agent: |
Thunderbird 1.5.0.7 (X11/20060913) |
Hi all,
I wrote a front-end of libcurl to download files from a web or ftp server. This
syntax is quite
straight forward:
download('url','localfile');
The error handling is similar to the copyfile function in matlab.
The attached source can be compiled with:
mkoctfile download.cc `curl-config --cflags --libs`
This function may be useful for the package manager. Like rpm is able to
install a package from a
web-server (for example: rpm -ihv http://example.com/package.rpm), a similar
functionality could be
added to pkg.m
I would be glad if this function would be considered for inclusion in octave or
octave-forge. If
octave-forge turns out to be the appropriate place, I can add it myself, maybe
in main/miscellaneous.
Cheers,
Alex
--
_______________________________________________________________
Alexander Barth
Ocean Circulation Group
University of South Florida
College of Marine Science
140 Seventh Avenue South
St. Petersburg, Florida 33701
USA
Phone: +1-727-553-3508 FAX: +1-727-553-1189
_______________________________________________________________
/*
download, a curl front-end for octave
Copyright (C) 2006 Alexander Barth <address@hidden>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
*/
/*
Compile with:
mkoctfile download.cc `curl-config --cflags --libs`
*/
#include <octave/oct.h>
#include <stdio.h>
#include <string>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
using namespace std;
struct FileStruct {
string filename;
FILE *stream;
};
// write callback function
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FileStruct *out=(struct FileStruct *)stream;
if(out && !out->stream) {
// printf("file %s\n",out->filename.c_str());
// open file for writing
out->stream=fopen(out->filename.c_str(), "wb");
if(!out->stream)
return -1; // failure, can't open file to write
}
return fwrite(buffer, size, nmemb, out->stream);
}
// progress callback function
int my_progress_func(char *url,
double dltotal,
double dlnow,
double ultotal,
double ulnow)
{
// macro that picks up Ctrl-C signalling
OCTAVE_QUIT;
printf("\r%s: ",url);
if (dltotal != 0) {
printf("%4.1f %%",dlnow*100.0/dltotal);
}
fflush(stdout);
return 0;
}
DEFUN_DLD (download, args, nargout,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {} download(@var{URL},@var{localfile}) \n\
@deftypefnx {Loadable Function} address@hidden,@var{message] =}
download(@var{url},@var{localfile})} \n\
Downloads a remote file specified by its @var{URL} and saves it as
@var{localfile}. \n\n\
Example: \n\
@example \n\
download('ftp://ftp.octave.org/pub/octave/README','README.txt'); \n\
@end example \n\n\
The variable @var{success} is 1 if the download was successful, otherwise it \n\
is 0 in which case @var{message} contains the error message. If no output
argument \n\
is specified and if an error occurs, then the error is signaled throught \n\
octave's error handling mechanism. \n\
\n\
This function uses libcurl. Curl supports, among others, the HTTP, FTP and FILE
protocols. \n\
Username and password may be specified in the URL, for example: \n\
@example \n\
download('http://username:password@@example.com/file.txt','file.txt'); \n\
@end example \n\
@end deftypefn")
{
CURL *curl;
// curl return code
CURLcode res;
// argument for my_fwrite callback function
struct FileStruct filestruct;
// octave's return value
octave_value_list retval;
// verify arguments
if (args.length() != 2) {
print_usage();
return octave_value();
}
if (!args(0).is_string() || !args(1).is_string()) {
error("download only expects string arguments");
return octave_value();
}
string url = args(0).string_value();
// name to store the file if download is succesful
filestruct.filename = args(1).string_value();
filestruct.stream = NULL;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL,url.c_str());
// Define our callback to get called when there's data to be written
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
// Set a pointer to our struct to pass to the callback
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &filestruct);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, url.c_str());
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
// Switch on full protocol/debug output
// curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
res = curl_easy_perform(curl);
printf("\n");
// always cleanup
curl_easy_cleanup(curl);
} else {
res = CURLE_FAILED_INIT;
}
if(filestruct.stream)
fclose(filestruct.stream); // close the local file
curl_global_cleanup();
// return error code if desired
if(nargout == 0 & res != CURLE_OK)
error("curl: %s\n", curl_easy_strerror(res));
else {
retval(0) = res == CURLE_OK;
// return empty string if no error occured
retval(1) = string(res == CURLE_OK ? "" : curl_easy_strerror(res));
}
return retval;
}
- front-end of libcurl,
Alexander Barth <=