/* * Copyright (c) 2004, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file is part of the Contiki operating system. * * Author: Adam Dunkels * * $Id: smtp-socket.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $ */ #include "smtp.h" #include "smtp-strings.h" #include "contiki-net.h" #include struct smtp_state { char connected; struct psock psock; char inputbuffer[4]; char *to; char *cc; char *from; char *subject; char *msg; u8_t msgwidth; u8_t msgheight; u8_t line; }; static struct smtp_state s; static char *localhostname; static u16_t smtpserver[2]; #define ISO_nl 0x0a #define ISO_cr 0x0d #define ISO_period 0x2e #define ISO_2 0x32 #define ISO_3 0x33 #define ISO_4 0x34 #define ISO_5 0x35 #define SEND_STRING(s, str) PSOCK_SEND(s, str, strlen(str)) /*---------------------------------------------------------------------------*/ static PT_THREAD(smtp_thread(void)) { PSOCK_BEGIN(&s.psock); PSOCK_READTO(&s.psock, ISO_nl); if(strncmp(s.inputbuffer, smtp_220, 3) != 0) { PSOCK_CLOSE(&s.psock); smtp_done(2); PSOCK_EXIT(&s.psock); } SEND_STRING(&s.psock, (char *)smtp_helo); SEND_STRING(&s.psock, localhostname); SEND_STRING(&s.psock, (char *)smtp_crnl); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_2) { PSOCK_CLOSE(&s.psock); smtp_done(3); PSOCK_EXIT(&s.psock); } SEND_STRING(&s.psock, (char *)smtp_mail_from); SEND_STRING(&s.psock, s.from); SEND_STRING(&s.psock, (char *)smtp_crnl); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_2) { PSOCK_CLOSE(&s.psock); smtp_done(4); PSOCK_EXIT(&s.psock); } SEND_STRING(&s.psock, (char *)smtp_rcpt_to); SEND_STRING(&s.psock, s.to); SEND_STRING(&s.psock, (char *)smtp_crnl); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_2) { PSOCK_CLOSE(&s.psock); smtp_done(5); PSOCK_EXIT(&s.psock); } if(*s.cc != 0) { SEND_STRING(&s.psock, (char *)smtp_rcpt_to); SEND_STRING(&s.psock, s.cc); SEND_STRING(&s.psock, (char *)smtp_crnl); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_2) { PSOCK_CLOSE(&s.psock); smtp_done(6); PSOCK_EXIT(&s.psock); } } SEND_STRING(&s.psock, (char *)smtp_data); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_3) { PSOCK_CLOSE(&s.psock); smtp_done(7); PSOCK_EXIT(&s.psock); } SEND_STRING(&s.psock, (char *)smtp_to); SEND_STRING(&s.psock, s.to); SEND_STRING(&s.psock, (char *)smtp_crnl); if(*s.cc != 0) { SEND_STRING(&s.psock, (char *)smtp_cc); SEND_STRING(&s.psock, s.cc); SEND_STRING(&s.psock, (char *)smtp_crnl); } SEND_STRING(&s.psock, (char *)smtp_from); SEND_STRING(&s.psock, s.from); SEND_STRING(&s.psock, (char *)smtp_crnl); SEND_STRING(&s.psock, (char *)smtp_subject); SEND_STRING(&s.psock, s.subject); SEND_STRING(&s.psock, (char *)smtp_crnl); for(s.line = 0; s.line < s.msgheight; ++s.line) { SEND_STRING(&s.psock, (char *)smtp_crnl); SEND_STRING(&s.psock, &s.msg[s.line * s.msgwidth]); } SEND_STRING(&s.psock, (char *)smtp_crnlperiodcrnl); PSOCK_READTO(&s.psock, ISO_nl); if(s.inputbuffer[0] != ISO_2) { PSOCK_CLOSE(&s.psock); smtp_done(8); PSOCK_EXIT(&s.psock); } SEND_STRING(&s.psock, (char *)smtp_quit); smtp_done(SMTP_ERR_OK); PSOCK_END(&s.psock); } /*---------------------------------------------------------------------------*/ void smtp_appcall(void *state) { if(uip_closed()) { s.connected = 0; return; } if(uip_aborted() || uip_timedout()) { s.connected = 0; smtp_done(1); return; } smtp_thread(); } /*---------------------------------------------------------------------------*/ void smtp_configure(char *lhostname, u16_t *server) { localhostname = lhostname; smtpserver[0] = server[0]; smtpserver[1] = server[1]; } /*---------------------------------------------------------------------------*/ unsigned char smtp_send(char *to, char *cc, char *from, char *subject, char *msg, u8_t msgwidth, u8_t msgheight) { struct uip_conn *conn; conn = tcp_connect(smtpserver, HTONS(25), NULL); if(conn == NULL) { return 0; } s.connected = 1; s.to = to; s.cc = cc; s.from = from; s.subject = subject; s.msg = msg; s.msgwidth = msgwidth; s.msgheight = msgheight; PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer)); return 1; } /*---------------------------------------------------------------------------*/ void smtp_init(void) { s.connected = 0; } /*---------------------------------------------------------------------------*/