smtp.c 6.8 KB

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