> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of Michael Wood
> Sent: Friday, October 09, 2009 4:58 PM
> To: libcurl development
> Subject: Re: libcurl and libssh2
>
> The curl command can generate sample code for any options you specify.
>
> Try this:
> curl -u username sftp://shell.example.com/etc/issue --libcurl
> ssh2-download-example.c curl -T uploadfile -u user:passwd
> ftp://ftp.upload.com/myfile --libcurl ftp-upload-example.c
>
> and then examine the ssh2-{download,upload}-example.c files
> that are generated.
I have generated the sample code with sftp upload:
===========================================
q...@durian(pts/4):~/opensrc/curl-7.19.6/src[111]$ ./curl -v -u qxu:fair123 -T
CMakeLists.txt sftp://13.198.98.190/~/scan/test.txt --libcurl sftp_upload_test.c
===========================================
The upload is successful, and the sample code is generated, most of which can
be understood.
However, the generated code doesn't specify the local filename (or filepointer)
to be uploaded. I understand that this can be set by CURLOPT_READDATA in real
coding. Still, I am not sure whether a callback function is necessary with the
option CURLOPT_READFUNCTION. Or, is it optional?
By the way, the prototype of the callback looks pretty similar to C function
fread():
===========================================
/* from http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTREADFUNCTION
*/
CURLOPT_READFUNCTION
Function pointer that should match the following prototype: size_t function(
void *ptr, size_t size, size_t nmemb, void *stream); This function gets called
by libcurl as soon as it needs to read data in order to send it to the peer.
The data area pointed at by the pointer ptr may be filled with at most size
multiplied with nmemb number of bytes. Your function must return the actual
number of bytes that you stored in that memory area. Returning 0 will signal
end-of-file to the library and cause it to stop the current transfer.
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the
server expected it, like when you've said you will upload N bytes and you
upload less than N bytes), you may experience that the server "hangs" waiting
for the rest of the data that won't come.
The read callback may return CURL_READFUNC_ABORT to stop the current operation
immediately, resulting in a CURLE_ABORTED_BY_CALLBACK error code from the
transfer (Added in 7.12.1)
>From 7.18.0, the function can return CURL_READFUNC_PAUSE which then will cause
>reading from this connection to become paused. See curl_easy_pause(3) for
>further details.
If you set the callback pointer to NULL, or don't set it at all, the default
internal read function will be used. It is simply doing an fread() on the FILE
* stream set with CURLOPT_READDATA.
/* from K&R, 2nd Edition, Page 247 */
size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream)
fread reads from stream into the array ptr at most nobj objects of size size.
fread returns the number of objects read; this may be less than the number
requested. feof and ferror must be used to determine status.
===========================================
Can I assume that if the callback is not defined in the code, the system
function fread() is used by default?
Thanks,
Xu Qiang
/********* Sample code generated by the curl command line tool **********
* Lines with [REMARK] below might need to be modified to make this code
* usable. Add error code checking where appropriate.
* Compile this with a suitable header include path. Then link with
* libcurl.
* If you use any *_LARGE options, make sure your compiler figure
* out the correct size for the curl_off_t variable.
* Read the details for all curl_easy_setopt() options online on:
* http://curlm.haxx.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#define _FILE_OFFSET_BITS 64 /* for pre libcurl 7.19.0 curl_off_t magic */
#include <curl/curl.h>
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd = curl_easy_init();
/* curl_easy_setopt(hnd, CURLOPT_WRITEDATA, 0xbff69e68); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, 0x80501b0); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_READDATA, 0xbff69ea8); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_READFUNCTION, 0x8050140); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_SEEKDATA, 0xbff69ea8); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_SEEKFUNCTION, 0x8050100); [REMARK] */
curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, (curl_off_t)2106);
curl_easy_setopt(hnd, CURLOPT_URL, "sftp://13.198.98.190/~/scan/test.txt");
curl_easy_setopt(hnd, CURLOPT_PROXY, NULL);
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(hnd, CURLOPT_HEADER, 0);
curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 0);
curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1);
curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 0);
curl_easy_setopt(hnd, CURLOPT_APPEND, 0);
curl_easy_setopt(hnd, CURLOPT_NETRC, 0);
curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 0);
curl_easy_setopt(hnd, CURLOPT_UNRESTRICTED_AUTH, 0);
curl_easy_setopt(hnd, CURLOPT_TRANSFERTEXT, 0);
curl_easy_setopt(hnd, CURLOPT_USERPWD, "qxu:fair123");
curl_easy_setopt(hnd, CURLOPT_PROXYUSERPWD, NULL);
curl_easy_setopt(hnd, CURLOPT_NOPROXY, NULL);
curl_easy_setopt(hnd, CURLOPT_RANGE, NULL);
/* curl_easy_setopt(hnd, CURLOPT_ERRORBUFFER, 0xbff69cec); [REMARK] */
curl_easy_setopt(hnd, CURLOPT_TIMEOUT, 0);
curl_easy_setopt(hnd, CURLOPT_REFERER, NULL);
curl_easy_setopt(hnd, CURLOPT_AUTOREFERER, 0);
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.19.6 (i686-pc-linux-gnu)
libcurl/7.19.6 OpenSSL/0.9.8b zlib/1.2.3 libssh2/1.2");
curl_easy_setopt(hnd, CURLOPT_FTPPORT, NULL);
curl_easy_setopt(hnd, CURLOPT_LOW_SPEED_LIMIT, 0);
curl_easy_setopt(hnd, CURLOPT_LOW_SPEED_TIME, 0);
curl_easy_setopt(hnd, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t)0);
curl_easy_setopt(hnd, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t)0);
curl_easy_setopt(hnd, CURLOPT_RESUME_FROM_LARGE, (curl_off_t)0);
curl_easy_setopt(hnd, CURLOPT_COOKIE, NULL);
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, NULL);
curl_easy_setopt(hnd, CURLOPT_SSLCERT, NULL);
curl_easy_setopt(hnd, CURLOPT_SSLCERTTYPE, NULL);
curl_easy_setopt(hnd, CURLOPT_SSLKEY, NULL);
curl_easy_setopt(hnd, CURLOPT_SSLKEYTYPE, NULL);
curl_easy_setopt(hnd, CURLOPT_KEYPASSWD, NULL);
curl_easy_setopt(hnd, CURLOPT_SSH_PRIVATE_KEYFILE, NULL);
curl_easy_setopt(hnd, CURLOPT_SSH_PUBLIC_KEYFILE, NULL);
curl_easy_setopt(hnd, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, NULL);
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 2);
curl_easy_setopt(hnd, CURLOPT_SSH_KNOWNHOSTS, "/home/qxu/.ssh/known_hosts");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50);
curl_easy_setopt(hnd, CURLOPT_CRLF, 0);
curl_easy_setopt(hnd, CURLOPT_QUOTE, NULL);
curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, NULL);
curl_easy_setopt(hnd, CURLOPT_PREQUOTE, NULL);
curl_easy_setopt(hnd, CURLOPT_WRITEHEADER, NULL);
curl_easy_setopt(hnd, CURLOPT_COOKIEFILE, NULL);
curl_easy_setopt(hnd, CURLOPT_COOKIESESSION, 0);
curl_easy_setopt(hnd, CURLOPT_SSLVERSION, 0);
curl_easy_setopt(hnd, CURLOPT_TIMECONDITION, 0);
curl_easy_setopt(hnd, CURLOPT_TIMEVALUE, 0);
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, NULL);
/* curl_easy_setopt(hnd, CURLOPT_STDERR, 0x645560); [REMARK] */
curl_easy_setopt(hnd, CURLOPT_HTTPPROXYTUNNEL, 0);
curl_easy_setopt(hnd, CURLOPT_INTERFACE, NULL);
curl_easy_setopt(hnd, CURLOPT_KRBLEVEL, NULL);
curl_easy_setopt(hnd, CURLOPT_TELNETOPTIONS, NULL);
curl_easy_setopt(hnd, CURLOPT_RANDOM_FILE, NULL);
curl_easy_setopt(hnd, CURLOPT_EGDSOCKET, NULL);
curl_easy_setopt(hnd, CURLOPT_CONNECTTIMEOUT, 0);
/* curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, 0x804fb20); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, 0xbff69a24); [REMARK] */
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1);
curl_easy_setopt(hnd, CURLOPT_ENCODING, NULL);
curl_easy_setopt(hnd, CURLOPT_FTP_CREATE_MISSING_DIRS, 0);
curl_easy_setopt(hnd, CURLOPT_IPRESOLVE, 0);
curl_easy_setopt(hnd, CURLOPT_FTP_ACCOUNT, NULL);
curl_easy_setopt(hnd, CURLOPT_IGNORE_CONTENT_LENGTH, 0);
curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 0);
curl_easy_setopt(hnd, CURLOPT_FTP_FILEMETHOD, 0);
curl_easy_setopt(hnd, CURLOPT_FTP_ALTERNATIVE_TO_USER, NULL);
curl_easy_setopt(hnd, CURLOPT_SSL_SESSIONID_CACHE, 1);
/* curl_easy_setopt(hnd, CURLOPT_SOCKOPTFUNCTION, 0x804fa00); [REMARK] */
/* curl_easy_setopt(hnd, CURLOPT_SOCKOPTDATA, 0xbff69a24); [REMARK] */
curl_easy_setopt(hnd, CURLOPT_POSTREDIR, 0);
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
return (int)ret;
}
/**** End of sample code ****/
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html