summaryrefslogtreecommitdiff
path: root/docs/examples
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-12 15:09:29 +0000
committerng0 <ng0@n0.is>2019-09-12 15:09:29 +0000
commit5d5a61dc56228532927a7786375a13d7ae749180 (patch)
tree1b4b73a0016f005655aaa18982df8383f790527f /docs/examples
parentbc555b4f37422efffcc9969f645f9dbf3cb444bd (diff)
parent9cd755e1d768bbf228e7c9faf223b7459f7e0105 (diff)
downloadgnurl-5d5a61dc56228532927a7786375a13d7ae749180.tar.gz
gnurl-5d5a61dc56228532927a7786375a13d7ae749180.tar.bz2
gnurl-5d5a61dc56228532927a7786375a13d7ae749180.zip
Merge tag 'curl-7_66_0'
7.66.0
Diffstat (limited to 'docs/examples')
-rw-r--r--docs/examples/Makefile.inc5
-rw-r--r--docs/examples/altsvc.c56
-rw-r--r--docs/examples/curlx.c6
-rw-r--r--docs/examples/ephiperfifo.c42
-rw-r--r--docs/examples/hiperfifo.c52
-rw-r--r--docs/examples/http3-present.c47
-rw-r--r--docs/examples/http3.c54
-rw-r--r--docs/examples/imap-authzid.c71
-rw-r--r--docs/examples/pop3-authzid.c70
-rw-r--r--docs/examples/smtp-authzid.c161
10 files changed, 510 insertions, 54 deletions
diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc
index 8dd55b9df..6fd8ecd76 100644
--- a/docs/examples/Makefile.inc
+++ b/docs/examples/Makefile.inc
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2019, 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
@@ -35,7 +35,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
http2-upload http2-serverpush getredirect ftpuploadfrommem \
ftpuploadresume sslbackend postit2-formadd multi-formadd \
shared-connection-cache sftpuploadresume http2-pushinmemory parseurl \
- urlapi
+ urlapi imap-authzid pop3-authzid smtp-authzid http3 altsvc \
+ http3-present
# These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here.
diff --git a/docs/examples/altsvc.c b/docs/examples/altsvc.c
new file mode 100644
index 000000000..24ef42585
--- /dev/null
+++ b/docs/examples/altsvc.c
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+/* <DESC>
+ * HTTP with Alt-Svc support
+ * </DESC>
+ */
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+ /* cache the alternatives in this file */
+ curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc.txt");
+
+ /* restrict which HTTP versions to use alternatives */
+ curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long)
+ CURLALTSVC_H1|CURLALTSVC_H2|CURLALTSVC_H3);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/curlx.c b/docs/examples/curlx.c
index eb37a6a72..a4d59427a 100644
--- a/docs/examples/curlx.c
+++ b/docs/examples/curlx.c
@@ -277,7 +277,7 @@ int main(int argc, char **argv)
int tabLength = 100;
char *binaryptr;
- char *mimetype;
+ char *mimetype = NULL;
char *mimetypeaccept = NULL;
char *contenttype;
const char **pp;
@@ -294,7 +294,7 @@ int main(int argc, char **argv)
binaryptr = malloc(tabLength);
- p.verbose = 0;
+ memset(&p, '\0', sizeof(p));
p.errorbio = BIO_new_fp(stderr, BIO_NOCLOSE);
curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -372,7 +372,7 @@ int main(int argc, char **argv)
args++;
}
- if(mimetype == NULL || mimetypeaccept == NULL)
+ if(mimetype == NULL || mimetypeaccept == NULL || p.p12file == NULL)
badarg = 1;
if(badarg) {
diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c
index 4668c6ca3..9f89125a9 100644
--- a/docs/examples/ephiperfifo.c
+++ b/docs/examples/ephiperfifo.c
@@ -73,12 +73,6 @@ callback.
#include <gnurl/curl.h>
-#ifdef __GNUC__
-#define _Unused __attribute__((unused))
-#else
-#define _Unused
-#endif
-
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
@@ -114,7 +108,7 @@ typedef struct _SockInfo
GlobalInfo *global;
} SockInfo;
-#define __case(code) \
+#define mycase(code) \
case code: s = __STRING(code)
/* Die if we get a bad CURLMcode somewhere */
@@ -123,14 +117,14 @@ static void mcode_or_die(const char *where, CURLMcode code)
if(CURLM_OK != code) {
const char *s;
switch(code) {
- __case(CURLM_BAD_HANDLE); break;
- __case(CURLM_BAD_EASY_HANDLE); break;
- __case(CURLM_OUT_OF_MEMORY); break;
- __case(CURLM_INTERNAL_ERROR); break;
- __case(CURLM_UNKNOWN_OPTION); break;
- __case(CURLM_LAST); break;
+ mycase(CURLM_BAD_HANDLE); break;
+ mycase(CURLM_BAD_EASY_HANDLE); break;
+ mycase(CURLM_OUT_OF_MEMORY); break;
+ mycase(CURLM_INTERNAL_ERROR); break;
+ mycase(CURLM_UNKNOWN_OPTION); break;
+ mycase(CURLM_LAST); break;
default: s = "CURLM_unknown"; break;
- __case(CURLM_BAD_SOCKET);
+ mycase(CURLM_BAD_SOCKET);
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
/* ignore this error */
return;
@@ -336,22 +330,21 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
/* CURLOPT_WRITEFUNCTION */
-static size_t write_cb(void *ptr _Unused, size_t size, size_t nmemb,
- void *data)
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
- size_t realsize = size * nmemb;
- (void)_Unused;
+ (void)ptr;
(void)data;
-
- return realsize;
+ return size * nmemb;
}
/* CURLOPT_PROGRESSFUNCTION */
-static int prog_cb(void *p, double dltotal, double dlnow, double ult _Unused,
- double uln _Unused)
+static int prog_cb(void *p, double dltotal, double dlnow, double ult,
+ double uln)
{
ConnInfo *conn = (ConnInfo *)p;
+ (void)ult;
+ (void)uln;
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
return 0;
@@ -469,12 +462,14 @@ void SignalHandler(int signo)
}
}
-int main(int argc _Unused, char **argv _Unused)
+int main(int argc, char **argv)
{
GlobalInfo g;
struct itimerspec its;
struct epoll_event ev;
struct epoll_event events[10];
+ (void)argc;
+ (void)argv;
g_should_exit_ = 0;
signal(SIGINT, SignalHandler);
@@ -547,5 +542,6 @@ int main(int argc _Unused, char **argv _Unused)
fflush(MSG_OUT);
curl_multi_cleanup(g.multi);
+ clean_fifo(&g);
return 0;
}
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c
index fb25259c2..a7f71125a 100644
--- a/docs/examples/hiperfifo.c
+++ b/docs/examples/hiperfifo.c
@@ -72,12 +72,6 @@ callback.
#include <errno.h>
#include <sys/cdefs.h>
-#ifdef __GNUC__
-#define _Unused __attribute__((unused))
-#else
-#define _Unused
-#endif
-
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
@@ -115,7 +109,7 @@ typedef struct _SockInfo
GlobalInfo *global;
} SockInfo;
-#define __case(code) \
+#define mycase(code) \
case code: s = __STRING(code)
/* Die if we get a bad CURLMcode somewhere */
@@ -124,14 +118,14 @@ static void mcode_or_die(const char *where, CURLMcode code)
if(CURLM_OK != code) {
const char *s;
switch(code) {
- __case(CURLM_BAD_HANDLE); break;
- __case(CURLM_BAD_EASY_HANDLE); break;
- __case(CURLM_OUT_OF_MEMORY); break;
- __case(CURLM_INTERNAL_ERROR); break;
- __case(CURLM_UNKNOWN_OPTION); break;
- __case(CURLM_LAST); break;
+ mycase(CURLM_BAD_HANDLE); break;
+ mycase(CURLM_BAD_EASY_HANDLE); break;
+ mycase(CURLM_OUT_OF_MEMORY); break;
+ mycase(CURLM_INTERNAL_ERROR); break;
+ mycase(CURLM_UNKNOWN_OPTION); break;
+ mycase(CURLM_LAST); break;
default: s = "CURLM_unknown"; break;
- __case(CURLM_BAD_SOCKET);
+ mycase(CURLM_BAD_SOCKET);
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
/* ignore this error */
return;
@@ -143,9 +137,10 @@ static void mcode_or_die(const char *where, CURLMcode code)
/* Update the event timer after curl_multi library calls */
-static int multi_timer_cb(CURLM *multi _Unused, long timeout_ms, GlobalInfo *g)
+static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{
struct timeval timeout;
+ (void)multi;
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
@@ -220,10 +215,12 @@ static void event_cb(int fd, short kind, void *userp)
/* Called by libevent when our timeout expires */
-static void timer_cb(int fd _Unused, short kind _Unused, void *userp)
+static void timer_cb(int fd, short kind, void *userp)
{
GlobalInfo *g = (GlobalInfo *)userp;
CURLMcode rc;
+ (void)fd;
+ (void)kind;
rc = curl_multi_socket_action(g->multi,
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
@@ -303,22 +300,21 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
/* CURLOPT_WRITEFUNCTION */
-static size_t write_cb(void *ptr _Unused, size_t size, size_t nmemb,
- void *data)
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
- size_t realsize = size * nmemb;
- (void)_Unused;
+ (void)ptr;
(void)data;
-
- return realsize;
+ return size * nmemb;
}
/* CURLOPT_PROGRESSFUNCTION */
-static int prog_cb(void *p, double dltotal, double dlnow, double ult _Unused,
- double uln _Unused)
+static int prog_cb(void *p, double dltotal, double dlnow, double ult,
+ double uln)
{
ConnInfo *conn = (ConnInfo *)p;
+ (void)ult;
+ (void)uln;
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
return 0;
@@ -361,12 +357,14 @@ static void new_conn(char *url, GlobalInfo *g)
}
/* This gets called whenever data is received from the fifo */
-static void fifo_cb(int fd _Unused, short event _Unused, void *arg)
+static void fifo_cb(int fd, short event, void *arg)
{
char s[1024];
long int rv = 0;
int n = 0;
GlobalInfo *g = (GlobalInfo *)arg;
+ (void)fd;
+ (void)event;
do {
s[0]='\0';
@@ -427,9 +425,11 @@ static void clean_fifo(GlobalInfo *g)
unlink(fifo);
}
-int main(int argc _Unused, char **argv _Unused)
+int main(int argc, char **argv)
{
GlobalInfo g;
+ (void)argc;
+ (void)argv;
memset(&g, 0, sizeof(GlobalInfo));
g.evbase = event_base_new();
diff --git a/docs/examples/http3-present.c b/docs/examples/http3-present.c
new file mode 100644
index 000000000..857952dc7
--- /dev/null
+++ b/docs/examples/http3-present.c
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+/* <DESC>
+ * Checks if HTTP/3 support is present in libcurl.
+ * </DESC>
+ */
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ curl_version_info_data *ver;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ ver = curl_version_info(CURLVERSION_NOW);
+ if(ver->features & CURL_VERSION_HTTP2)
+ printf("HTTP/2 support is present\n");
+
+ if(ver->features & CURL_VERSION_HTTP3)
+ printf("HTTP/3 support is present\n");
+
+ if(ver->features & CURL_VERSION_ALTSVC)
+ printf("Alt-svc support is present\n");
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/http3.c b/docs/examples/http3.c
new file mode 100644
index 000000000..240a7edd4
--- /dev/null
+++ b/docs/examples/http3.c
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+/* <DESC>
+ * Very simple HTTP/3 GET
+ * </DESC>
+ */
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+ /* Forcing HTTP/3 will make the connection fail if the server isn't
+ accessible over QUIC + HTTP/3 on the given host and port.
+ Consider using CURLOPT_ALTSVC instead! */
+ curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_3);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/imap-authzid.c b/docs/examples/imap-authzid.c
new file mode 100644
index 000000000..bfe7d71d7
--- /dev/null
+++ b/docs/examples/imap-authzid.c
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+
+/* <DESC>
+ * IMAP example showing how to retreieve e-mails from a shared mailed box
+ * </DESC>
+ */
+
+#include <stdio.h>
+#include <curl/curl.h>
+
+/* This is a simple example showing how to fetch mail using libcurl's IMAP
+ * capabilities.
+ *
+ * Note that this example requires libcurl 7.66.0 or above.
+ */
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Set the username and password */
+ curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
+
+ /* Set the authorisation identity (identity to act as) */
+ curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "shared-mailbox");
+
+ /* Force PLAIN authentication */
+ curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
+
+ /* This will fetch message 1 from the user's inbox */
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "imap://imap.example.com/INBOX/;UID=1");
+
+ /* Perform the fetch */
+ res = curl_easy_perform(curl);
+
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* Always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ return (int)res;
+}
diff --git a/docs/examples/pop3-authzid.c b/docs/examples/pop3-authzid.c
new file mode 100644
index 000000000..57363579a
--- /dev/null
+++ b/docs/examples/pop3-authzid.c
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+
+/* <DESC>
+ * POP3 example showing how to retrieve e-mails from a shared mailbox
+ * </DESC>
+ */
+
+#include <stdio.h>
+#include <curl/curl.h>
+
+/* This is a simple example showing how to retrieve mail using libcurl's POP3
+ * capabilities.
+ *
+ * Note that this example requires libcurl 7.66.0 or above.
+ */
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Set the username and password */
+ curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
+
+ /* Set the authorisation identity (identity to act as) */
+ curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "shared-mailbox");
+
+ /* Force PLAIN authentication */
+ curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
+
+ /* This will retrieve message 1 from the user's mailbox */
+ curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
+
+ /* Perform the retr */
+ res = curl_easy_perform(curl);
+
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* Always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ return (int)res;
+}
diff --git a/docs/examples/smtp-authzid.c b/docs/examples/smtp-authzid.c
new file mode 100644
index 000000000..decdb719d
--- /dev/null
+++ b/docs/examples/smtp-authzid.c
@@ -0,0 +1,161 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, 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 https://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.
+ *
+ ***************************************************************************/
+
+/* <DESC>
+ * Send e-mail on behalf of another user with SMTP
+ * </DESC>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+/*
+ * This is a simple example show how to send an email using libcurl's SMTP
+ * capabilities.
+ *
+ * Note that this example requires libcurl 7.66.0 or above.
+ */
+
+/* The libcurl options want plain addresses, the viewable headers in the mail
+ * can very well get a full name as well.
+ */
+#define FROM_ADDR "<ursel@example.org>"
+#define SENDER_ADDR "<kurt@example.org>"
+#define TO_ADDR "<addressee@example.net>"
+
+#define FROM_MAIL "Ursel " FROM_ADDR
+#define SENDER_MAIL "Kurt " SENDER_ADDR
+#define TO_MAIL "A Receiver " TO_ADDR
+
+static const char *payload_text[] = {
+ "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
+ "To: " TO_MAIL "\r\n",
+ "From: " FROM_MAIL "\r\n",
+ "Sender: " SENDER_MAIL "\r\n",
+ "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
+ "rfcpedant.example.org>\r\n",
+ "Subject: SMTP example message\r\n",
+ "\r\n", /* empty line to divide headers from body, see RFC5322 */
+ "The body of the message starts here.\r\n",
+ "\r\n",
+ "It could be a lot of lines, could be MIME encoded, whatever.\r\n",
+ "Check RFC5322.\r\n",
+ NULL
+};
+
+struct upload_status {
+ int lines_read;
+};
+
+static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct upload_status *upload_ctx = (struct upload_status *)userp;
+ const char *data;
+
+ if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
+ return 0;
+ }
+
+ data = payload_text[upload_ctx->lines_read];
+
+ if(data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ upload_ctx->lines_read++;
+
+ return len;
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ struct curl_slist *recipients = NULL;
+ struct upload_status upload_ctx;
+
+ upload_ctx.lines_read = 0;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* This is the URL for your mailserver. In this example we connect to the
+ smtp-submission port as we require an authenticated connection. */
+ curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com:587");
+
+ /* Set the username and password */
+ curl_easy_setopt(curl, CURLOPT_USERNAME, "kurt");
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, "xipj3plmq");
+
+ /* Set the authorisation identity (identity to act as) */
+ curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "ursel");
+
+ /* Force PLAIN authentication */
+ curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
+
+ /* Note that this option isn't strictly required, omitting it will result
+ * in libcurl sending the MAIL FROM command with empty sender data. All
+ * autoresponses should have an empty reverse-path, and should be directed
+ * to the address in the reverse-path which triggered them. Otherwise,
+ * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
+ * details.
+ */
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);
+
+ /* Add a recipient, in this particular case it corresponds to the
+ * To: addressee in the header. */
+ recipients = curl_slist_append(recipients, TO_ADDR);
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
+
+ /* We're using a callback function to specify the payload (the headers and
+ * body of the message). You could just use the CURLOPT_READDATA option to
+ * specify a FILE pointer to read from. */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* Send the message */
+ res = curl_easy_perform(curl);
+
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* Free the list of recipients */
+ curl_slist_free_all(recipients);
+
+ /* curl won't send the QUIT command until you call cleanup, so you should
+ * be able to re-use this connection for additional messages (setting
+ * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
+ * curl_easy_perform() again. It may not be a good idea to keep the
+ * connection open for a very long time though (more than a few minutes
+ * may result in the server timing out the connection), and you do want to
+ * clean up in the end.
+ */
+ curl_easy_cleanup(curl);
+ }
+
+ return (int)res;
+}