在Linux中从C/C++程序发送电子邮件

14
我希望每次模拟结束时都能向我的gmail账户发送电子邮件。我已经尝试在网上搜索并找到了sendEmail,但它超时了。如果有人可以指出一个他们尝试过的包或链接,我将不胜感激。
谢谢

3
为什么不使用sendmail?http://www.linuxquestions.org/questions/linux-newbie-8/sendmail-from-the-command-line-288920/ - perreal
我不是系统管理员,因此无法为我的Gmail帐户设置系统。 - Madagascar
开一个套接字连接到SMTP服务器,创建一个原始电子邮件并通过这种方式传递它怎么样? - crush
SMTP是一个非常简单的协议(这就是它的名字所体现的!)。 - dreamlax
@Madagascar,如果您不是该计算机的管理员,您可以使用wget、ssh等工具向自己的计算机发送请求,然后使用邮件程序。 - perreal
5个回答

26

您可以使用popen()直接调用本地MTA并输入符合RFC822标准的文本。

#include <stdio.h>
#include <string.h>
#include <errno.h>
int sendmail(const char *to, const char *from, const char *subject, const char *message)
{
    int retval = -1;
    FILE *mailpipe = popen("/usr/lib/sendmail -t", "w");
    if (mailpipe != NULL) {
        fprintf(mailpipe, "To: %s\n", to);
        fprintf(mailpipe, "From: %s\n", from);
        fprintf(mailpipe, "Subject: %s\n\n", subject);
        fwrite(message, 1, strlen(message), mailpipe);
        fwrite(".\n", 1, 2, mailpipe);
        pclose(mailpipe);
        retval = 0;
     }
     else {
         perror("Failed to invoke sendmail");
     }
     return retval;
}

main(int argc, char** argv)
{
    if (argc == 5) {
        sendmail(argv[1], argv[2], argv[3], argv[4]);
    }
}

3
只要你确信message不包含子字符串"\n.\n",这个方案就足够有效。 - dreamlax
4
你必须确保message的最后一个字符是'\n' - Robᵩ
抱歉问一个愚蠢的问题,我是邮件编程的新手,但我想使用Gmail SMTP。如何更改以使用它? - Madagascar
@Madagascar 这不只是把你的 Gmail 账户放在“收件人”字段中吗? - trojanfoe
如果您的本地MTA无法按照您的期望发送邮件,请更改其配置。 - MarkR
显示剩余10条评论

5

libESMTP似乎是您要寻找的内容。它有很好的文档,而且看起来正在积极开发中(最新的候选版本发布于2012年1月中旬)。它还支持SSL和各种身份验证协议。

源代码包中有示例应用程序。


我在使用libeSMTP时遇到了问题。请参考此链接:http://stackoverflow.com/questions/28146658/this-libesmtp-example-not-showing-any-response - 3bdalla
@jupp0r提供的链接已经失效,但我在GitHub仓库https://github.com/libesmtp/libESMTP上找到了libESMTP。看起来它仍在开发中。 - TenerowiczS

2

无论是VMime还是libcurl都是用于电子邮件发送(及其他)的好库。


1

执行fork exec并将正文管道传输到类似sendmail/mail的程序:

#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

using std::string;

static const int READEND = 0;
static const int WRITEEND = 1;

int sendEmail(const string& to, const string& subject, const string& body) {
  int p2cFd[2];

  int ret = pipe(p2cFd);
  if (ret) {
    return ret;
  }

  pid_t child_pid = fork();
  if (child_pid < 0) {
    close(p2cFd[READEND]);
    close(p2cFd[WRITEEND]);

    return child_pid;
  }
  else if (!child_pid) {
    dup2(p2cFd[READEND], READEND);
    close(p2cFd[READEND]);
    close(p2cFd[WRITEEND]);

    execlp("mail", "mail", "-s", subject.c_str(), to.c_str(), NULL);

    exit(EXIT_FAILURE);
  }

  close(p2cFd[READEND]);

  ret = write(p2cFd[WRITEEND], body.c_str(), body.size());
  if (ret < 0) {
    return ret;
  }

  close(p2cFd[WRITEEND]);

  if (waitpid(child_pid, &ret, 0) == -1) {
    return ret;
  }

  return 0;
}

int main() {
  return sendEmail("email@hostname.com", "Subject", "Body");
}

Poco是另一个选择 https://pocoproject.org/docs/Poco.Net.MailMessage.html https://pocoproject.org/docs/Poco.Net.SMTPClientSession.html https://pocoproject.org/docs/Poco.Net.SecureSMTPClientSession.html - ericcurtin

1
我喜欢trojanfoe的答案,但在我的情况下,我需要打开一个邮件发送代理...一个MTA来使linux能够发送电子邮件 - 我发现exim4是一个相对简单的MTA,可以很好地与trojanfoe的程序配合使用。
为了使其工作,我在虚拟盒子中的debian类型系统上使用了以下命令:
sudo apt-get install exim sudo apt-get install mailutils
我使用以下命令配置了exim4:
sudo dpkg-reconfigure exim4-config
我使用以下命令告诉计算机我的常规(远程)电子邮件地址:
sudo emacs /etc/email-addresses
希望这对你有用,因为这些是我发现的让我的linux系统使用trojanfoe上面的电子邮件程序发送电子邮件的步骤。

没有管理员权限将无法完成此操作。 - mckenzm
@mckenzm 这是真的 - 我在 Windows 的虚拟机中完成了这个操作,因此我在该虚拟机上拥有管理员权限。 - tom
如果你的*n?x系统没有MTA,不管出于什么原因,那么最好安装Postfix。 - ScumCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接