Newer
Older
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <curl/curl.h>
/* This is a simple example showing how to fetch mail using libcurl's IMAP
* capabilities. It builds on the imap-fetch.c example to demonstrate how to
* use libcurl's multi interface.
*
* Note that this example requires libcurl 7.30.0 or above.
*/
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
static struct timeval tvnow(void)
{
struct timeval now;
/* time() returns the value of time in seconds since the epoch */
now.tv_sec = (long)time(NULL);
now.tv_usec = 0;
return now;
}
static long tvdiff(struct timeval newer, struct timeval older)
{
return (newer.tv_sec - older.tv_sec) * 1000 +
(newer.tv_usec - older.tv_usec) / 1000;
}
int main(void)
{
CURL *curl;
CURLM *mcurl;
int still_running = 1;
struct timeval mp_start;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(!curl)
return 1;
mcurl = curl_multi_init();
if(!mcurl)
return 2;
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
/* This will fetch message 1 from the user's inbox */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1");
/* Tell the multi stack about our easy handle */
curl_multi_add_handle(mcurl, curl);
/* Record the start time which we can use later */
mp_start = tvnow();
/* We start some action by calling perform right away */
curl_multi_perform(mcurl, &still_running);
while(still_running) {
struct timeval timeout;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
int rc;
CURLMcode mc; /* curl_multi_fdset() return code */
long curl_timeo = -1;
/* Initialise the file descriptors */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* Set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_timeout(mcurl, &curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}
/* get file descriptors from the transfers */
mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK)
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}
/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) we call
select(0, ...), which is basically equal to sleeping the timeout. On
Windows we can't sleep via select without a dummy socket and instead
we Sleep() for 100ms which is the minimum suggested value in the
curl_multi_fdset() doc. */
#ifdef _WIN32
if(maxfd == -1) {
Sleep(100);
rc = 0;
}
else
#endif
{
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
}
if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
fprintf(stderr,
"ABORTING: Since it seems that we would have run forever.\n");
break;
}
switch(rc) {
case -1: /* select error */
break;
case 0: /* timeout */
default: /* action */
curl_multi_perform(mcurl, &still_running);
break;
}
}
/* Always cleanup */
curl_multi_remove_handle(mcurl, curl);
curl_multi_cleanup(mcurl);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}