mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-26 22:41:03 +08:00
Add smtp client example
This commit is contained in:
parent
f94a019733
commit
48800504be
20
examples/smtp-client/Makefile
Normal file
20
examples/smtp-client/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
PROG ?= example
|
||||
CFLAGS ?= -W -Wall -Wextra -O2 $(EXTRA_CFLAGS)
|
||||
SSL ?= MBEDTLS
|
||||
|
||||
ifeq "$(SSL)" "MBEDTLS"
|
||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509 -L$(MBEDTLS)/lib -I$(MBEDTLS)/include
|
||||
endif
|
||||
|
||||
ifeq "$(SSL)" "OPENSSL"
|
||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto -L$(OPENSSL)/lib -I$(OPENSSL)/include
|
||||
endif
|
||||
|
||||
all: $(PROG)
|
||||
$(RUN) ./$(PROG) $(ARGS)
|
||||
|
||||
$(PROG): main.c
|
||||
$(CC) ../../mongoose.c -I../.. $(CFLAGS) -o $(PROG) main.c
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) _CL* *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mbedtls
|
5
examples/smtp-client/README.md
Normal file
5
examples/smtp-client/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# SMTP client example
|
||||
|
||||
This example shows how to send emails via Gmail.
|
||||
Before running this example, open main.c and modify settings at the top
|
||||
of the file.
|
1
examples/smtp-client/ca.pem
Symbolic link
1
examples/smtp-client/ca.pem
Symbolic link
@ -0,0 +1 @@
|
||||
../../test/data/ca.pem
|
80
examples/smtp-client/main.c
Normal file
80
examples/smtp-client/main.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *user = "aaa@gmail.com"; // Change this! Your gmail account
|
||||
static const char *pass = "xxxxxxxxxxxxx"; // Change this! Your gmail password
|
||||
static const char *to = "bbb@gmail.com"; // Change this! Destination email
|
||||
|
||||
static const char *from = "My Mail Sender";
|
||||
static const char *subj = "test email from mongoose library!";
|
||||
static const char *mesg = "Hi!\nThis is a test message.\nBye.";
|
||||
|
||||
static bool s_quit;
|
||||
|
||||
enum { EHLO, STARTTLS, STARTTLS_WAIT, AUTH, FROM, TO, DATA, BODY, QUIT, END };
|
||||
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
uint8_t *state = (uint8_t *) c->label;
|
||||
if (ev == MG_EV_OPEN) {
|
||||
// c->is_hexdumping = 1;
|
||||
} else if (ev == MG_EV_READ) {
|
||||
if (c->recv.len > 0 && c->recv.buf[c->recv.len - 1] == '\n') {
|
||||
MG_INFO(("<-- %.*s", (int) c->recv.len - 2, c->recv.buf));
|
||||
c->recv.len = 0;
|
||||
if (*state == EHLO) {
|
||||
mg_printf(c, "EHLO gmail.com\r\n");
|
||||
*state = c->is_tls ? AUTH : STARTTLS;
|
||||
} else if (*state == STARTTLS) {
|
||||
mg_printf(c, "STARTTLS\r\n");
|
||||
*state = STARTTLS_WAIT;
|
||||
} else if (*state == STARTTLS_WAIT) {
|
||||
struct mg_tls_opts opts = {.ca = "/tmp/ca.pem"};
|
||||
mg_tls_init(c, &opts);
|
||||
*state = EHLO;
|
||||
} else if (*state == AUTH) {
|
||||
char a[100], b[300] = "";
|
||||
size_t n = mg_snprintf(a, sizeof(a), "%c%s%c%s", 0, user, 0, pass);
|
||||
mg_base64_encode((uint8_t *) a, n, b);
|
||||
mg_printf(c, "AUTH PLAIN %s\r\n", b);
|
||||
*state = FROM;
|
||||
} else if (*state == FROM) {
|
||||
mg_printf(c, "MAIL FROM: <%s>\r\n", user);
|
||||
*state = TO;
|
||||
} else if (*state == TO) {
|
||||
mg_printf(c, "RCPT TO: <%s>\r\n", to);
|
||||
*state = DATA;
|
||||
} else if (*state == DATA) {
|
||||
mg_printf(c, "DATA\r\n");
|
||||
*state = BODY;
|
||||
} else if (*state == BODY) {
|
||||
mg_printf(c, "From: %s <%s>\r\n", from, user); // Mail header
|
||||
mg_printf(c, "Subject: %s\r\n", subj); // Mail header
|
||||
mg_printf(c, "\r\n"); // End of headers
|
||||
mg_printf(c, "%s\r\n", mesg); // Mail body
|
||||
mg_printf(c, ".\r\n"); // End of body
|
||||
*state = QUIT;
|
||||
} else if (*state == QUIT) {
|
||||
mg_printf(c, "QUIT\r\n");
|
||||
*state = END;
|
||||
} else {
|
||||
c->is_draining = 1;
|
||||
MG_INFO(("end"));
|
||||
}
|
||||
MG_INFO(("--> %.*s", (int) c->send.len - 2, c->send.buf));
|
||||
}
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
s_quit = true;
|
||||
} else if (ev == MG_EV_TLS_HS) {
|
||||
MG_INFO(("TLS handshake done!"));
|
||||
mg_printf(c, "EHLO gmail.com\r\n");
|
||||
}
|
||||
(void) fn_data, (void) ev_data;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr);
|
||||
// mg_log_set(MG_LL_VERBOSE);
|
||||
mg_connect(&mgr, "tcp://smtp.gmail.com:587", fn, NULL);
|
||||
while (s_quit == false) mg_mgr_poll(&mgr, 1000);
|
||||
return 0;
|
||||
}
|
@ -5101,6 +5101,7 @@ void mg_tls_handshake(struct mg_connection *c) {
|
||||
if (rc == 0) { // Success
|
||||
MG_DEBUG(("%lu success", c->id));
|
||||
c->is_tls_hs = 0;
|
||||
mg_call(c, MG_EV_TLS_HS, NULL);
|
||||
} else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
|
||||
MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
|
||||
@ -5238,7 +5239,7 @@ size_t mg_tls_pending(struct mg_connection *c) {
|
||||
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||
long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
|
||||
if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
return MG_IO_WAIT;
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
@ -5375,6 +5376,7 @@ void mg_tls_handshake(struct mg_connection *c) {
|
||||
if (rc == 1) {
|
||||
MG_DEBUG(("%lu success", c->id));
|
||||
c->is_tls_hs = 0;
|
||||
mg_call(c, MG_EV_TLS_HS, NULL);
|
||||
} else {
|
||||
int code = mg_tls_err(tls, rc);
|
||||
if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
|
||||
|
@ -993,6 +993,7 @@ enum {
|
||||
MG_EV_RESOLVE, // Host name is resolved NULL
|
||||
MG_EV_CONNECT, // Connection established NULL
|
||||
MG_EV_ACCEPT, // Connection accepted NULL
|
||||
MG_EV_TLS_HS, // TLS handshake succeeded NULL
|
||||
MG_EV_READ, // Data received from socket long *bytes_read
|
||||
MG_EV_WRITE, // Data written to socket long *bytes_written
|
||||
MG_EV_CLOSE, // Connection closed NULL
|
||||
|
@ -13,6 +13,7 @@ enum {
|
||||
MG_EV_RESOLVE, // Host name is resolved NULL
|
||||
MG_EV_CONNECT, // Connection established NULL
|
||||
MG_EV_ACCEPT, // Connection accepted NULL
|
||||
MG_EV_TLS_HS, // TLS handshake succeeded NULL
|
||||
MG_EV_READ, // Data received from socket long *bytes_read
|
||||
MG_EV_WRITE, // Data written to socket long *bytes_written
|
||||
MG_EV_CLOSE, // Connection closed NULL
|
||||
|
@ -48,6 +48,7 @@ void mg_tls_handshake(struct mg_connection *c) {
|
||||
if (rc == 0) { // Success
|
||||
MG_DEBUG(("%lu success", c->id));
|
||||
c->is_tls_hs = 0;
|
||||
mg_call(c, MG_EV_TLS_HS, NULL);
|
||||
} else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rc == MBEDTLS_ERR_SSL_WANT_WRITE) { // Still pending
|
||||
MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
|
||||
@ -185,7 +186,7 @@ size_t mg_tls_pending(struct mg_connection *c) {
|
||||
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||
long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
|
||||
if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
return MG_IO_WAIT;
|
||||
if (n <= 0) return MG_IO_ERR;
|
||||
return n;
|
||||
|
@ -116,6 +116,7 @@ void mg_tls_handshake(struct mg_connection *c) {
|
||||
if (rc == 1) {
|
||||
MG_DEBUG(("%lu success", c->id));
|
||||
c->is_tls_hs = 0;
|
||||
mg_call(c, MG_EV_TLS_HS, NULL);
|
||||
} else {
|
||||
int code = mg_tls_err(tls, rc);
|
||||
if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
|
||||
|
Loading…
x
Reference in New Issue
Block a user