cURL / Mailing Lists / curl-library / Single Mail

curl-library

pop3 commands hang beside LIST

From: Tural Ismayilzade <qeribturalmb_at_gmail.com>
Date: Thu, 06 Nov 2014 16:30:50 +0400

The following is the code snippet that i am trying to fetch email from mail server by
libcurls easy interface.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>

/**
 * network data data structure for holding received data by curl
 */
typedef struct {
    char *ptr;
    size_t length;
} net_data_t;

/**
 * error checked malloc
 */
void *ec_malloc(size_t size)
{
    void *mptr;

    mptr = malloc(size);
    if (mptr == NULL) {
        printf("not enough memory to allocate");
        exit(EXIT_FAILURE);
    }

    return mptr;
}

/**
 * error checked realloc
 */
void *ec_realloc(void *ptr, size_t new_size)
{
    void *mptr;

    mptr = realloc(ptr, new_size);
    if (mptr == NULL) {
        printf("not enough memory to reallocate");
        exit(EXIT_FAILURE);
    }

    return mptr;
}

/**
 * network data initialize
 */
static void net_data_init(net_data_t *data)
{
  data->length = 0;
  data->ptr = NULL;
}

/**
 * network data free & reinitialize
 */
static void net_data_free(net_data_t *data)
{
    free(data->ptr);
    net_data_init(data);
}

/**
 * curl write function for received data
 */
static size_t net_data_fill(char *ptr, size_t size, size_t nmemb, net_data_t *data)
{
    size_t length = data->length + (size * nmemb);

    data->ptr = ec_realloc(data->ptr, length + 1);
    memcpy(data->ptr + data->length, ptr, size * nmemb);
    data->ptr[length] = '\0';
    data->length = length;

    return size * nmemb;
}

/**
 * perform curl easy file transfer, log if error, else return
 * received data
 */
void ec_curl_easy_perform(CURL **easy_handle, char **recv_data)
{
    CURLcode res;
    net_data_t data;

    *recv_data = NULL;
    net_data_init(&data);
    curl_easy_setopt(*easy_handle, CURLOPT_TIMEOUT, 5);
    curl_easy_setopt(*easy_handle, CURLOPT_ACCEPTTIMEOUT_MS, 1000);
    curl_easy_setopt(*easy_handle, CURLOPT_WRITEFUNCTION, net_data_fill);
    curl_easy_setopt(*easy_handle, CURLOPT_WRITEDATA, &data);

    res = curl_easy_perform(*easy_handle);
    if (res != CURLE_OK) {
        printf("%s\n", curl_easy_strerror(res));
        net_data_free(&data);
        return;
    }

    *recv_data = ec_malloc(data.length);
    strncpy(*recv_data, data.ptr, data.length + 1);

    net_data_free(&data);
}

/**
 * fetch
 */
static void fetch(char **data)
{
    CURL *easy_handle = curl_easy_init();
    curl_easy_setopt(easy_handle, CURLOPT_USERNAME, "username");
    curl_easy_setopt(easy_handle, CURLOPT_PASSWORD, "password");
    curl_easy_setopt(easy_handle, CURLOPT_URL, "pop3://host/1");
    ec_curl_easy_perform(&easy_handle, data);
    curl_easy_cleanup(easy_handle);
}

int main(void)
{
    char *data;

    fetch(&data);
    printf("%s\n", data);

    return 0;
}

However, it hangs indefinitely. I used wireshark to sniff packets. It seems that after issuing
QUIT command libcurl does not issue FIN, ACK. After hitting CTRL^C it sends FIN, ACK. I
have checked for all pop3 commands. This happens on all commands but LIST. Please help.

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2014-11-06