apps/smtp/smtp.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup apps
00003  * @{
00004  */
00005 
00006 /**
00007  * \defgroup smtp SMTP E-mail sender
00008  * @{
00009  *
00010  * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is
00011  * the standard way of sending and transfering e-mail on the
00012  * Internet. This simple example implementation is intended as an
00013  * example of how to implement protocols in uIP, and is able to send
00014  * out e-mail but has not been extensively tested.
00015  */
00016 
00017 /**
00018  * \file
00019  * SMTP example implementation
00020  * \author Adam Dunkels <adam@dunkels.com>
00021  */
00022 
00023 /*
00024  * Copyright (c) 2004, Adam Dunkels.
00025  * All rights reserved.
00026  *
00027  * Redistribution and use in source and binary forms, with or without
00028  * modification, are permitted provided that the following conditions
00029  * are met:
00030  * 1. Redistributions of source code must retain the above copyright
00031  *    notice, this list of conditions and the following disclaimer.
00032  * 2. Redistributions in binary form must reproduce the above copyright
00033  *    notice, this list of conditions and the following disclaimer in the
00034  *    documentation and/or other materials provided with the distribution.
00035  * 3. Neither the name of the Institute nor the names of its contributors
00036  *    may be used to endorse or promote products derived from this software
00037  *    without specific prior written permission.
00038  *
00039  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00040  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00041  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00042  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00043  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00044  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00045  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00046  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00047  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00048  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00049  * SUCH DAMAGE.
00050  *
00051  * This file is part of the uIP TCP/IP stack.
00052  *
00053  * Author: Adam Dunkels <adam@sics.se>
00054  *
00055  * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $
00056  */
00057 #include "smtp.h"
00058 
00059 #include "smtp-strings.h"
00060 #include "psock.h"
00061 #include "uip.h"
00062 
00063 #include <string.h>
00064 
00065 static struct smtp_state s;
00066 
00067 static char *localhostname;
00068 static uip_ipaddr_t smtpserver;
00069 
00070 #define ISO_nl 0x0a
00071 #define ISO_cr 0x0d
00072 
00073 #define ISO_period 0x2e
00074 
00075 #define ISO_2  0x32
00076 #define ISO_3  0x33
00077 #define ISO_4  0x34
00078 #define ISO_5  0x35
00079 
00080 
00081 /*---------------------------------------------------------------------------*/
00082 static
00083 PT_THREAD(smtp_thread(void))
00084 {
00085   PSOCK_BEGIN(&s.psock);
00086 
00087   PSOCK_READTO(&s.psock, ISO_nl);
00088    
00089   if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
00090     PSOCK_CLOSE(&s.psock);
00091     smtp_done(2);
00092     PSOCK_EXIT(&s.psock);
00093   }
00094   
00095   PSOCK_SEND_STR(&s.psock, (char *)smtp_helo);
00096   PSOCK_SEND_STR(&s.psock, localhostname);
00097   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00098 
00099   PSOCK_READTO(&s.psock, ISO_nl);
00100   
00101   if(s.inputbuffer[0] != ISO_2) {
00102     PSOCK_CLOSE(&s.psock);
00103     smtp_done(3);
00104     PSOCK_EXIT(&s.psock);
00105   }
00106 
00107   PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from);
00108   PSOCK_SEND_STR(&s.psock, s.from);
00109   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00110 
00111   PSOCK_READTO(&s.psock, ISO_nl);
00112   
00113   if(s.inputbuffer[0] != ISO_2) {
00114     PSOCK_CLOSE(&s.psock);
00115     smtp_done(4);
00116     PSOCK_EXIT(&s.psock);
00117   }
00118 
00119   PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
00120   PSOCK_SEND_STR(&s.psock, s.to);
00121   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00122 
00123   PSOCK_READTO(&s.psock, ISO_nl);
00124   
00125   if(s.inputbuffer[0] != ISO_2) {
00126     PSOCK_CLOSE(&s.psock);
00127     smtp_done(5);
00128     PSOCK_EXIT(&s.psock);
00129   }
00130   
00131   if(s.cc != 0) {
00132     PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to);
00133     PSOCK_SEND_STR(&s.psock, s.cc);
00134     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00135 
00136     PSOCK_READTO(&s.psock, ISO_nl);
00137   
00138     if(s.inputbuffer[0] != ISO_2) {
00139       PSOCK_CLOSE(&s.psock);
00140       smtp_done(6);
00141       PSOCK_EXIT(&s.psock);
00142     }
00143   }
00144   
00145   PSOCK_SEND_STR(&s.psock, (char *)smtp_data);
00146   
00147   PSOCK_READTO(&s.psock, ISO_nl);
00148   
00149   if(s.inputbuffer[0] != ISO_3) {
00150     PSOCK_CLOSE(&s.psock);
00151     smtp_done(7);
00152     PSOCK_EXIT(&s.psock);
00153   }
00154 
00155   PSOCK_SEND_STR(&s.psock, (char *)smtp_to);
00156   PSOCK_SEND_STR(&s.psock, s.to);
00157   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00158   
00159   if(s.cc != 0) {
00160     PSOCK_SEND_STR(&s.psock, (char *)smtp_cc);
00161     PSOCK_SEND_STR(&s.psock, s.cc);
00162     PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00163   }
00164   
00165   PSOCK_SEND_STR(&s.psock, (char *)smtp_from);
00166   PSOCK_SEND_STR(&s.psock, s.from);
00167   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00168   
00169   PSOCK_SEND_STR(&s.psock, (char *)smtp_subject);
00170   PSOCK_SEND_STR(&s.psock, s.subject);
00171   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl);
00172 
00173   PSOCK_SEND(&s.psock, s.msg, s.msglen);
00174   
00175   PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl);
00176 
00177   PSOCK_READTO(&s.psock, ISO_nl);
00178   if(s.inputbuffer[0] != ISO_2) {
00179     PSOCK_CLOSE(&s.psock);
00180     smtp_done(8);
00181     PSOCK_EXIT(&s.psock);
00182   }
00183 
00184   PSOCK_SEND_STR(&s.psock, (char *)smtp_quit);
00185   smtp_done(SMTP_ERR_OK);
00186   PSOCK_END(&s.psock);
00187 }
00188 /*---------------------------------------------------------------------------*/
00189 void
00190 smtp_appcall(void)
00191 {
00192   if(uip_closed()) {
00193     s.connected = 0;
00194     return;
00195   }
00196   if(uip_aborted() || uip_timedout()) {
00197     s.connected = 0;
00198     smtp_done(1);
00199     return;
00200   }
00201   smtp_thread();
00202 }
00203 /*---------------------------------------------------------------------------*/
00204 /**
00205  * Specificy an SMTP server and hostname.
00206  *
00207  * This function is used to configure the SMTP module with an SMTP
00208  * server and the hostname of the host.
00209  *
00210  * \param lhostname The hostname of the uIP host.
00211  *
00212  * \param server A pointer to a 4-byte array representing the IP
00213  * address of the SMTP server to be configured.
00214  */
00215 void
00216 smtp_configure(char *lhostname, void *server)
00217 {
00218   localhostname = lhostname;
00219   uip_ipaddr_copy(smtpserver, server);
00220 }
00221 /*---------------------------------------------------------------------------*/
00222 /**
00223  * Send an e-mail.
00224  *
00225  * \param to The e-mail address of the receiver of the e-mail.
00226  * \param cc The e-mail address of the CC: receivers of the e-mail.
00227  * \param from The e-mail address of the sender of the e-mail.
00228  * \param subject The subject of the e-mail.
00229  * \param msg The actual e-mail message.
00230  * \param msglen The length of the e-mail message.
00231  */
00232 unsigned char
00233 smtp_send(char *to, char *cc, char *from,
00234           char *subject, char *msg, u16_t msglen)
00235 {
00236   struct uip_conn *conn;
00237 
00238   conn = uip_connect(smtpserver, HTONS(25));
00239   if(conn == NULL) {
00240     return 0;
00241   }
00242   s.connected = 1;
00243   s.to = to;
00244   s.cc = cc;
00245   s.from = from;
00246   s.subject = subject;
00247   s.msg = msg;
00248   s.msglen = msglen;
00249 
00250   PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
00251   
00252   return 1;
00253 }
00254 /*---------------------------------------------------------------------------*/
00255 void
00256 smtp_init(void)
00257 {
00258   s.connected = 0;
00259 }
00260 /*---------------------------------------------------------------------------*/
00261 /** @} */
00262 /** @} */

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  doxygen 1.4.6