1 /**
2 * \addtogroup apps
3 * @{
4 */
5
6 /**
7 * \defgroup smtp SMTP E-mail sender
8 * @{
9 *
10 * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is
11 * the standard way of sending and transfering e-mail on the
12 * Internet. This simple example implementation is intended as an
13 * example of how to implement protocols in uIP, and is able to send
14 * out e-mail but has not been extensively tested.
15 */
16
17 /**
18 * \file
19 * SMTP example implementation
20 * \author Adam Dunkels <[email protected]>
21 */
22
23 /*
24 * Copyright (c) 2004, Adam Dunkels.
25 * All rights reserved.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. Neither the name of the Institute nor the names of its contributors
36 * may be used to endorse or promote products derived from this software
37 * without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
43 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * SUCH DAMAGE.
50 *
51 * This file is part of the uIP TCP/IP stack.
52 *
53 * Author: Adam Dunkels <[email protected]>
54 *
55 * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $
56 */
57 #include "smtp.h"
58
59 #include "smtp-strings.h"
60 #include "psock.h"
61 #include "uip.h"
62
63 #include <string.h>
64
65 static struct smtp_state s;
66
67 static char *localhostname;
68 static uip_ipaddr_t smtpserver;
69
70 #define ISO_nl 0x0a
71 #define ISO_cr 0x0d
72
73 #define ISO_period 0x2e
74
75 #define ISO_2 0x32
76 #define ISO_3 0x33
77 #define ISO_4 0x34
78 #define ISO_5 0x35
79
80
81 /*---------------------------------------------------------------------------*/
82 static
PT_THREAD(smtp_thread (void))83 PT_THREAD(smtp_thread(void))
84 {
85 PSOCK_BEGIN(&s.psock);
86
87 PSOCK_READTO(&s.psock, ISO_nl);
88
89 if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
90 PSOCK_CLOSE(&s.psock);
91 smtp_done(2);
92 PSOCK_EXIT(&s.psock);
93 }
94
95 PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
96 PSOCK_SEND_STR(&s.psock, localhostname);
97 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
98
99 PSOCK_READTO(&s.psock, ISO_nl);
100
101 if(s.inputbuffer[0] != ISO_2) {
102 PSOCK_CLOSE(&s.psock);
103 smtp_done(3);
104 PSOCK_EXIT(&s.psock);
105 }
106
107 PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
108 PSOCK_SEND_STR(&s.psock, s.from);
109 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
110
111 PSOCK_READTO(&s.psock, ISO_nl);
112
113 if(s.inputbuffer[0] != ISO_2) {
114 PSOCK_CLOSE(&s.psock);
115 smtp_done(4);
116 PSOCK_EXIT(&s.psock);
117 }
118
119 PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
120 PSOCK_SEND_STR(&s.psock, s.to);
121 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
122
123 PSOCK_READTO(&s.psock, ISO_nl);
124
125 if(s.inputbuffer[0] != ISO_2) {
126 PSOCK_CLOSE(&s.psock);
127 smtp_done(5);
128 PSOCK_EXIT(&s.psock);
129 }
130
131 if(s.cc != 0) {
132 PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
133 PSOCK_SEND_STR(&s.psock, s.cc);
134 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
135
136 PSOCK_READTO(&s.psock, ISO_nl);
137
138 if(s.inputbuffer[0] != ISO_2) {
139 PSOCK_CLOSE(&s.psock);
140 smtp_done(6);
141 PSOCK_EXIT(&s.psock);
142 }
143 }
144
145 PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
146
147 PSOCK_READTO(&s.psock, ISO_nl);
148
149 if(s.inputbuffer[0] != ISO_3) {
150 PSOCK_CLOSE(&s.psock);
151 smtp_done(7);
152 PSOCK_EXIT(&s.psock);
153 }
154
155 PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
156 PSOCK_SEND_STR(&s.psock, s.to);
157 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
158
159 if(s.cc != 0) {
160 PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
161 PSOCK_SEND_STR(&s.psock, s.cc);
162 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
163 }
164
165 PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
166 PSOCK_SEND_STR(&s.psock, s.from);
167 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
168
169 PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
170 PSOCK_SEND_STR(&s.psock, s.subject);
171 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
172
173 PSOCK_SEND(&s.psock, s.msg, s.msglen);
174
175 PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);
176
177 PSOCK_READTO(&s.psock, ISO_nl);
178 if(s.inputbuffer[0] != ISO_2) {
179 PSOCK_CLOSE(&s.psock);
180 smtp_done(8);
181 PSOCK_EXIT(&s.psock);
182 }
183
184 PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
185 smtp_done(SMTP_ERR_OK);
186 PSOCK_END(&s.psock);
187 }
188 /*---------------------------------------------------------------------------*/
189 void
smtp_appcall(void)190 smtp_appcall(void)
191 {
192 if(uip_closed()) {
193 s.connected = 0;
194 return;
195 }
196 if(uip_aborted() || uip_timedout()) {
197 s.connected = 0;
198 smtp_done(1);
199 return;
200 }
201 smtp_thread();
202 }
203 /*---------------------------------------------------------------------------*/
204 /**
205 * Specificy an SMTP server and hostname.
206 *
207 * This function is used to configure the SMTP module with an SMTP
208 * server and the hostname of the host.
209 *
210 * \param lhostname The hostname of the uIP host.
211 *
212 * \param server A pointer to a 4-byte array representing the IP
213 * address of the SMTP server to be configured.
214 */
215 void
smtp_configure(char * lhostname,void * server)216 smtp_configure(char *lhostname, void *server)
217 {
218 localhostname = lhostname;
219 uip_ipaddr_copy(smtpserver, server);
220 }
221 /*---------------------------------------------------------------------------*/
222 /**
223 * Send an e-mail.
224 *
225 * \param to The e-mail address of the receiver of the e-mail.
226 * \param cc The e-mail address of the CC: receivers of the e-mail.
227 * \param from The e-mail address of the sender of the e-mail.
228 * \param subject The subject of the e-mail.
229 * \param msg The actual e-mail message.
230 * \param msglen The length of the e-mail message.
231 */
232 unsigned char
smtp_send(char * to,char * cc,char * from,char * subject,char * msg,u16_t msglen)233 smtp_send(char *to, char *cc, char *from,
234 char *subject, char *msg, u16_t msglen)
235 {
236 struct uip_conn *conn;
237
238 conn = uip_connect(smtpserver, HTONS(25));
239 if(conn == NULL) {
240 return 0;
241 }
242 s.connected = 1;
243 s.to = to;
244 s.cc = cc;
245 s.from = from;
246 s.subject = subject;
247 s.msg = msg;
248 s.msglen = msglen;
249
250 PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
251
252 return 1;
253 }
254 /*---------------------------------------------------------------------------*/
255 void
smtp_init(void)256 smtp_init(void)
257 {
258 s.connected = 0;
259 }
260 /*---------------------------------------------------------------------------*/
261 /** @} */
262 /** @} */
263