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 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 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 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 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 256 smtp_init(void) 257 { 258 s.connected = 0; 259 } 260 /*---------------------------------------------------------------------------*/ 261 /** @} */ 262 /** @} */ 263