Freitag, 28. Dezember 2012

libcurl - Tutorial Example 01

About

Following the example in the libcurl Tutorial, let's make a simple demonstration program to use the basic cURL facilities.

Usage

curltut01 URL

The specified URL is downloaded and echoed on standard output, along with other information for demonstration purposes. If an error occurs, the error message from Curl is displayed.

Code Listing

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <curl/curl.h>  
   
 char errorbuffer[CURL_ERROR_SIZE] = "(UNKNOWN ERROR)";  
 void error(){printf("An error occured with a curl function: %s\n", errorbuffer);}  
 size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);  
   
 typedef struct {  
      char *filename;  
      FILE *fp;  
 } UserData;  
   
 #define SELF_EXE argv[0]  
 #define URL argv[1]  
 int main(int argc, char *argv[])  
 {  
      if (argc != 2) {  
           printf("Usage: %s URL\n", SELF_EXE);  
           exit(1);  
      }  
        
      if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {  
           error();  
           goto aft_curl_global_cleanup;  
      }  
        
      CURL *easyhandle = curl_easy_init();  
      if (easyhandle == NULL) {  
           error();  
           goto aft_curl_easy_cleanup;  
      }  
      if (curl_easy_setopt(easyhandle, CURLOPT_ERRORBUFFER, errorbuffer) != CURLE_OK) {  
           error();  
           goto done;  
      }       
      if (curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1) != CURLE_OK) {  
           error();  
           goto done;  
      }  
      if (curl_easy_setopt(easyhandle, CURLOPT_HEADER, 1) != CURLE_OK) {  
           error();  
           goto done;  
      }  
      if (curl_easy_setopt(easyhandle, CURLOPT_STDERR, stderr) != CURLE_OK) {  
           error();  
           goto done;  
      }  
      if (curl_easy_setopt(easyhandle, CURLOPT_URL, URL) != CURLE_OK) {  
           error();  
           goto done;  
      }  
      if (curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data) != CURLE_OK) {  
           error();  
           goto done;  
      }  
        
      UserData userdata = {.filename = "somefilename", .fp=stdout};       
      if (curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &userdata) != CURLE_OK) {  
           error();  
           goto done;  
      }  
      if (curl_easy_perform(easyhandle) != CURLE_OK) {  
           error();  
           goto done;  
      }  
        
 done:  
      curl_easy_cleanup(easyhandle);  
 aft_curl_easy_cleanup:  
      curl_global_cleanup();  
 aft_curl_global_cleanup:  
      return 0;  
 }  
   
 #define BAR "\  
 -------------------------------------------------------------------------------"  
 size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)  
 {  
      UserData *ud = userp;  
      printf(BAR "\n");  
      printf("ud.filename: %s\n", ud->filename);  
        
      printf("buffer: ");  
      if (fwrite(buffer, size, nmemb, ud->fp) == nmemb) {  
           printf("\n" BAR "\n");  
           return size*nmemb; // success  
      }  
      printf("\n" BAR "\n");  
      return 0; // error  
 }  
   


Explanations

curl_global_init(CURL_GLOBAL_ALL);

Curl global initialization. CURL_GLOBAL_ALL sets common initial parameters.

CURL *easyhandle = curl_easy_init();

Get a handle called easyhandle for future Curl calls.

curl_easy_setopt(HAND, OPT, VAL);

General form for initializing handle HAND with Curl option OPT with the value VAL. This call returns CURLE_OK on success, otherwise it is a failure. In many of the examples on the Curl website, the return value of curl_easy_setopt is not checked, probably because a failure is unlikely. However, it could conceivably fail if there is a memory allocation problem.

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);

curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);

This defines write_data as the callback function for Curl write operations. The function is passed a buffer containing nmemb entries, each with size bytes. The userp parameter is a pointer to a user-defined parameter. The callback function should return size*nmemb on success (i.e. "the number of bytes processed"). Other return values are interpreted by Curl as an error and the transfer is aborted.

UserData userdata = {.filename = "somefilename", .fp=stdout};

curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &userdata);

Define a custom structure which I will call UserData to pass to our write_data function.

curl_easy_perform(easyhandle);

Begin the transfer as specified by the previous calls to curl_easy_setopt(3).

References

http://curl.haxx.se/libcurl/c/libcurl-tutorial.html

Keine Kommentare:

Kommentar veröffentlichen