Return to imap-multi.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / docs / examples |
1.1 ! misho 1: /*************************************************************************** ! 2: * _ _ ____ _ ! 3: * Project ___| | | | _ \| | ! 4: * / __| | | | |_) | | ! 5: * | (__| |_| | _ <| |___ ! 6: * \___|\___/|_| \_\_____| ! 7: * ! 8: * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. ! 9: * ! 10: * This software is licensed as described in the file COPYING, which ! 11: * you should have received as part of this distribution. The terms ! 12: * are also available at https://curl.haxx.se/docs/copyright.html. ! 13: * ! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell ! 15: * copies of the Software, and permit persons to whom the Software is ! 16: * furnished to do so, under the terms of the COPYING file. ! 17: * ! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ! 19: * KIND, either express or implied. ! 20: * ! 21: ***************************************************************************/ ! 22: ! 23: /* <DESC> ! 24: * IMAP example using the multi interface ! 25: * </DESC> ! 26: */ ! 27: ! 28: #include <stdio.h> ! 29: #include <string.h> ! 30: #include <curl/curl.h> ! 31: ! 32: /* This is a simple example showing how to fetch mail using libcurl's IMAP ! 33: * capabilities. It builds on the imap-fetch.c example to demonstrate how to ! 34: * use libcurl's multi interface. ! 35: * ! 36: * Note that this example requires libcurl 7.30.0 or above. ! 37: */ ! 38: ! 39: #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 ! 40: ! 41: static struct timeval tvnow(void) ! 42: { ! 43: struct timeval now; ! 44: ! 45: /* time() returns the value of time in seconds since the epoch */ ! 46: now.tv_sec = (long)time(NULL); ! 47: now.tv_usec = 0; ! 48: ! 49: return now; ! 50: } ! 51: ! 52: static long tvdiff(struct timeval newer, struct timeval older) ! 53: { ! 54: return (newer.tv_sec - older.tv_sec) * 1000 + ! 55: (newer.tv_usec - older.tv_usec) / 1000; ! 56: } ! 57: ! 58: int main(void) ! 59: { ! 60: CURL *curl; ! 61: CURLM *mcurl; ! 62: int still_running = 1; ! 63: struct timeval mp_start; ! 64: ! 65: curl_global_init(CURL_GLOBAL_DEFAULT); ! 66: ! 67: curl = curl_easy_init(); ! 68: if(!curl) ! 69: return 1; ! 70: ! 71: mcurl = curl_multi_init(); ! 72: if(!mcurl) ! 73: return 2; ! 74: ! 75: /* Set username and password */ ! 76: curl_easy_setopt(curl, CURLOPT_USERNAME, "user"); ! 77: curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret"); ! 78: ! 79: /* This will fetch message 1 from the user's inbox */ ! 80: curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1"); ! 81: ! 82: /* Tell the multi stack about our easy handle */ ! 83: curl_multi_add_handle(mcurl, curl); ! 84: ! 85: /* Record the start time which we can use later */ ! 86: mp_start = tvnow(); ! 87: ! 88: /* We start some action by calling perform right away */ ! 89: curl_multi_perform(mcurl, &still_running); ! 90: ! 91: while(still_running) { ! 92: struct timeval timeout; ! 93: fd_set fdread; ! 94: fd_set fdwrite; ! 95: fd_set fdexcep; ! 96: int maxfd = -1; ! 97: int rc; ! 98: CURLMcode mc; /* curl_multi_fdset() return code */ ! 99: ! 100: long curl_timeo = -1; ! 101: ! 102: /* Initialise the file descriptors */ ! 103: FD_ZERO(&fdread); ! 104: FD_ZERO(&fdwrite); ! 105: FD_ZERO(&fdexcep); ! 106: ! 107: /* Set a suitable timeout to play around with */ ! 108: timeout.tv_sec = 1; ! 109: timeout.tv_usec = 0; ! 110: ! 111: curl_multi_timeout(mcurl, &curl_timeo); ! 112: if(curl_timeo >= 0) { ! 113: timeout.tv_sec = curl_timeo / 1000; ! 114: if(timeout.tv_sec > 1) ! 115: timeout.tv_sec = 1; ! 116: else ! 117: timeout.tv_usec = (curl_timeo % 1000) * 1000; ! 118: } ! 119: ! 120: /* get file descriptors from the transfers */ ! 121: mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd); ! 122: ! 123: if(mc != CURLM_OK) { ! 124: fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); ! 125: break; ! 126: } ! 127: ! 128: /* On success the value of maxfd is guaranteed to be >= -1. We call ! 129: select(maxfd + 1, ...); specially in case of (maxfd == -1) there are ! 130: no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- ! 131: to sleep 100ms, which is the minimum suggested value in the ! 132: curl_multi_fdset() doc. */ ! 133: ! 134: if(maxfd == -1) { ! 135: #ifdef _WIN32 ! 136: Sleep(100); ! 137: rc = 0; ! 138: #else ! 139: /* Portable sleep for platforms other than Windows. */ ! 140: struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ ! 141: rc = select(0, NULL, NULL, NULL, &wait); ! 142: #endif ! 143: } ! 144: else { ! 145: /* Note that on some platforms 'timeout' may be modified by select(). ! 146: If you need access to the original value save a copy beforehand. */ ! 147: rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); ! 148: } ! 149: ! 150: if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { ! 151: fprintf(stderr, ! 152: "ABORTING: Since it seems that we would have run forever.\n"); ! 153: break; ! 154: } ! 155: ! 156: switch(rc) { ! 157: case -1: /* select error */ ! 158: break; ! 159: case 0: /* timeout */ ! 160: default: /* action */ ! 161: curl_multi_perform(mcurl, &still_running); ! 162: break; ! 163: } ! 164: } ! 165: ! 166: /* Always cleanup */ ! 167: curl_multi_remove_handle(mcurl, curl); ! 168: curl_multi_cleanup(mcurl); ! 169: curl_easy_cleanup(curl); ! 170: curl_global_cleanup(); ! 171: ! 172: return 0; ! 173: }