xref: /aosp_15_r20/external/libwebsockets/lib/abstract/protocols/smtp/smtp-sequencer.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * Abstract SMTP support for libwebsockets - SMTP sequencer
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2016-2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  *
24*1c60b9acSAndroid Build Coastguard Worker  * This sequencer sits above the abstract protocol, and manages queueing,
25*1c60b9acSAndroid Build Coastguard Worker  * retrying mail transmission, and retry limits.
26*1c60b9acSAndroid Build Coastguard Worker  *
27*1c60b9acSAndroid Build Coastguard Worker  * Having the sequencer means that, eg, we can manage retries after complete
28*1c60b9acSAndroid Build Coastguard Worker  * connection failure.
29*1c60b9acSAndroid Build Coastguard Worker  *
30*1c60b9acSAndroid Build Coastguard Worker  * Connections to the smtp server are serialized
31*1c60b9acSAndroid Build Coastguard Worker  */
32*1c60b9acSAndroid Build Coastguard Worker 
33*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
34*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-abstract-protocols-smtp.h"
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker typedef enum {
37*1c60b9acSAndroid Build Coastguard Worker 	LSMTPSS_DISCONNECTED,
38*1c60b9acSAndroid Build Coastguard Worker 	LSMTPSS_CONNECTING,
39*1c60b9acSAndroid Build Coastguard Worker 	LSMTPSS_CONNECTED,
40*1c60b9acSAndroid Build Coastguard Worker 	LSMTPSS_BUSY,
41*1c60b9acSAndroid Build Coastguard Worker } smtpss_connstate_t;
42*1c60b9acSAndroid Build Coastguard Worker 
43*1c60b9acSAndroid Build Coastguard Worker typedef struct lws_smtp_sequencer {
44*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dll2_owner		emails_owner; /* email queue */
45*1c60b9acSAndroid Build Coastguard Worker 
46*1c60b9acSAndroid Build Coastguard Worker 	lws_abs_t			*abs, *instance;
47*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_sequencer_args_t	args;
48*1c60b9acSAndroid Build Coastguard Worker 	struct lws_sequencer		*seq;
49*1c60b9acSAndroid Build Coastguard Worker 
50*1c60b9acSAndroid Build Coastguard Worker 	smtpss_connstate_t		connstate;
51*1c60b9acSAndroid Build Coastguard Worker 
52*1c60b9acSAndroid Build Coastguard Worker 	time_t				email_connect_started;
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker 	/* holds the HELO for the smtp protocol to consume */
55*1c60b9acSAndroid Build Coastguard Worker 	lws_token_map_t			apt[3];
56*1c60b9acSAndroid Build Coastguard Worker } lws_smtp_sequencer_t;
57*1c60b9acSAndroid Build Coastguard Worker 
58*1c60b9acSAndroid Build Coastguard Worker /* sequencer messages specific to this sequencer */
59*1c60b9acSAndroid Build Coastguard Worker 
60*1c60b9acSAndroid Build Coastguard Worker enum {
61*1c60b9acSAndroid Build Coastguard Worker 	SEQ_MSG_CLIENT_FAILED = LWSSEQ_USER_BASE,
62*1c60b9acSAndroid Build Coastguard Worker 	SEQ_MSG_CLIENT_DONE,
63*1c60b9acSAndroid Build Coastguard Worker };
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker /*
66*1c60b9acSAndroid Build Coastguard Worker  * We're going to bind to the raw-skt transport, so tell that what we want it
67*1c60b9acSAndroid Build Coastguard Worker  * to connect to
68*1c60b9acSAndroid Build Coastguard Worker  */
69*1c60b9acSAndroid Build Coastguard Worker 
70*1c60b9acSAndroid Build Coastguard Worker static const lws_token_map_t smtp_rs_transport_tokens[] = {
71*1c60b9acSAndroid Build Coastguard Worker  {
72*1c60b9acSAndroid Build Coastguard Worker 	.u = { .value = "127.0.0.1" },
73*1c60b9acSAndroid Build Coastguard Worker 	.name_index = LTMI_PEER_V_DNS_ADDRESS,
74*1c60b9acSAndroid Build Coastguard Worker  }, {
75*1c60b9acSAndroid Build Coastguard Worker 	.u = { .lvalue = 25 },
76*1c60b9acSAndroid Build Coastguard Worker 	.name_index = LTMI_PEER_LV_PORT,
77*1c60b9acSAndroid Build Coastguard Worker  }, {
78*1c60b9acSAndroid Build Coastguard Worker  }
79*1c60b9acSAndroid Build Coastguard Worker };
80*1c60b9acSAndroid Build Coastguard Worker 
81*1c60b9acSAndroid Build Coastguard Worker static void
lws_smtpc_kick_internal(lws_smtp_sequencer_t * s)82*1c60b9acSAndroid Build Coastguard Worker lws_smtpc_kick_internal(lws_smtp_sequencer_t *s)
83*1c60b9acSAndroid Build Coastguard Worker {
84*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_email_t *e;
85*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t *d;
86*1c60b9acSAndroid Build Coastguard Worker 	char buf[64];
87*1c60b9acSAndroid Build Coastguard Worker 	int n;
88*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t *pd2;
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker 	pd2 = lws_dll2_get_head(&s->emails_owner);
91*1c60b9acSAndroid Build Coastguard Worker 	if (!pd2)
92*1c60b9acSAndroid Build Coastguard Worker 		return;
93*1c60b9acSAndroid Build Coastguard Worker 
94*1c60b9acSAndroid Build Coastguard Worker 	e = lws_container_of(pd2, lws_smtp_email_t, list);
95*1c60b9acSAndroid Build Coastguard Worker 	if (!e)
96*1c60b9acSAndroid Build Coastguard Worker 		return;
97*1c60b9acSAndroid Build Coastguard Worker 
98*1c60b9acSAndroid Build Coastguard Worker 	/* Is there something to do?  If so, we need a connection... */
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker 	if (s->connstate == LSMTPSS_DISCONNECTED) {
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 		s->apt[0].u.value = s->args.helo;
103*1c60b9acSAndroid Build Coastguard Worker 		s->apt[0].name_index = LTMI_PSMTP_V_HELO;
104*1c60b9acSAndroid Build Coastguard Worker 		s->apt[1].u.value = (void *)e;
105*1c60b9acSAndroid Build Coastguard Worker 		s->apt[1].name_index = LTMI_PSMTP_V_LWS_SMTP_EMAIL_T;
106*1c60b9acSAndroid Build Coastguard Worker 
107*1c60b9acSAndroid Build Coastguard Worker 		/*
108*1c60b9acSAndroid Build Coastguard Worker 		 * create and connect the smtp protocol + transport
109*1c60b9acSAndroid Build Coastguard Worker 		 */
110*1c60b9acSAndroid Build Coastguard Worker 
111*1c60b9acSAndroid Build Coastguard Worker 		s->abs = lws_abstract_alloc(s->args.vhost, NULL, "smtp.raw_skt",
112*1c60b9acSAndroid Build Coastguard Worker 					    s->apt, smtp_rs_transport_tokens,
113*1c60b9acSAndroid Build Coastguard Worker 					    s->seq, NULL);
114*1c60b9acSAndroid Build Coastguard Worker 		if (!s->abs)
115*1c60b9acSAndroid Build Coastguard Worker 			return;
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 		s->instance = lws_abs_bind_and_create_instance(s->abs);
118*1c60b9acSAndroid Build Coastguard Worker 		if (!s->instance) {
119*1c60b9acSAndroid Build Coastguard Worker 			lws_abstract_free(&s->abs);
120*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: failed to create SMTP client\n", __func__);
121*1c60b9acSAndroid Build Coastguard Worker 
122*1c60b9acSAndroid Build Coastguard Worker 			goto bail1;
123*1c60b9acSAndroid Build Coastguard Worker 		}
124*1c60b9acSAndroid Build Coastguard Worker 
125*1c60b9acSAndroid Build Coastguard Worker 		s->connstate = LSMTPSS_CONNECTING;
126*1c60b9acSAndroid Build Coastguard Worker 		lws_seq_timeout_us(s->seq, 10 * LWS_USEC_PER_SEC);
127*1c60b9acSAndroid Build Coastguard Worker 		return;
128*1c60b9acSAndroid Build Coastguard Worker 	}
129*1c60b9acSAndroid Build Coastguard Worker 
130*1c60b9acSAndroid Build Coastguard Worker 	/* ask the transport if we have a connection to the server ongoing */
131*1c60b9acSAndroid Build Coastguard Worker 
132*1c60b9acSAndroid Build Coastguard Worker 	if (s->abs->at->state(s->abs->ati)) {
133*1c60b9acSAndroid Build Coastguard Worker 		/*
134*1c60b9acSAndroid Build Coastguard Worker 		 * there's a connection, it could be still trying to connect
135*1c60b9acSAndroid Build Coastguard Worker 		 * or established
136*1c60b9acSAndroid Build Coastguard Worker 		 */
137*1c60b9acSAndroid Build Coastguard Worker 		s->abs->at->ask_for_writeable(s->abs->ati);
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 		return;
140*1c60b9acSAndroid Build Coastguard Worker 	}
141*1c60b9acSAndroid Build Coastguard Worker 
142*1c60b9acSAndroid Build Coastguard Worker 	/* there's no existing connection */
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 	lws_smtpc_state_transition(c, LGSSMTP_CONNECTING);
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker 	if (s->abs->at->client_conn(s->abs)) {
147*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: failed to connect\n", __func__);
148*1c60b9acSAndroid Build Coastguard Worker 
149*1c60b9acSAndroid Build Coastguard Worker 		return;
150*1c60b9acSAndroid Build Coastguard Worker 	}
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker 	e->tries++;
153*1c60b9acSAndroid Build Coastguard Worker 	e->last_try = lws_now_secs();
154*1c60b9acSAndroid Build Coastguard Worker }
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 
157*1c60b9acSAndroid Build Coastguard Worker /*
158*1c60b9acSAndroid Build Coastguard Worker  * The callback we get from the smtp protocol... we use this to drive
159*1c60b9acSAndroid Build Coastguard Worker  * decisions about destroy email, retry and fail.
160*1c60b9acSAndroid Build Coastguard Worker  *
161*1c60b9acSAndroid Build Coastguard Worker  * Sequencer will handle it via the event loop.
162*1c60b9acSAndroid Build Coastguard Worker  */
163*1c60b9acSAndroid Build Coastguard Worker 
164*1c60b9acSAndroid Build Coastguard Worker static int
email_result(void * e,void * d,int disp,void * b,size_t l)165*1c60b9acSAndroid Build Coastguard Worker email_result(void *e, void *d, int disp, void *b, size_t l)
166*1c60b9acSAndroid Build Coastguard Worker {
167*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_sequencer_t *s = (lws_smtp_sequencer_t *)d;
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	lws_sequencer_event(s->seq, LWSSEQ_USER_BASE + disp, e);
170*1c60b9acSAndroid Build Coastguard Worker 
171*1c60b9acSAndroid Build Coastguard Worker 	return 0;
172*1c60b9acSAndroid Build Coastguard Worker }
173*1c60b9acSAndroid Build Coastguard Worker 
174*1c60b9acSAndroid Build Coastguard Worker static int
cleanup(struct lws_dll2 * d,void * user)175*1c60b9acSAndroid Build Coastguard Worker cleanup(struct lws_dll2 *d, void *user)
176*1c60b9acSAndroid Build Coastguard Worker {
177*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_email_t *e;
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 	e = lws_container_of(d, lws_smtp_email_t, list);
180*1c60b9acSAndroid Build Coastguard Worker 	if (e->done)
181*1c60b9acSAndroid Build Coastguard Worker 		e->done(e, "destroying", 10);
182*1c60b9acSAndroid Build Coastguard Worker 
183*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_remove(d);
184*1c60b9acSAndroid Build Coastguard Worker 	lws_free(e);
185*1c60b9acSAndroid Build Coastguard Worker 
186*1c60b9acSAndroid Build Coastguard Worker 	return 0;
187*1c60b9acSAndroid Build Coastguard Worker }
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker static lws_seq_cb_return_t
smtp_sequencer_cb(struct lws_sequencer * seq,void * user,int event,void * data)190*1c60b9acSAndroid Build Coastguard Worker smtp_sequencer_cb(struct lws_sequencer *seq, void *user, int event, void *data)
191*1c60b9acSAndroid Build Coastguard Worker {
192*1c60b9acSAndroid Build Coastguard Worker 	struct lws_smtp_sequencer_t *s = (struct lws_smtp_sequencer_t *)user;
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker 	switch ((int)event) {
195*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_CREATED: /* our sequencer just got started */
196*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: %s: created\n", __func__,
197*1c60b9acSAndroid Build Coastguard Worker 			    lws_sequencer_name(seq));
198*1c60b9acSAndroid Build Coastguard Worker 		s->connstate = LSMTPSS_DISCONNECTED;
199*1c60b9acSAndroid Build Coastguard Worker 		s->state = 0;  /* first thing we'll do is the first url */
200*1c60b9acSAndroid Build Coastguard Worker 		goto step;
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_DESTROYED:
203*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_foreach_safe(&s->pending_owner, NULL, cleanup);
204*1c60b9acSAndroid Build Coastguard Worker 		break;
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_TIMED_OUT:
207*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: LWSSEQ_TIMED_OUT\n", __func__);
208*1c60b9acSAndroid Build Coastguard Worker 		break;
209*1c60b9acSAndroid Build Coastguard Worker 
210*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_USER_BASE + LWS_SMTP_DISPOSITION_SENT:
211*1c60b9acSAndroid Build Coastguard Worker 		lws_smtpc_free_email(data);
212*1c60b9acSAndroid Build Coastguard Worker 		break;
213*1c60b9acSAndroid Build Coastguard Worker 
214*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_WSI_CONNECTED:
215*1c60b9acSAndroid Build Coastguard Worker 		s->connstate = LSMTPSS_CONNECTED;
216*1c60b9acSAndroid Build Coastguard Worker 		lws_smtpc_kick_internal(s);
217*1c60b9acSAndroid Build Coastguard Worker 		break;
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_WSI_CONN_FAIL:
220*1c60b9acSAndroid Build Coastguard Worker 	case LWSSEQ_WSI_CONN_CLOSE:
221*1c60b9acSAndroid Build Coastguard Worker 		s->connstate = LSMTPSS_DISCONNECTED;
222*1c60b9acSAndroid Build Coastguard Worker 		lws_smtpc_kick_internal(s);
223*1c60b9acSAndroid Build Coastguard Worker 		break;
224*1c60b9acSAndroid Build Coastguard Worker 
225*1c60b9acSAndroid Build Coastguard Worker 	case SEQ_MSG_SENT:
226*1c60b9acSAndroid Build Coastguard Worker 		break;
227*1c60b9acSAndroid Build Coastguard Worker 
228*1c60b9acSAndroid Build Coastguard Worker 	default:
229*1c60b9acSAndroid Build Coastguard Worker 		break;
230*1c60b9acSAndroid Build Coastguard Worker 	}
231*1c60b9acSAndroid Build Coastguard Worker 
232*1c60b9acSAndroid Build Coastguard Worker 	return LWSSEQ_RET_CONTINUE;
233*1c60b9acSAndroid Build Coastguard Worker }
234*1c60b9acSAndroid Build Coastguard Worker 
235*1c60b9acSAndroid Build Coastguard Worker /*
236*1c60b9acSAndroid Build Coastguard Worker  * Creates an lws_sequencer to manage the test sequence
237*1c60b9acSAndroid Build Coastguard Worker  */
238*1c60b9acSAndroid Build Coastguard Worker 
239*1c60b9acSAndroid Build Coastguard Worker lws_smtp_sequencer_t *
lws_smtp_sequencer_create(const lws_smtp_sequencer_args_t * args)240*1c60b9acSAndroid Build Coastguard Worker lws_smtp_sequencer_create(const lws_smtp_sequencer_args_t *args)
241*1c60b9acSAndroid Build Coastguard Worker {
242*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_sequencer_t *s;
243*1c60b9acSAndroid Build Coastguard Worker 	struct lws_sequencer *seq;
244*1c60b9acSAndroid Build Coastguard Worker 
245*1c60b9acSAndroid Build Coastguard Worker 	/*
246*1c60b9acSAndroid Build Coastguard Worker 	 * Create a sequencer in the event loop to manage the SMTP queue
247*1c60b9acSAndroid Build Coastguard Worker 	 */
248*1c60b9acSAndroid Build Coastguard Worker 
249*1c60b9acSAndroid Build Coastguard Worker 	seq = lws_sequencer_create(args->vhost->context, 0,
250*1c60b9acSAndroid Build Coastguard Worker 				   sizeof(lws_smtp_sequencer_t), (void **)&s,
251*1c60b9acSAndroid Build Coastguard Worker 				   smtp_sequencer_cb, "smtp-seq");
252*1c60b9acSAndroid Build Coastguard Worker 	if (!seq) {
253*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to create sequencer\n", __func__);
254*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
255*1c60b9acSAndroid Build Coastguard Worker 	}
256*1c60b9acSAndroid Build Coastguard Worker 
257*1c60b9acSAndroid Build Coastguard Worker 	s->abs = *args->abs;
258*1c60b9acSAndroid Build Coastguard Worker 	s->args = *args;
259*1c60b9acSAndroid Build Coastguard Worker 	s->seq = seq;
260*1c60b9acSAndroid Build Coastguard Worker 
261*1c60b9acSAndroid Build Coastguard Worker 	/* set defaults in our copy of the args */
262*1c60b9acSAndroid Build Coastguard Worker 
263*1c60b9acSAndroid Build Coastguard Worker 	if (!s->args.helo[0])
264*1c60b9acSAndroid Build Coastguard Worker 		strcpy(s->args.helo, "default-helo");
265*1c60b9acSAndroid Build Coastguard Worker 	if (!s->args.email_queue_max)
266*1c60b9acSAndroid Build Coastguard Worker 		s->args.email_queue_max = 8;
267*1c60b9acSAndroid Build Coastguard Worker 	if (!s->args.retry_interval)
268*1c60b9acSAndroid Build Coastguard Worker 		s->args.retry_interval = 15 * 60;
269*1c60b9acSAndroid Build Coastguard Worker 	if (!s->args.delivery_timeout)
270*1c60b9acSAndroid Build Coastguard Worker 		s->args.delivery_timeout = 12 * 60 * 60;
271*1c60b9acSAndroid Build Coastguard Worker 
272*1c60b9acSAndroid Build Coastguard Worker 	return s;
273*1c60b9acSAndroid Build Coastguard Worker }
274*1c60b9acSAndroid Build Coastguard Worker 
275*1c60b9acSAndroid Build Coastguard Worker void
lws_smtp_sequencer_destroy(lws_smtp_sequencer_t * s)276*1c60b9acSAndroid Build Coastguard Worker lws_smtp_sequencer_destroy(lws_smtp_sequencer_t *s)
277*1c60b9acSAndroid Build Coastguard Worker {
278*1c60b9acSAndroid Build Coastguard Worker 	/* sequencer destruction destroys all assets */
279*1c60b9acSAndroid Build Coastguard Worker 	lws_sequencer_destroy(&s->seq);
280*1c60b9acSAndroid Build Coastguard Worker }
281*1c60b9acSAndroid Build Coastguard Worker 
282*1c60b9acSAndroid Build Coastguard Worker int
lws_smtpc_add_email(lws_smtp_sequencer_t * s,const char * payload,size_t payload_len,const char * sender,const char * recipient,void * data,lws_smtp_cb_t done)283*1c60b9acSAndroid Build Coastguard Worker lws_smtpc_add_email(lws_smtp_sequencer_t *s, const char *payload,
284*1c60b9acSAndroid Build Coastguard Worker 		    size_t payload_len, const char *sender,
285*1c60b9acSAndroid Build Coastguard Worker 		    const char *recipient, void *data, lws_smtp_cb_t done)
286*1c60b9acSAndroid Build Coastguard Worker {
287*1c60b9acSAndroid Build Coastguard Worker 	lws_smtp_email_t *e;
288*1c60b9acSAndroid Build Coastguard Worker 
289*1c60b9acSAndroid Build Coastguard Worker 	if (s->emails_owner.count > s->args.email_queue_max) {
290*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: email queue at limit of %d\n", __func__,
291*1c60b9acSAndroid Build Coastguard Worker 			 (int)s->args.email_queue_max);
292*1c60b9acSAndroid Build Coastguard Worker 
293*1c60b9acSAndroid Build Coastguard Worker 		return 1;
294*1c60b9acSAndroid Build Coastguard Worker 	}
295*1c60b9acSAndroid Build Coastguard Worker 
296*1c60b9acSAndroid Build Coastguard Worker 	if (!done)
297*1c60b9acSAndroid Build Coastguard Worker 		return 1;
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker 	e = malloc(sizeof(*e) + payload_len + 1);
300*1c60b9acSAndroid Build Coastguard Worker 	if (!e)
301*1c60b9acSAndroid Build Coastguard Worker 		return 1;
302*1c60b9acSAndroid Build Coastguard Worker 
303*1c60b9acSAndroid Build Coastguard Worker 	memset(e, 0, sizeof(*e));
304*1c60b9acSAndroid Build Coastguard Worker 
305*1c60b9acSAndroid Build Coastguard Worker 	e->data = data;
306*1c60b9acSAndroid Build Coastguard Worker 	e->done = done;
307*1c60b9acSAndroid Build Coastguard Worker 
308*1c60b9acSAndroid Build Coastguard Worker 	lws_strncpy(e->from, sender, sizeof(e->from));
309*1c60b9acSAndroid Build Coastguard Worker 	lws_strncpy(e->to, recipient, sizeof(e->to));
310*1c60b9acSAndroid Build Coastguard Worker 
311*1c60b9acSAndroid Build Coastguard Worker 	memcpy((char *)&e[1], payload, payload_len + 1);
312*1c60b9acSAndroid Build Coastguard Worker 
313*1c60b9acSAndroid Build Coastguard Worker 	e->added = lws_now_secs();
314*1c60b9acSAndroid Build Coastguard Worker 	e->last_try = 0;
315*1c60b9acSAndroid Build Coastguard Worker 	e->tries = 0;
316*1c60b9acSAndroid Build Coastguard Worker 
317*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_clear(&e->list);
318*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_add_tail(&e->list, &s->emails_owner);
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 	lws_smtpc_kick_internal(s);
321*1c60b9acSAndroid Build Coastguard Worker 
322*1c60b9acSAndroid Build Coastguard Worker 	return 0;
323*1c60b9acSAndroid Build Coastguard Worker }
324