c/c :libcurl smtp 邮件客户端(mua)-尊龙官方平台

c/c :libcurl smtp 邮件客户端(mua)

el/2024/3/25 16:57:43

c/c :libcurl smtp 邮件客户端(mua)

最近在研究关于邮件的一些东西,需要实现个自己的邮件客户端,也就是类似于foxmail那样的东西。

网上找了下感觉使用libcurl比较便捷靠谱(当然,还有esmtp等库)。

先放几个主要的libcurl官方的sample,然后相关内容我晚点再整理下。

sample 1:(最常用的最简单的,模拟mua发送邮件到mta)

/****************************************************************************                                  _   _ ____  _*  project                     ___| | | |  _ \| |*                             / __| | | | |_) | |*                            | (__| |_| |  _ <| |___*                             \___|\___/|_| \_\_____|** 尊龙凯时官方 copyright (c) 1998 - 2017, daniel stenberg, , 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.****************************************************************************//* * send e-mail with smtp* */#include 
#include 
#include /** for an smtp example using the multi interface please see smtp-multi.c.*//* the libcurl options want plain addresses, the viewable headers in the mail* can very well get a full name as well.*/
#define from_addr    ""
#define to_addr      ""
#define cc_addr      ""#define from_mail "sender person " from_addr
#define to_mail   "a receiver " to_addr
#define cc_mail   "john cc smith " cc_addrstatic 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","cc: " cc_mail "\r\n","message-id: "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 */curl_easy_setopt(curl, curlopt_url, "smtp://mail.example.com");/* 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 two recipients, in this particular case they correspond to the* to: and cc: addressees in the header, but they could be any kind of* recipient. */recipients = curl_slist_append(recipients, to_addr);recipients = curl_slist_append(recipients, cc_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;
}

sample 2:( ssl)

/****************************************************************************                                  _   _ ____  _*  project                     ___| | | |  _ \| |*                             / __| | | | |_) | |*                            | (__| |_| |  _ <| |___*                             \___|\___/|_| \_\_____|** 尊龙凯时官方 copyright (c) 1998 - 2016, daniel stenberg, , 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.****************************************************************************//* * smtp example using ssl* */#include 
#include 
#include /* this is a simple example showing how to send mail using libcurl's smtp* capabilities. it builds on the smtp-mail.c example to add authentication* and, more importantly, transport security to protect the authentication* details from being snooped.** note that this example requires libcurl 7.20.0 or above.*/#define from    ""
#define to      ""
#define cc      ""static const char *payload_text[] = {"date: mon, 29 nov 2010 21:54:29  1100\r\n","to: " to "\r\n","from: " from " (example user)\r\n","cc: " cc " (another example user)\r\n","message-id: "rfcpedant.example.org>\r\n","subject: smtp ssl 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) {/* set username and password */curl_easy_setopt(curl, curlopt_username, "user");curl_easy_setopt(curl, curlopt_password, "secret");/* this is the url for your mailserver. note the use of smtps:// rather* than smtp:// to request a ssl based connection. */curl_easy_setopt(curl, curlopt_url, "smtps://mainserver.example.net");/* if you want to connect to a site who isn't using a certificate that is* signed by one of the certs in the ca bundle you have, you can skip the* verification of the server's certificate. this makes the connection* a lot less secure.** if you have a ca cert for the server stored someplace else than in the* default bundle, then the curlopt_capath option might come handy for* you. */
#ifdef skip_peer_verificationcurl_easy_setopt(curl, curlopt_ssl_verifypeer, 0l);
#endif/* if the site you're connecting to uses a different host name that what* they have mentioned in their server certificate's commonname (or* subjectaltname) fields, libcurl will refuse to connect. you can skip* this check, but this will make the connection less secure. */
#ifdef skip_hostname_verificationcurl_easy_setopt(curl, curlopt_ssl_verifyhost, 0l);
#endif/* 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);/* add two recipients, in this particular case they correspond to the* to: and cc: addressees in the header, but they could be any kind of* recipient. */recipients = curl_slist_append(recipients, to);recipients = curl_slist_append(recipients, cc);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);/* since the traffic will be encrypted, it is very useful to turn on debug* information within libcurl to see what is happening during the* transfer */curl_easy_setopt(curl, curlopt_verbose, 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);/* always cleanup */curl_easy_cleanup(curl);}return (int)res;
}

sample 3:( tls)

/****************************************************************************                                  _   _ ____  _*  project                     ___| | | |  _ \| |*                             / __| | | | |_) | |*                            | (__| |_| |  _ <| |___*                             \___|\___/|_| \_\_____|** 尊龙凯时官方 copyright (c) 1998 - 2016, daniel stenberg, , 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.****************************************************************************//* * smtp example using tls* */#include 
#include 
#include /* this is a simple example showing how to send mail using libcurl's smtp* capabilities. it builds on the smtp-mail.c example to add authentication* and, more importantly, transport security to protect the authentication* details from being snooped.** note that this example requires libcurl 7.20.0 or above.*/#define from    ""
#define to      ""
#define cc      ""static const char *payload_text[] = {"date: mon, 29 nov 2010 21:54:29  1100\r\n","to: " to "\r\n","from: " from " (example user)\r\n","cc: " cc " (another example user)\r\n","message-id: "rfcpedant.example.org>\r\n","subject: smtp tls 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) {/* set username and password */curl_easy_setopt(curl, curlopt_username, "user");curl_easy_setopt(curl, curlopt_password, "secret");/* this is the url for your mailserver. note the use of port 587 here,* instead of the normal smtp port (25). port 587 is commonly used for* secure mail submission (see rfc4403), but you should use whatever* matches your server configuration. */curl_easy_setopt(curl, curlopt_url, "smtp://mainserver.example.net:587");/* in this example, we'll start with a plain text connection, and upgrade* to transport layer security (tls) using the starttls command. be careful* of using curlusessl_try here, because if tls upgrade fails, the transfer* will continue anyway - see the security discussion in the libcurl* tutorial for more details. */curl_easy_setopt(curl, curlopt_use_ssl, (long)curlusessl_all);/* if your server doesn't have a valid certificate, then you can disable* part of the transport layer security protection by setting the* curlopt_ssl_verifypeer and curlopt_ssl_verifyhost options to 0 (false).*   curl_easy_setopt(curl, curlopt_ssl_verifypeer, 0l);*   curl_easy_setopt(curl, curlopt_ssl_verifyhost, 0l);* that is, in general, a bad idea. it is still better than sending your* authentication details in plain text though.  instead, you should get* the issuer certificate (or the host certificate if the certificate is* self-signed) and add it to the set of certificates that are known to* libcurl using curlopt_cainfo and/or curlopt_capath. see docs/sslcerts* for more information. */curl_easy_setopt(curl, curlopt_cainfo, "/path/to/certificate.pem");/* 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);/* add two recipients, in this particular case they correspond to the* to: and cc: addressees in the header, but they could be any kind of* recipient. */recipients = curl_slist_append(recipients, to);recipients = curl_slist_append(recipients, cc);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);/* since the traffic will be encrypted, it is very useful to turn on debug* information within libcurl to see what is happening during the transfer.*/curl_easy_setopt(curl, curlopt_verbose, 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);/* always cleanup */curl_easy_cleanup(curl);}return (int)res;
}

官方资料:

1)https://curl.haxx.se/libcurl/c/example.html
2)https://curl.haxx.se/libcurl/c/smtp-mail.html
3)https://curl.haxx.se/libcurl/c/smtp-ssl.html
4)https://curl.haxx.se/libcurl/c/smtp-tls.html

源文件:

1)https://raw.githubusercontent.com/curl/curl/master/docs/examples/smtp-mail.c
2)https://raw.githubusercontent.com/curl/curl/master/docs/examples/smtp-ssl.c
3)https://raw.githubusercontent.com/curl/curl/master/docs/examples/smtp-tls.c

资料搬运工~

今天晚点我再整理下具体遇到的问题~


http://www.ngui.cc/el/5127125.html

相关文章

other:环比与同比

other:环比与同比 今天看新闻,看到两个熟悉而陌生的词汇:环比、同比。 啥是环比,啥是同比? 环比: 2017年12月销售额130,相比2017年11月销售额100: 环比130/1001.3 环比增长&am…

libcurl:protocol smtps not supported or disabled in libcurl

libcurl:protocol “smtps” not supported or disabled in libcurl 在使用libcurl来作为mua时,开启debug模式,使用smtps协议,在运行时报错: libcurl:protocol “smtps” not supported or disabled in l…

编解码:十六进制编解码

编解码:十六进制编解码 信息有多种表现形式:二进制、十进制、十六进制、字符串… 在计算机中,信息是以二进制的形式来表现。 可以人为定义:0就是假,1就是真,等等。 所谓编解码,是将一种数据…

编解码:base64编解码

编解码:base64编解码 编解码:十六进制编解码中提到,编解码本质上是以不同的数据形式来展示“信息”,可以用二进制来表示,可以用十六进制来表示。 二进制的数据,在计算机中通常是不可读、不可打印的。 那…

postfix:转发邮件配置启用ssl/tls

postfix:转发邮件配置启用ssl/tls postfix version: [rootlocalhost postfix]# postconf -d | grep mail_version mail_version 2.6.6 postfix在收到一封邮件后,会将其通过mta进行转发到指定邮箱服务器。 默认情况下,postfix…

安装redis-4.0.1以及hiredis库

安装redis-4.0.1以及hiredis库 redis是一个开源的使用ansi c语言编写、遵守bsd协议、支持网络、可基于内存亦可持久化的日志型、key-value数据库,并提供多种语言的api。 install redis-4.0.1 一、新建账户 [rootlocalhost ~]# useradd -d /home/redis -m redis […

工作中写文档的一些经验总结

工作中写文档的一些经验总结 在工作中,有很多时间是在写设计文档、配置说明、升级部署等文档。 有时候真的很烦写文档,但是写文档又是必不可少的重要工作内容。 如何写好文档? 我个人在工作中有一丢丢的经验总结: 一、尽可能…

redis:使用set命令实现简单的高可用(ha)

##redis:使用set命令实现简单的高可用(ha) 我们的需求: 假设有多个相同的进程实例分别在多个主机上运行,但是逻辑上同一时刻至多只能有一个进程实例在“工作”。 只有当在“工作”的那个进程实例由于某种异常原因宕…

压力测试模拟程序(c实现)

压力测试模拟程序(c实现) 最近在做一个功能模块,目前功能上已经实现,但是性能暂时没有做过测试。 我的功能主要是接收udp消息,并将udp消息进行封装处理,发送到后端处理模块进行处理。 简单写一个小的udp…

udp socket接收缓冲区与netstat recv-q

udp socket接收缓冲区与netstat recv-q 我们通常使用netstat查看网络的诸多状态,其中包含send-q与recv-q。 我们知道: 每一个socket对象在系统中都被映射为一个socket文件; 每一个socket对象在系统中都关联有两个内核缓冲区:一…
网站地图