1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
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 http://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
22 /* This is an example application source code sending SMTP mail using the
27 #include <curl/curl.h>
30 * This is the list of basic details you need to tweak to get things right.
32 #define USERNAME "user@example.com"
33 #define PASSWORD "123qwerty"
34 #define SMTPSERVER "smtp.example.com"
35 #define SMTPPORT ":587" /* it is a colon+port string, but you can set it
36 to "" to use the default port */
37 #define RECIPIENT "<recipient@example.com>"
38 #define MAILFROM "<realuser@example.com>"
40 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
42 /* Note that you should include the actual meta data headers here as well if
43 you want the mail to have a Subject, another From:, show a To: or whatever
44 you think your mail should feature! */
45 static const char *text[]={
49 " Hello, this is CURL email SMTP\n",
57 static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
59 struct WriteThis *pooh = (struct WriteThis *)userp;
65 data = text[pooh->counter];
68 size_t len = strlen(data);
69 memcpy(ptr, data, len);
70 pooh->counter++; /* advance pointer */
73 return 0; /* no more data left to deliver */
76 static struct timeval tvnow(void)
79 ** time() returns the value of time in seconds since the Epoch.
82 now.tv_sec = (long)time(NULL);
87 static long tvdiff(struct timeval newer, struct timeval older)
89 return (newer.tv_sec-older.tv_sec)*1000+
90 (newer.tv_usec-older.tv_usec)/1000;
97 int still_running = 1;
98 struct timeval mp_start;
99 struct WriteThis pooh;
100 struct curl_slist* rcpt_list = NULL;
104 curl_global_init(CURL_GLOBAL_DEFAULT);
106 curl = curl_easy_init();
110 mcurl = curl_multi_init();
114 rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
115 /* more addresses can be added here
116 rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
119 curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT);
120 curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
121 curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
122 curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
123 curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
124 curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
125 curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
126 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
127 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
128 curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
129 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
130 curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L);
131 curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
132 curl_multi_add_handle(mcurl, curl);
136 /* we start some action by calling perform right away */
137 curl_multi_perform(mcurl, &still_running);
139 while(still_running) {
140 struct timeval timeout;
141 int rc; /* select() return code */
148 long curl_timeo = -1;
154 /* set a suitable timeout to play around with */
158 curl_multi_timeout(mcurl, &curl_timeo);
159 if(curl_timeo >= 0) {
160 timeout.tv_sec = curl_timeo / 1000;
161 if(timeout.tv_sec > 1)
164 timeout.tv_usec = (curl_timeo % 1000) * 1000;
167 /* get file descriptors from the transfers */
168 curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
170 /* In a real-world program you OF COURSE check the return code of the
171 function calls. On success, the value of maxfd is guaranteed to be
172 greater or equal than -1. We call select(maxfd + 1, ...), specially in
173 case of (maxfd == -1), we call select(0, ...), which is basically equal
176 rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
178 if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
179 fprintf(stderr, "ABORTING TEST, since it seems "
180 "that it would have run forever.\n");
188 case 0: /* timeout */
189 default: /* action */
190 curl_multi_perform(mcurl, &still_running);
195 curl_slist_free_all(rcpt_list);
196 curl_multi_remove_handle(mcurl, curl);
197 curl_multi_cleanup(mcurl);
198 curl_easy_cleanup(curl);
199 curl_global_cleanup();