编译

需要安装libesmtp开发环境,centos下可以用yum安装。

yum install libesmtp-devel

编译时加上-lesmtp选项,账号密码等替换成自己的

gcc -o mail mail.c -lesmtp
./mail

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* mail.c */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>

#include <errno.h>
#include <openssl/ssl.h>
#include <auth-client.h>
#include <libesmtp.h>


#define FAIL -1
#define OK 0

#define SUBJECT "Subject" /* 邮件主题*/
#define TO "to@to.com" /* 收件人 */
#define BODY "hello" /* 邮件正文 */
#define SERVER "smtp.163.com:25" /* 邮件服务器地址 */
#define USERNAME "wen-4@163.com" /* 邮箱账号 */
#define PASSWOED "123456789" /* 邮箱密码 */

/* 回调函数 设置账号密码 */
int authinteract(auth_client_request_t request, char **result, int fields, void *args)
{
int i;

for (i=0; i < fields; i++)
{
if (request[i].flags & AUTH_PASS)
result[i] = PASSWOED;
else
result[i] = USERNAME;
}
return 1;
}

/* 回调函数 打印客户端与服务器交互情况 可以不要 */
void monitor_cb(const char *buf, int buflen, int writing, void *arg)
{
int i;

if (writing == SMTP_CB_HEADERS)
printf("H: ");
else if(writing)
printf("C: ");
else
printf("S: ");

const char *p = buf;
for(i=0; p[i]!='\n'; i++)
{
printf("%c", p[i]);
}
printf("\n");
}

int main()
{
int ret;
FILE *tmp_fp = NULL;
smtp_session_t session;
smtp_message_t message;
smtp_recipient_t recipient;
auth_context_t authctx;
const smtp_status_t *status;

auth_client_init();
session = smtp_create_session();
message = smtp_add_message(session);

smtp_set_monitorcb(session, monitor_cb, stdout, 1);


/* 设置邮件主题 */
smtp_set_header(message, "Subject",SUBJECT);
smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1);

/* 设置收件人 */
smtp_set_header(message, "To", NULL, TO);

/* 设置发件人 */
smtp_set_reverse_path(message, USERNAME);

/* 添加收件人 */
recipient = smtp_add_recipient(message, TO);

/* 设置服务器域名和端口 */
smtp_set_server(session, SERVER);

/* 设置邮件正文 */
tmp_fp = tmpfile();
if (tmp_fp == NULL)
{
printf("create temp file failed: %s\n", strerror(errno));
return FAIL;
}
fprintf(tmp_fp, "\r\n%s",BODY);
rewind(tmp_fp);
smtp_set_message_fp(message, tmp_fp);

/* 设置登录验证相关的东西 */
authctx = auth_create_context();
if (authctx == NULL)
{
return FAIL;
}

auth_set_mechanism_flags(authctx, AUTH_PLUGIN_PLAIN, 0);
auth_set_interact_cb(authctx, authinteract, NULL);
smtp_auth_set_context(session, authctx);

if (!smtp_start_session(session))
{
char buf[128];
printf( "SMTP server problem %s", smtp_strerror(smtp_errno(), buf, sizeof buf));
ret = FAIL;
}
else
{
/* 输出邮件发送情况 如果 status->code== 250则表明发送成功 */
status = smtp_message_transfer_status(message);
printf("%d %s", status->code, (status->text != NULL) ? status->text : "\n");
ret = OK;
}

/* 释放资源 */
smtp_destroy_session(session);
if (authctx)
auth_destroy_context(authctx);
auth_client_exit();
fclose(tmp_fp);
return ret;
}

运行结果

下面是程序运行的实际情况, 如果提示535 Error或者authentication failed表明验证失败,说明是账号密码错误,或者邮箱的设置问题。
程序运行实例