PublicEnemy
PublicEnemy

Reputation: 23

Retrieving data in C with libcurl

I'm using C and libcurl to log in to a website and retrieve a value from the form(ie put the string "username=random" into a char array). This is what I have so far:

curl = curl_easy_init();
if(curl) {
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0");
    curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1 );
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1 );
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, " "); 
    curl_easy_setopt(curl, CURLOPT_URL, "http://www.website.com/login");
    curl_easy_perform(curl);
    curl_easy_setopt(curl, CURLOPT_REFERER, "http://www.website.com/login");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,fields );
    curl_easy_perform(curl);
    curl_easy_setopt(curl, CURLOPT_URL, "http://www.website.com/form-with-data");

    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    }

but I'm not sure where to go from there. I've tried writing the whole page into a file then manually searching for the string, but that did not work.

I'm sure there is a simple answer for this, I'm just new to both C and libcurl :)

Upvotes: 2

Views: 1554

Answers (2)

Are you familiar with HTTP and HTML? You should at least know what GET, HEAD, and POST requests are, and what exactly happens at the protocol level when a form is submitted by a user thru his browser. You may practice by using telnet and typing manually the HTTP requests.

Then, you want to make a POST request programmatically. The libcurl has several examples, you should look inside postit2.c

You could be concerned with HTTP cookies, and look into cookie_interface.c example. Your CURLOPT_COOKIEFILE is wrong (you are giving a file named by a single space).

Don't forget to enable all warnings and debugging info when compiling. If on Linux, compile with gcc -Wall -g yourexample.c -lcurl -o yourprog and improve your code till no warnings are given. Then learn to use gdb for debugging.

Upvotes: 1

user529758
user529758

Reputation:

Your current code will do one thing: it will write the data to the standard output. To accumulate the data, you have to do something like this:

size_t write_clbk(void *data, size_t blksz, size_t nblk, void *ctx)
{
    static size_t sz = 0;
    size_t currsz = blksz * nblk;

    size_t prevsz = sz;
    sz += currsz;
    void *tmp = realloc(*(char **)ctx, sz);
    if (tmp == NULL) {
        // handle error
        free(*(char **)ctx);
        *(char **)ctx = NULL;
        return 0;
    }
    *(char **)ctx = tmp;

    memcpy(*(char **)ctx + prevsz, data, currsz);
    return currsz;
}

hndl = curl_easy_init();
// Set up the easy handle, i. e. specify URL, user agent, etc.
// Do the ENTIRE setup BEFORE calling `curl_easy_perform()'.
// Afterwards the calls to `curl_easy_setopt()' won't be effective anymore

char *buf = NULL;
curl_easy_setopt(hndl, CURLOPT_WRITEFUNCTION, write_clbk);
curl_easy_setopt(hndl, CURLOPT_WRITEDATA, &buf);
curl_easy_perform(hndl);
curl_easy_cleanup(hndl);

// here `buf' will contain the data
// after use, don't forget:
free(buf);

Upvotes: 2

Related Questions