libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
SMTP client session, sansIO

Data Structures

struct  lws_smtp_email
struct  lws_smtp_session

Macros

#define LWS_SMTP_ADDR_MAX   254
#define LWS_SMTP_LOCAL_MAX   64
#define LWS_SMTP_SUBJECT_MAX   512
#define LWS_SMTP_MSGID_MAX   128
#define LWS_SMTP_LINE_MAX   998
#define LWS_SMTP_TX_MIN   512

Typedefs

typedef struct lws_smtp_email lws_smtp_email_t
typedef enum lws_smtp_ev lws_smtp_ev_t
typedef struct lws_smtp_session lws_smtp_session_t

Enumerations

enum  lws_smtp_ev {
  LWS_SMTP_EV_NONE , LWS_SMTP_EV_TX , LWS_SMTP_EV_STARTTLS , LWS_SMTP_EV_READY ,
  LWS_SMTP_EV_MAIL_DONE , LWS_SMTP_EV_CLOSE , LWS_SMTP_EV_FAILED
}

Functions

LWS_VISIBLE LWS_EXTERN int lws_smtp_email_check (const lws_smtp_email_t *e)
LWS_VISIBLE LWS_EXTERN int lws_smtp_addr_check (const char *addr)
LWS_VISIBLE LWS_EXTERN void lws_smtp_session_init (lws_smtp_session_t *s, const char *helo, int starttls)
LWS_VISIBLE LWS_EXTERN lws_smtp_ev_t lws_smtp_session_rx (lws_smtp_session_t *s, const uint8_t *buf, size_t len, size_t *used)
LWS_VISIBLE LWS_EXTERN int lws_smtp_session_tx (lws_smtp_session_t *s, uint8_t *buf, size_t max, size_t *produced)
LWS_VISIBLE LWS_EXTERN void lws_smtp_session_tls_up (lws_smtp_session_t *s)
LWS_VISIBLE LWS_EXTERN int lws_smtp_session_mail (lws_smtp_session_t *s, const lws_smtp_email_t *mail)

Detailed Description

SMTP client session, sansIO

The client side of an SMTP session (RFC 5321) with no transport under it: it is handed the server's reply bytes as they arrive, and fills a buffer it is given with the bytes to send next. lws_smtpc (lws-smtp-client.h) runs it over an lws client connection, and that is what most code wants; anything else holding a byte stream to an SMTP server can run it the same way.

A mail is one transaction with one envelope sender and one recipient, and several may be sent in turn on one session. Commands are not pipelined: each one waits for its reply. The message is sent as text/plain in UTF-8, with Date:, From:, To:, Subject: and Message-ID: headers; a Subject: that is not plain ASCII, or is long, is sent as folded RFC 2047 encoded-words. Line ends in the body are sent as CRLF whatever they were, and lines starting with '.' are dot-stuffed.

The session has no clock: how long to wait for a reply is the caller's business.


Data Structure Documentation

◆ lws_smtp_email

struct lws_smtp_email

Definition at line 61 of file lws-smtp.h.

Collaboration diagram for lws_smtp_email:
Data Fields
const char * from

envelope sender and From:, "local@domain"

const char * to

envelope recipient and To:, "local@domain"

const char * subject

UTF-8, with no control characters

const char * body

UTF-8 text, lines ending in LF or CRLF

const char * message_id

Message-ID: without the <>, or NULL to send none. lws_smtpc_queue() makes one when this is NULL

int64_t date

Date: as seconds since 1970 UTC, or 0 to send none. lws_smtpc_queue() uses the time it was queued when this is 0

◆ lws_smtp_session

struct lws_smtp_session

The session's state. The caller owns it and may embed it; its members are not to be written, but .code and .text say what the last complete reply was.

Definition at line 109 of file lws-smtp.h.

Collaboration diagram for lws_smtp_session:
Data Fields
const lws_smtp_email_t * mail
const char * helo
size_t pos
int code
char text[96]
uint16_t rx_line_len
uint16_t rx_code
uint16_t rx_first_code
uint8_t rx_state
uint8_t rx_text_len
uint8_t rx_kw_len
uint8_t rx_kw_end
char rx_kw[16]
uint8_t state
uint8_t item
uint8_t flags

Macro Definition Documentation

◆ LWS_SMTP_ADDR_MAX

#define LWS_SMTP_ADDR_MAX   254

#include <lws-smtp.h>

Definition at line 52 of file lws-smtp.h.

◆ LWS_SMTP_LOCAL_MAX

#define LWS_SMTP_LOCAL_MAX   64

#include <lws-smtp.h>

Definition at line 53 of file lws-smtp.h.

◆ LWS_SMTP_SUBJECT_MAX

#define LWS_SMTP_SUBJECT_MAX   512

#include <lws-smtp.h>

Definition at line 54 of file lws-smtp.h.

◆ LWS_SMTP_MSGID_MAX

#define LWS_SMTP_MSGID_MAX   128

#include <lws-smtp.h>

Definition at line 55 of file lws-smtp.h.

◆ LWS_SMTP_LINE_MAX

#define LWS_SMTP_LINE_MAX   998

#include <lws-smtp.h>

Definition at line 56 of file lws-smtp.h.

◆ LWS_SMTP_TX_MIN

#define LWS_SMTP_TX_MIN   512

#include <lws-smtp.h>

Definition at line 59 of file lws-smtp.h.

Typedef Documentation

◆ lws_smtp_email_t

#include <lws-smtp.h>

◆ lws_smtp_ev_t

typedef enum lws_smtp_ev lws_smtp_ev_t

#include <lws-smtp.h>

what the caller should do after lws_smtp_session_rx()

◆ lws_smtp_session_t

#include <lws-smtp.h>

The session's state. The caller owns it and may embed it; its members are not to be written, but .code and .text say what the last complete reply was.

Enumeration Type Documentation

◆ lws_smtp_ev

#include <lws-smtp.h>

what the caller should do after lws_smtp_session_rx()

Enumerator
LWS_SMTP_EV_NONE 

nothing yet: the rest of the reply is still to come

LWS_SMTP_EV_TX 

there are bytes to send: call lws_smtp_session_tx() when the transport can take them

LWS_SMTP_EV_STARTTLS 

the server agreed to STARTTLS: start tls on the transport, then call lws_smtp_session_tls_up(). Anything the server sent after this reply was not protected by the tls and must be discarded

LWS_SMTP_EV_READY 

the session can take a mail: call lws_smtp_session_mail() with one, or with NULL to end the session

LWS_SMTP_EV_MAIL_DONE 

the mail given to lws_smtp_session_mail() is concluded, as .code says: 2xx it was accepted, 4xx refused for now, 5xx refused. Then the session can take a mail as for LWS_SMTP_EV_READY

LWS_SMTP_EV_CLOSE 

the session ended as it was asked to: close the transport

LWS_SMTP_EV_FAILED 

the session failed, or the server refused it: close the transport. .code and .text say why, .code 0 being something the server sent that was not an SMTP reply to what we asked

Definition at line 79 of file lws-smtp.h.

79 {
enum lws_smtp_ev lws_smtp_ev_t
@ LWS_SMTP_EV_TX
Definition lws-smtp.h:82
@ LWS_SMTP_EV_READY
Definition lws-smtp.h:89
@ LWS_SMTP_EV_STARTTLS
Definition lws-smtp.h:85
@ LWS_SMTP_EV_NONE
Definition lws-smtp.h:80
@ LWS_SMTP_EV_MAIL_DONE
Definition lws-smtp.h:92
@ LWS_SMTP_EV_CLOSE
Definition lws-smtp.h:96
@ LWS_SMTP_EV_FAILED
Definition lws-smtp.h:98

Function Documentation

◆ lws_smtp_email_check()

LWS_VISIBLE LWS_EXTERN int lws_smtp_email_check ( const lws_smtp_email_t * e)

#include <lws-smtp.h>

lws_smtp_email_check() - is a mail acceptable to send

Parameters
ethe mail

The addresses must be plain "local@domain" (no quoted local parts, no address literals, no UTF-8), the subject UTF-8 with no control characters and at most LWS_SMTP_SUBJECT_MAX bytes, each body line at most LWS_SMTP_LINE_MAX once it is sent, and a message_id, if given, a "left@right" of the characters an address may have. What is checked here is what keeps what the session sends well-formed, and lws_smtp_session_mail() refuses a mail that fails it.

Returns 0 if the mail is acceptable, else nonzero.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_addr_check()

LWS_VISIBLE LWS_EXTERN int lws_smtp_addr_check ( const char * addr)

#include <lws-smtp.h>

lws_smtp_addr_check() - is this a plain "local@domain" address

Parameters
addrthe address, NUL-terminated

Returns 0 if it is, else nonzero.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_session_init()

LWS_VISIBLE LWS_EXTERN void lws_smtp_session_init ( lws_smtp_session_t * s,
const char * helo,
int starttls )

#include <lws-smtp.h>

lws_smtp_session_init() - start a session

Parameters
sthe session state to initialize
heloour name for EHLO and HELO (a domain), which must stay valid for the life of the session
starttlsnonzero to require STARTTLS before any mail is sent

Call once the transport to the server is up; the session waits for the server's greeting. With starttls, a server that does not offer STARTTLS, or refuses it, fails the session: no mail goes in plaintext.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_session_rx()

LWS_VISIBLE LWS_EXTERN lws_smtp_ev_t lws_smtp_session_rx ( lws_smtp_session_t * s,
const uint8_t * buf,
size_t len,
size_t * used )

#include <lws-smtp.h>

lws_smtp_session_rx() - the server sent these bytes

Parameters
sthe session
bufthe bytes
lenhow many
usedset to how many of them were taken

Takes bytes up to the end of the first complete reply, and says what the caller is to do about it. If fewer than len were used, call again with the rest after acting on the result... except after LWS_SMTP_EV_STARTTLS, where the rest must be discarded, and after LWS_SMTP_EV_CLOSE and LWS_SMTP_EV_FAILED, where the session is over.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_session_tx()

LWS_VISIBLE LWS_EXTERN int lws_smtp_session_tx ( lws_smtp_session_t * s,
uint8_t * buf,
size_t max,
size_t * produced )

#include <lws-smtp.h>

lws_smtp_session_tx() - fill a buffer with the next bytes to send

Parameters
sthe session
bufwhere to put them
maxhow much room there is, at least LWS_SMTP_TX_MIN
producedset to how many bytes were put in buf

Returns 1 if there is more to send after these, 0 if nothing more is to be sent until the server replies, or -1 if max is too small or the mail could not be encoded.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_session_tls_up()

LWS_VISIBLE LWS_EXTERN void lws_smtp_session_tls_up ( lws_smtp_session_t * s)

#include <lws-smtp.h>

lws_smtp_session_tls_up() - tls is up after LWS_SMTP_EV_STARTTLS

Parameters
sthe session

The session forgets what the server said before the tls and greets it again: there is then something to send.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_smtp_session_mail()

LWS_VISIBLE LWS_EXTERN int lws_smtp_session_mail ( lws_smtp_session_t * s,
const lws_smtp_email_t * mail )

#include <lws-smtp.h>

lws_smtp_session_mail() - send a mail, or end the session

Parameters
sthe session
mailthe mail, or NULL to end the session

Only after LWS_SMTP_EV_READY or LWS_SMTP_EV_MAIL_DONE. mail must stay valid until its LWS_SMTP_EV_MAIL_DONE, or the session ends. There is then something to send.

Returns 0, or -1 if the session cannot take a mail now, or mail does not pass lws_smtp_email_check(); the session is unchanged then.