diff -udprN mutt-1.2.5.orig/Makefile.am mutt-1.2.5.smtp/Makefile.am --- mutt-1.2.5.orig/Makefile.am Thu Jun 22 13:28:16 2000 +++ mutt-1.2.5.smtp/Makefile.am Sat Sep 1 13:33:27 2001 @@ -59,7 +59,8 @@ non_us_sources = pgp.c pgpinvoke.c pgpke imap/imap_ssl.c imap/imap_ssl.h README.SSL EXTRA_mutt_SOURCES = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c \ - gnupgparse.c resize.c dotlock.c pop.c remailer.c remailer.h browser.h + gnupgparse.c resize.c dotlock.c pop.c smtp.c remailer.c \ + remailer.h browser.h EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h attach.h \ buffy.h charset.h copy.h dotlock.h functions.h gen_defs \ diff -udprN mutt-1.2.5.orig/Makefile.in mutt-1.2.5.smtp/Makefile.in --- mutt-1.2.5.orig/Makefile.in Fri Jul 28 20:51:01 2000 +++ mutt-1.2.5.smtp/Makefile.in Sat Sep 1 13:52:32 2001 @@ -142,7 +142,7 @@ INCLUDES = -I$(top_srcdir) -I. $(IMAP_IN non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c gnupgparse.c sha.h sha_locl.h doc/language.txt doc/language50.txt OPS.PGP doc/PGP-Notes.txt OPS.MIX remailer.c remailer.h pgpewrap contrib/pgp2.rc contrib/pgp5.rc contrib/gpg.rc imap/imap_ssl.c imap/imap_ssl.h README.SSL -EXTRA_mutt_SOURCES = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c gnupgparse.c resize.c dotlock.c pop.c remailer.c remailer.h browser.h +EXTRA_mutt_SOURCES = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c gnupgparse.c resize.c dotlock.c pop.c smtp.c remailer.c remailer.h browser.h EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h attach.h buffy.h charset.h copy.h dotlock.h functions.h gen_defs globals.h hash.h history.h init.h keymap.h mailbox.h mapping.h mime.h mutt.h mutt_curses.h mutt_menu.h mutt_regex.h mx.h pager.h parse.h pgp.h protos.h reldate.h rfc1524.h rfc2047.h rfc2231.h rfc822.h sha.h sha_locl.h sort.h mime.types VERSION prepare _regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h lib.h extlib.c pgpewrap pgplib.h Muttrc.head Muttrc makedoc.c stamp-doc-rc README.SSL README.UPGRADE diff -udprN mutt-1.2.5.orig/acconfig.h mutt-1.2.5.smtp/acconfig.h --- mutt-1.2.5.orig/acconfig.h Thu May 18 11:43:22 2000 +++ mutt-1.2.5.smtp/acconfig.h Sat Sep 1 13:34:30 2001 @@ -39,6 +39,9 @@ /* Do you want support for the POP3 protocol? (--enable-pop) */ #undef USE_POP +/* Do you want support for the SMTP protocol? (--enable-smtp) */ +#undef USE_SMTP + /* Do you want support for the IMAP protocol? (--enable-imap) */ #undef USE_IMAP diff -udprN mutt-1.2.5.orig/configure.in mutt-1.2.5.smtp/configure.in --- mutt-1.2.5.orig/configure.in Fri Jul 28 20:50:24 2000 +++ mutt-1.2.5.smtp/configure.in Sat Sep 1 13:35:39 2001 @@ -436,6 +436,15 @@ AC_ARG_ENABLE(pop, [ --enable-pop MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pop.o" fi ]) + +AC_ARG_ENABLE(smtp, [ --enable-smtp Enable SMTP support], +[ if test x$enableval = xyes ; then + AC_DEFINE(USE_SMTP) + AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) + AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) + MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS smtp.o" + fi +]) AC_ARG_ENABLE(imap, [ --enable-imap Enable IMAP support], [ if test x$enableval = xyes ; then diff -udprN mutt-1.2.5.orig/globals.h mutt-1.2.5.smtp/globals.h --- mutt-1.2.5.orig/globals.h Fri Mar 3 11:10:08 2000 +++ mutt-1.2.5.smtp/globals.h Sat Sep 1 13:35:59 2001 @@ -88,6 +88,12 @@ WHERE char *Sendmail; WHERE char *Shell; WHERE char *Signature; WHERE char *SimpleSearch; +#ifdef USE_SMTP +WHERE char *SmtpHost; +WHERE char *SmtpPass; +WHERE char *SmtpServ; +WHERE char *SmtpUser; +#endif WHERE char *Spoolfile; WHERE char *StChars; WHERE char *Status; @@ -133,6 +139,7 @@ WHERE short WriteInc; WHERE short ScoreThresholdDelete; WHERE short ScoreThresholdRead; WHERE short ScoreThresholdFlag; +WHERE short SmtpPort; /* flags for received signals */ WHERE volatile sig_atomic_t SigAlrm INITVAL (0); diff -udprN mutt-1.2.5.orig/init.h mutt-1.2.5.smtp/init.h --- mutt-1.2.5.orig/init.h Tue Jul 18 09:47:08 2000 +++ mutt-1.2.5.smtp/init.h Sat Sep 1 13:42:07 2001 @@ -92,6 +92,9 @@ struct option_t # ifndef USE_POP # define USE_POP # endif +# ifndef USE_SMTP +# define USE_SMTP +# endif # ifndef USE_SSL # define USE_SSL # endif @@ -1812,6 +1815,37 @@ struct option_t MuttVars[] = { ** positives of ``$$quote_regexp'', most notably smileys in the beginning ** of a line */ +#ifdef USE_SMTP + { "smtp_host", DT_STR, R_NONE, UL &SmtpHost, UL 0 }, + /* + ** .pp + ** Your computer present itself as $$smtp_host to your SMTP server. + */ + { "smtp_serv", DT_STR, R_NONE, UL &SmtpServ, UL 0 }, + /* + ** .pp + ** The name or address of your SMTP server. + */ + { "smtp_port", DT_NUM, R_NONE, UL &SmtpPort, 25 }, + /* + ** .pp + ** This variable specifies which port your SMTP server is listening on. + */ + { "smtp_pass", DT_STR, R_NONE, UL &SmtpPass, UL 0 }, + /* + ** .pp + ** Not used. + */ + { "smtp_user", DT_STR, R_NONE, UL &SmtpUser, UL 0 }, + /* + ** .pp + ** Your login name on the SMTP server. Mutt presents you as + ** $$smtp_user@$$smtp_host, unless $$envelope_from is set. + ** This becomes the message's envelope sender. + ** .pp + ** Defaults to your login name on the local system. + */ +#endif { "sort", DT_SORT, R_INDEX|R_RESORT, UL &Sort, SORT_DATE }, /* ** .pp diff -udprN mutt-1.2.5.orig/sendlib.c mutt-1.2.5.smtp/sendlib.c --- mutt-1.2.5.orig/sendlib.c Sat May 20 08:38:59 2000 +++ mutt-1.2.5.smtp/sendlib.c Sat Sep 1 13:25:58 2001 @@ -1651,6 +1651,11 @@ mutt_invoke_sendmail (ADDRESS *from, /* size_t argslen = 0, argsmax = 0; int i; +#ifdef USE_SMTP + if (!Sendmail || mutt_strcmp (Sendmail, "builtin") == 0) + return mutt_invoke_smtp (from, to,cc,bcc, msg); +#endif + ps = s; i = 0; while ((ps = strtok (ps, " "))) diff -udprN mutt-1.2.5.orig/smtp.c mutt-1.2.5.smtp/smtp.c --- mutt-1.2.5.orig/smtp.c Thu Jan 1 01:00:00 1970 +++ mutt-1.2.5.smtp/smtp.c Sat Sep 1 13:25:57 2001 @@ -0,0 +1,726 @@ +/* + * Copyright (C) 1996-8 Michael R. Elkins + * Copyright (C) 1996-9 Brandon Long + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "mutt.h" +#include "mutt_curses.h" +#include "mx.h" +#include "mailbox.h" +#include "globals.h" +#include "sort.h" +#include "smtp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +char *smtp_reply_error[] = +{ + NULL, + "ESTABILISHED", + "HELO", + "EHLO", + "MAIL", + "RCPT", + "DATA", + "RSET", + "NOOP", + "QUIT" +}; + +int smtp_parse_reply ( char *buf ) +{ + enum { SMTPSUCCESS = 1 ,SMTPINTERMEDIATE ,SMTPFAILURE ,SMTPERROR }; + int count1 ,count2; + + char *code[][6][10] = + { { {NULL }, + {NULL }, /*SUCCESS*/ + {NULL }, /*INTERMEDIATE*/ + {NULL }, /*FAILURE*/ + {NULL }, /*ERROR*/ + {NULL ,NULL } + }, + + { {NULL}, + {NULL,"220",NULL}, /*ESTABILISHED*/ + {NULL,"666",NULL}, + {NULL,"421",NULL}, + {NULL,NULL }, + {NULL,NULL } + }, + + { {NULL}, + {NULL,"250",NULL}, /*HELO*/ + {NULL,"666",NULL}, + {NULL,"666",NULL}, + {NULL,"500","501","504","421",NULL}, + {NULL,NULL } + }, + + { {NULL}, + {NULL,"250",NULL}, /*EHLO*/ + {NULL,"666",NULL}, + {NULL,"666",NULL}, + {NULL,"500",NULL}, + {NULL,NULL } + }, + + { {NULL}, + {NULL,"250",NULL}, /*MAIL*/ + {NULL,"666",NULL}, + {NULL,"552","451","452",NULL}, + {NULL,"500","501","421",NULL}, + {NULL,NULL} + }, + + { {NULL}, + {NULL,"250","251",NULL}, /*RCPT*/ + {NULL,"666",NULL }, + {NULL,"550","551","552","553","450","451","452",NULL}, + {NULL,"500","501","503","421",NULL}, + {NULL,NULL} + }, + + { {NULL}, + {NULL,"250","354",NULL}, /*DATA*/ + {NULL,"354",NULL}, + {NULL,"552","554","451","452",NULL}, + {NULL,"500","501","503","421",NULL}, + {NULL,NULL } + }, + + { {NULL}, + {NULL,"250",NULL}, /*RSET*/ + {NULL,"666",NULL}, + {NULL,"666",NULL}, + {NULL,"500","501","504","421",NULL}, + {NULL,NULL} + }, + + { {NULL}, + {NULL,"250",NULL}, /*NOOP*/ + {NULL,"666",NULL}, + {NULL,"666",NULL}, + {NULL,"500","421",NULL}, + {NULL,NULL} + }, + + { {NULL}, + {NULL,"221",NULL}, /*QUIT*/ + {NULL,"666",NULL}, + {NULL,"666",NULL}, + {NULL,"500",NULL}, + {NULL,NULL} + }, + + { {NULL}, + {NULL ,NULL} + } + + }; + + + count1 = 1; + + /* + mutt_message (_("Receiving \"%s\""), buf); + sleep(1); + */ + + while ( code[smtp_data.command][count1][1] ) { + + count2 =1 ; + + while (code[smtp_data.command][count1][count2]) { + + if (!strncmp (buf,code[smtp_data.command][count1][count2],3) ) + goto end; + count2++; + } + + count1++; + } + + + + if (!code[smtp_data.command][count1][1]) { + + if ( (smtp_data.command == SMTP_COMMAND_RSET || + smtp_data.command == SMTP_COMMAND_QUIT) && + (smtp_data.status == SMTP_REPLY_ERROR || + smtp_data.status == SMTP_REPLY_UNKNOW_ERROR ) ) return (-1) ; + + + smtp_data.status = SMTP_REPLY_UNKNOW_ERROR; + + snprintf (smtp_data.reply, sizeof (smtp_data.reply), + "REPLY UNKNOW (%s) %s \r\n", + smtp_reply_error[smtp_data.command] ,buf ); + + return (-1); + + } + +end: + + if ( count1 == SMTPSUCCESS ) return (0); + + else { + + if ( (smtp_data.command == SMTP_COMMAND_RSET || + smtp_data.command == SMTP_COMMAND_QUIT) && + (smtp_data.status == SMTP_REPLY_ERROR || + smtp_data.status == SMTP_REPLY_UNKNOW_ERROR ) ) return (-1) ; + + + + smtp_data.status = SMTP_REPLY_ERROR ; + + snprintf (smtp_data.reply, sizeof (smtp_data.reply), + "REPLY ERROR (%s) %s \r\n", + smtp_reply_error[smtp_data.command] ,buf ); + + return (-1); + } + +} + +static int getLine (int fd, char *s, int len) +{ + char ch; + int bytes = 0; + + while (read (fd, &ch, 1) > 0) + { + *s++ = ch; + bytes++; + if (ch == '\n') + { + *s = 0; + return (bytes); + } + /* make sure not to overwrite the buffer */ + if (bytes == len - 1) + { + *s = 0; + return bytes; + } + } + *s = 0; + return (-1); +} + +static int send_smtp(int fd, char *s, int len) +{ + /* + mutt_message (_("Sending \"%s\""), s); + sleep(1); + */ + return write (fd,s,len); +} + +static int smtp_send_rcpt (ADDRESS *rcpt) +{ + char buf[LONG_STRING] ,tmpbuf[LONG_STRING]; + + while (rcpt) + { + snprintf (tmpbuf, sizeof (tmpbuf), "RCPT TO:<%s>\r\n",rcpt->mailbox); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + return (-1); + } + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_RCPT ; + + if ( smtp_parse_reply ( buf) ) { return -2 ; } + + rcpt = rcpt->next; + } + return 0; +} + +int smtp_send_message (ADDRESS *from, /* the sender */ + ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */ + const char *message) /* file containing message */ +{ + int Flush = 10000 ,count ,total ,dummy, tmpc=0 ; + char buf[LONG_STRING] ,tmpbuf[LONG_STRING] ,tmpf[10003]; + char host[SHORT_STRING] ,user[SHORT_STRING] ,serv[SHORT_STRING]; + char *tmpff ; + char *slang[] = { "|" ,"/" ,"-" ,"\\" ,NULL }; + FILE *in=NULL ; + + struct sockaddr_in sin; +#if SIZEOF_LONG == 4 + long n; +#else + int n; +#endif + struct hostent *he; + + smtp_data.status = smtp_data.state = 0 ; + + if (!SmtpPort ) SmtpPort = 25 ; + + if (!SmtpServ) + { + serv[0] = 0 ; + + if (mutt_get_field(_("SMTP Server: "),serv ,sizeof(serv),0)!=0 || + !serv[0] ) + { + serv[0] = 0 ; + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_ENTER_DATA_ERROR; + return (-1); + } + + } + else strfcpy ( serv ,SmtpServ ,sizeof (serv) ); + + if (!SmtpUser && !(option (OPTENVFROM) && from && !from->next)) + { + user[0] = 0 ; + + if (mutt_get_field(_("SMTP User: "),user ,sizeof(user),0)!=0 || + !user[0] ) + { + user[0] = 0 ; + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_ENTER_DATA_ERROR; + return (-1); + } + + } + else if (SmtpUser) + strfcpy ( user ,SmtpUser ,sizeof (user) ); + + if (!SmtpHost && !Fqdn) + { + host[0] = 0 ; + + if (mutt_get_field(_("SMTP Host: "),host ,sizeof(host),0)!=0 || + !host[0] ) + { + host[0] = 0 ; + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_ENTER_DATA_ERROR; + return (-1); + } + + } + else strfcpy ( host ,SmtpHost ? SmtpHost:Fqdn ,sizeof (host) ); + +/* + if (!SmtpPass) + { + pass[0] = 0 ; + + snprintf (buf ,sizeof(buf) ,_("password for %s@%s: "),user ,conn->server); + + if (mutt_get_field (buf,pass ,sizeof(pass),M_PASS) != 0 || !pass[0] ) + { + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_ENTER_DATA_ERROR; + return (-1); + } + } + else strfcpy (pass ,SmtpPass ,sizeof (pass)); +*/ + + smtp_data.fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP); + + memset ((char *) &sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons (SmtpPort); + + if ((n = inet_addr (NONULL(serv))) == -1) + { + /* Must be a DNS name */ + if ((he = gethostbyname (NONULL(serv))) == NULL) + { + mutt_error (_("Could not find address for host %s."), serv); + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_CONNECTION_ERROR; + return -1; + } + memcpy ((void *)&sin.sin_addr, *(he->h_addr_list), he->h_length); + } + else + memcpy ((void *)&sin.sin_addr, (void *)&n, sizeof(n)); + + mutt_message (_("Connecting to %s"), inet_ntoa (sin.sin_addr)); + + if (connect (smtp_data.fd, (struct sockaddr *) &sin, sizeof (struct sockaddr_in)) == -1) + { + mutt_perror ("connect"); + smtp_data.state = SMTP_DISCONNECTED; + smtp_data.status = SMTP_CONNECTION_ERROR; + return -1; + } + + smtp_data.state = SMTP_CONNECTED; + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + return (-1); + } + + smtp_data.command = SMTP_ESTABILISHED ; + + if ( smtp_parse_reply ( buf) ) {close (smtp_data.fd) ;return (-1) ; } + +/**** HELO **********************************/ + + snprintf (tmpbuf, sizeof (tmpbuf), "HELO %s\r\n", host ); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + return (-1); + } + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_HELO ; + + if ( smtp_parse_reply ( buf) ) { goto QUITSMTP ; } + + +/**** MAIL *********************************/ + + if (option (OPTENVFROM) && from && !from->next) { + snprintf(tmpbuf,sizeof (tmpbuf),"MAIL FROM:<%s>\r\n" ,from->mailbox); + } + else + { + snprintf(tmpbuf,sizeof (tmpbuf),"MAIL FROM:<%s@%s>\r\n" ,user,host); + } + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + return (-1); + } + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_MAIL ; + + if ( smtp_parse_reply ( buf) ) { goto RESETSMTP ; } + +/*** RCPT ***********************************/ + + + dummy = smtp_send_rcpt (to); + if (!dummy) dummy = smtp_send_rcpt (cc); + if (!dummy) dummy = smtp_send_rcpt (bcc); + + if ( dummy == -1 ) return -1; + if ( dummy == -2 ) goto RESETSMTP; + +/**** DATA ***********************************/ + + snprintf (tmpbuf, sizeof (tmpbuf), "DATA\r\n"); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + return (-1); + } + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_DATA ; + + if ( smtp_parse_reply ( buf) ) { goto RESETSMTP ; } + +/***** message ********************************/ + + if ( (in = fopen ( message ,"rb" ) ) == NULL ){ + mutt_error _("Can't Open Message "); + smtp_data.status = SMTP_FATAL ; + return (-1); + } + + total = 0 ;dummy = 0; + +ciclo: + + count = 0 ;tmpff = tmpf ; + + while ( (count < Flush ) && (tmpc = getc (in) ) != EOF ) { + + *tmpff = tmpc; + count++ ;tmpff++ ; + + if (count==1 && tmpc=='.') { + *(tmpff++) = '.'; + count++; + } + + if ( (*(tmpff-1) == '\n') ) { + if ( (*(tmpff-2) != '\r') ) { + *(tmpff-1) = '\r'; + *(tmpff++) = '\n'; + count++; + } + break; + } + } + + total += count ; + + if ( (*(tmpff-1) != '\n') ) { + *(tmpff++) = '\r' ; + *(tmpff++) = '\n' ; + } + *tmpff = '\0' ; + + if ( count && write ( smtp_data.fd ,tmpf, mutt_strlen(tmpf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + if (in) fclose (in); + return (-1); + } + + mutt_message( _("Sending... %c Sent %d" ) ,*slang[dummy],total ); + + dummy++ ; + + dummy %= 4 ; + + if ( tmpc != EOF ) goto ciclo; + + + snprintf (tmpbuf, sizeof (tmpbuf), ".\r\n" ); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + if (in) fclose (in); + return (-1); + } + + if (getLine (smtp_data.fd, buf, sizeof (buf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + if (in) fclose (in); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_DATA ; + + if ( smtp_parse_reply ( buf) ) { goto RESETSMTP; } + +/***** QUIT ************************************/ + +QUITSMTP: + + snprintf (tmpbuf, sizeof (tmpbuf), "QUIT\r\n"); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + if (in) fclose (in); + return (-1); + } + + if (getLine (smtp_data.fd, tmpbuf, sizeof (tmpbuf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + if (tmpbuf[0]) + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + else + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + if (in) fclose (in); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_QUIT ; + + if ( smtp_parse_reply ( tmpbuf) ) { + close (smtp_data.fd) ; + if (in) fclose (in); + return (-1) ; + } + + if ( smtp_data.status == SMTP_REPLY_ERROR || + smtp_data.status == SMTP_REPLY_UNKNOW_ERROR ) { + if (in) fclose (in); + return (-1) ; + } + + else { + close (smtp_data.fd) ; + if (in) fclose (in); + return (0); + } + +/******* RSET **********************************/ + +RESETSMTP: + + snprintf (tmpbuf, sizeof (tmpbuf), "RSET\r\n"); + + if ( send_smtp ( smtp_data.fd ,tmpbuf, mutt_strlen(tmpbuf) ) < 0 ) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_WRITE_ERROR; + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + if (in) fclose (in); + return (-1); + } + + if (getLine (smtp_data.fd, tmpbuf, sizeof (tmpbuf)) < 0) + { + close (smtp_data.fd); + smtp_data.state = SMTP_CONNECTED; + smtp_data.status = SMTP_SOCKET_READ_ERROR; + if (tmpbuf[0]) + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,tmpbuf); + else + snprintf ( smtp_data.error ,sizeof (smtp_data.error) ,buf); + if (in) fclose (in); + return (-1); + } + + smtp_data.command = SMTP_COMMAND_RSET ; + + if ( smtp_parse_reply ( tmpbuf) ) { + close (smtp_data.fd) ; + if (in) fclose (in); + return (-1) ; + } + + else goto QUITSMTP; + +} + + + +int mutt_invoke_smtp (ADDRESS *from, /* the sender */ + ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */ + const char *msg) /* file containing message */ +{ + int i; + + smtp_data.state = 0; + smtp_data.status = 0; + smtp_data.error[0] = '\0'; + smtp_data.reply[0] = '\0'; + + i = smtp_send_message (from, to,cc,bcc, msg); + + unlink (msg); + + if ( i == -1 ) { + if (smtp_data.status == SMTP_ENTER_DATA_ERROR ) + mutt_error _("Data Error") ; + if (smtp_data.status == SMTP_CONNECTION_ERROR ) + mutt_error _("Connection Error") ; + if (smtp_data.status == SMTP_SOCKET_READ_ERROR ) + mutt_error ( _("Read %s"),smtp_data.error) ; + if (smtp_data.status == SMTP_SOCKET_WRITE_ERROR ) + mutt_error ( _("Write %s"),smtp_data.error) ; + if (smtp_data.status == SMTP_REPLY_ERROR || + smtp_data.status == SMTP_REPLY_UNKNOW_ERROR ) + mutt_error ( _("%s"),smtp_data.reply); + } + else if ( i == 0 ) { + mutt_error ( _("OK !!! %s"),smtp_data.reply ); + return (0); + } + + return i; +} diff -udprN mutt-1.2.5.orig/smtp.h mutt-1.2.5.smtp/smtp.h --- mutt-1.2.5.orig/smtp.h Thu Jan 1 01:00:00 1970 +++ mutt-1.2.5.smtp/smtp.h Sat Sep 1 13:43:10 2001 @@ -0,0 +1,75 @@ +/* + * Copyright (C) 1996-8 Michael R. Elkins + * Copyright (C) 1996-9 Brandon Long + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "rfc822.h" + +enum +{ + SMTP_ESTABILISHED=1, + SMTP_COMMAND_HELO, + SMTP_COMMAND_EHLO, + SMTP_COMMAND_MAIL, + SMTP_COMMAND_RCPT, + SMTP_COMMAND_DATA, + SMTP_COMMAND_RSET, + SMTP_COMMAND_NOOP, + SMTP_COMMAND_QUIT +}; + + +enum +{ + /* status */ + SMTP_FATAL =1 , + SMTP_ENTER_DATA_ERROR , + SMTP_CONNECTION_ERROR, + SMTP_SOCKET_READ_ERROR, + SMTP_SOCKET_WRITE_ERROR, + SMTP_REPLY_ERROR, + SMTP_REPLY_UNKNOW_ERROR + +}; + +enum +{ + /* State */ + SMTP_ENTER_DATA = 1 , + SMTP_DISCONNECTED, + SMTP_CONNECTED, + SMTP_AUTHENTICATED, + SMTP_INIZIALIZATED, + SMTP_SELECTED +}; + +struct +{ + /* This data is specific to a CONNECTION to an SMTP server */ + short command; + char reply[LONG_STRING] ; + char error[LONG_STRING]; + short status; + short state; + short check_status; + char delim; + int fd; +} smtp_data; + + +/*extern int smtp_send_message ( ADDRESS * ,char * );*/ +