aboutsummaryrefslogtreecommitdiffstats
path: root/smtp.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>1996-09-11 19:01:53 +0000
committerEric S. Raymond <esr@thyrsus.com>1996-09-11 19:01:53 +0000
commite2035c018f293db615fb4c46984ea033b9e7f50b (patch)
tree81803a87e383b510be5682b634758c35e1ee7cde /smtp.c
parent7e3ec8c9d872b906a803c406f4851f30ff98ee5c (diff)
downloadfetchmail-e2035c018f293db615fb4c46984ea033b9e7f50b.tar.gz
fetchmail-e2035c018f293db615fb4c46984ea033b9e7f50b.tar.bz2
fetchmail-e2035c018f293db615fb4c46984ea033b9e7f50b.zip
Most of the way to SMTP forwarding.
svn path=/trunk/; revision=79
Diffstat (limited to 'smtp.c')
-rw-r--r--smtp.c351
1 files changed, 16 insertions, 335 deletions
diff --git a/smtp.c b/smtp.c
index c46128e1..8d1a4637 100644
--- a/smtp.c
+++ b/smtp.c
@@ -1,20 +1,15 @@
-/* Copyright 1996 Harry Hochheiser
+/* Copyright 1996 Eric S. Raymond
* All rights reserved.
* For license terms, see the file COPYING in this directory.
*/
/***********************************************************************
module: smtp.c
- project: popforward
+ project: popclient
programmer: Harry Hochheiser
description: Handling of SMTP connections, and processing of mail
to be forwarded via SMTP connections.
- 7/30/96. Note: since this file is new from scratch, I'll assume
- that I'm working on a modern (ANSI) compiler, and I'll use
- prototypes.
-
-
***********************************************************************/
#include <config.h>
@@ -22,22 +17,16 @@
#include <unistd.h>
#include <string.h>
#include "socket.h"
-#include "popforward.h"
+#include "popclient.h"
#include "smtp.h"
-static int POP3_parseHeaders(int number, int socket,char **from,int *replFlag);
-static int SMTP_sendMessageHeaders(int mboxfd,struct optrec *option,
- char *from);
-static int SendData(int f,char *buf,int check);
-
-
/*********************************************************************
function: SMTP_helo
description: Send a "HELO" message to the SMTP server.
arguments:
socket TCP/IP socket for connection to SMTP
- return value: Result of SMTP_OK: based on codes in popforward.h.
+ return value: Result of SMTP_OK: based on codes in popclient.h.
*********************************************************************/
@@ -45,6 +34,7 @@ int SMTP_helo(int socket,char *host)
{
int ok;
char buf[SMTPBUFSIZE];
+
sprintf(buf,"HELO %s\r\n",host);
SockPrintf(socket,"%s",buf);
ok = SMTP_ok(socket,buf);
@@ -64,7 +54,7 @@ int SMTP_helo(int socket,char *host)
Note: these args are likely to change, as we get fancier about
handling the names.
- return value: Result of SMTP_ok: based on codes in popforward.h.
+ return value: Result of SMTP_ok: based on codes in popclient.h.
*********************************************************************/
int SMTP_from(int socket,char *fromuser,char *fromhost)
@@ -72,7 +62,7 @@ int SMTP_from(int socket,char *fromuser,char *fromhost)
char buf[SMTPBUFSIZE]; /* it's as good as size as any... */
int ok;
SockPrintf(socket,"MAIL FROM %s@%s\n",fromuser,fromhost);
- ok= SMTP_ok(socket,buf);
+ ok = SMTP_ok(socket,buf);
return ok;
}
@@ -84,13 +74,13 @@ int SMTP_from(int socket,char *fromuser,char *fromhost)
arguments:
socket TCP/IP socket for connection to SMTP
- toser: user name of recipient
- tohost: host name of recipient
+ touser: user name of recipient
+ tohost: host name of recipient
- return value: Result of SMTP_OK: based on codes in popforward.h.
+ return value: Result of SMTP_OK: based on codes in popclient.h.
*********************************************************************/
-int SMTP_rcpt(int socket,char *touser,char *tohost)
+int SMTP_rcpt(int socket,char *touser, char *tohost)
{
char buf[SMTPBUFSIZE]; /* it's as good as size as any... */
int ok;
@@ -109,8 +99,6 @@ int SMTP_rcpt(int socket,char *touser,char *tohost)
arguments:
socket TCP/IP socket for connection to SMTP
- return value: Result of SMTP_OK: based on codes in popforward.h.
-
*********************************************************************/
int SMTP_data(int socket)
{
@@ -120,29 +108,23 @@ int SMTP_data(int socket)
/*********************************************************************
function: SMTP_rset
- description: Send a "DATA" message to the SMTP server.
+ description: Send an "RSET" message to the SMTP server.
arguments:
socket TCP/IP socket for connection to SMTP
- return value: Result of SMTP_OK: based on codes in popforward.h.
-
*********************************************************************/
void SMTP_rset(int socket)
{
SockPrintf(socket,"RSET\n");
}
-
-
/*********************************************************************
function: SMTP_check
description: Returns the status of the smtp connection
- 8/13/96, HSH
arguments:
socket TCP/IP socket for connection to SMTP
-
- return value: based on codes in popforward.h.
+ return value: based on codes in popclient.h.
Do the dirty work of seeing what the status is..
*********************************************************************/
static int SMTP_check(int socket,char *argbuf)
@@ -159,21 +141,16 @@ static int SMTP_check(int socket,char *argbuf)
ok = SM_ERROR;
}
else
- ok= SM_UNRECOVERABLE;
+ ok = SM_UNRECOVERABLE;
return (ok);
}
/*********************************************************************
function: SMTP_ok
description: Returns the statsus of the smtp connection
- 7/31/96, HSH
arguments:
socket TCP/IP socket for connection to SMTP
-
- return value: based on codes in popforward.h.
-
- NOTE: As of 7/31/96 Initial implementation, we're just returning
- a dummy value of SM_OK. Eventually, we should really implement this.
+ return value: based on codes in popclient.h.
*********************************************************************/
int SMTP_ok(int socket,char *argbuf)
{
@@ -198,7 +175,7 @@ int SMTP_ok(int socket,char *argbuf)
ok = SM_ERROR; /* It's just a simple error, for*/
/* the current message */
else
- ok = SM_UNRECOVERABLE; /* if It still says error, we're */
+ ok = SM_UNRECOVERABLE; /* if it still says error, we're */
/* in bad shape */
}
return ok;
@@ -207,308 +184,12 @@ int SMTP_ok(int socket,char *argbuf)
/*********************************************************************
function: SMTP_Gets
description: Gets a line from the SMTP connection
- 7/31/96, HSH
arguments:
socket TCP/IP socket for connection to SMTP
-
return value: number of bytes read.
-
*********************************************************************/
int SMTP_Gets(int socket,char *buf,int sz)
{
return read(socket,buf,sz);
}
-
-/*********************************************************************
- function: POP3_readSMTP
- description: Read the message content as described in RFC 1225.
- arguments:
- number message number.
- socket ... to which the server is connected.
- mboxfd open file descriptor to which the retrieved message will
- be written.
- options added 7/30/96, HSH send in the whole options package...
- server: originating pop server. 7/30/96, HSH
-
- This procedure is the SMTP version of the original POP3_readmsg that
- is found in the original popforward. 8/2/96, HSH
- return value: zero if success else PS_* return code.
- calls: SockGets.
- globals: reads outlevel.
- *********************************************************************/
-
-int POP3_readSMTP(int number,int socket,int mboxfd,struct optrec *options,
- char *server)
-{
- char buf [MSGBUFSIZE];
- char smtpbuf[SMTPBUFSIZE];
- char *bufp;
- char fromBuf[MSGBUFSIZE];
- char *summaryHeaders[3];
- int sumLines =0;
- int needFrom;
- int inheaders;
- int lines,sizeticker;
- int n;
- time_t now;
-
- char *from = NULL;
- int replFlag = 0;
-
-
- /* HSH 8/19/96, Archive file */
-
- int archive = 0;
-
- int msgnum = 0;
-
-
- /* This keeps the retrieved message count for display purposes */
- int ok=0;
-
- /* set up for status message if outlevel allows it */
- /* Get this into log file as well. */
-
-
- ok = POP3_parseHeaders(number,socket,&from,&replFlag);
- if (ok != 0)
- {
- if (from) free(from);
- return(PS_IOERR);
- }
-
- ok = POP3_sendGet(number,options,socket);
- if (ok != 0)
- {
- if (from) free(from);
- return(PS_IOERR);
- }
-
- /* 8/19/96 HSH open the archive file.. */
-
- if ((archive =archGetFile(options,&msgnum)) <= 0)
- {
- if (from) free(from);
- return(PS_IOERR);
- }
-
- /* reads the message content from the server */
- inheaders = 1;
- lines = 0;
- sizeticker = MSGBUFSIZE;
- while (1) {
- if (SockGets(socket,buf,sizeof(buf)) < 0)
- {
- if (from) free(from);
- return(PS_SOCKET);
- }
- bufp = buf;
- if (buf[0] == '\r' || buf[0] == '\n')
- inheaders = 0;
- if (*bufp == '.') {
- bufp++;
- if (*bufp == 0)
- break; /* end of message */
- }
- strcat(bufp,"\n");
-
- /* Check for Unix 'From' header, and add a bogus one if it's not
- present -- only if not using an MDA.
- XXX -- should probably parse real From: header and use its
- address field instead of bogus 'POPmail' string.
- */
-
-
-
- if (lines == 0) {
- if (strlen(bufp) >= strlen("From "))
- needFrom = strncasecmp(bufp,"From ",strlen("From "));
- else
- needFrom = 1;
-
- if ((ok = SMTP_sendMessageHeaders(mboxfd,options,from)) != SM_OK)
- goto smtperr;
-
- if (needFrom) {
- now = time(NULL);
- sprintf(fromBuf,"From POPmail %s",ctime(&now));
- if ((ok =SendData(mboxfd,fromBuf,0)) != SM_OK)
- goto smtperr;
- }
- }
-
- n = write(archive,bufp,strlen(bufp));
-
- /* write this line to the file */
- if ((ok =SendData(mboxfd,bufp,0)) != SM_OK)
- {
- /* Abort the message, so we'll be clear.. */
- SendData(mboxfd,BINMAIL_TERM,0);
- goto smtperr;
- }
-
-
- sizeticker -= strlen(bufp);
- lines++;
- }
-
- if ((ok =SendData(mboxfd,BINMAIL_TERM,0)) !=SM_OK)
- goto smtperr;
-
-
- /* finish up display output */
-
- if (from) free(from);
- if (archive != 0) close(archive);
- return(0);
-
-smtperr:
- if (archive != 0) close(archive);
- SMTP_rset(mboxfd);
- if (from) free(from);
- return(ok);
-}
-
-/******************************************************************
- function: POP3_parseHeaders
- description: Read the headers of the mail message, in order to grab the
- "From" and "reply to" fields, to be used for proper
- mail processing.
- arguments:
- number message number
- socket TCP socket for POP connection
- from character pointer to hold value of message "FROM" field
- replFlag indicates whether or not we've seen a reply flag.
-
- ret. value: non-zero on success, else zero.
- globals: SockGets POP3_OK.
- calls: reads outlevel.
- *****************************************************************/
-int POP3_parseHeaders(number,socket,from,replFlag)
-int number;
-int socket;
-char **from;
-int *replFlag;
-{
-
- int ok;
- char buf[MSGBUFSIZE];
- char *bufp;
- int len;
-
- ok = POP3_sendTOP(number,0,socket);
- if (ok != 0)
- return(ok);
-
- ok = -1; /* we're not ok until we find "FROM: " */
- /* read lines in until we're done.. */
- while (1)
- {
-
- if (SockGets(socket,buf,sizeof(buf)) < 0)
- {
- return(PS_SOCKET);
- }
- bufp = buf;
-
- if (*bufp == '.') {
- bufp++;
- if (*bufp == 0)
- break; /* end of message */
- }
-
- len = strlen(buf);
- if (len < strlen(HEADER_FROM)) /* since From header is shorter than reply-to, it */
- continue; /* can't be either type. */
-
- /* if it starts with "FROM: ", grab from */
- if (strncasecmp(buf,HEADER_FROM,strlen(HEADER_FROM)) == 0)
- {
- bufp = buf + strlen(HEADER_FROM);
- *from = strdup(bufp);
- ok =0;
- }
- if (strncasecmp(buf,HEADER_REPLY,strlen(HEADER_REPLY)) == 0)
- *replFlag = 1;
- }
-
- return(ok);
-}
-
-
-/******************************************************************
- function: SMTP_sendMessageHeaders
- description: Send the headers for the smtp message along to the mailbox..
- arguments:
- number message number
- socket TCP socket for POP connection
- from character pointer to hold value of message "FROM" field
- replFlag indicates whether or not we've seen a reply flag.
-
- ret. value: non-zero on success, else zero.
- globals: SockGets POP3_OK.
- calls: reads outlevel.
- *****************************************************************/
-int SMTP_sendMessageHeaders(int mboxfd,struct optrec *options,char *from)
-{
- char smtpbuf[SMTPBUFSIZE];
- char fromBuf[MSGBUFSIZE];
-
- int ok;
-
- /* 7/30/96, HSH add stuff to print out the SMTP commands. */
- ok = SMTP_ok(mboxfd,smtpbuf);
- if (ok != SM_OK)
- {
- return ok;
- }
- /* mail is from whoever the headers said it was from */
- sprintf(fromBuf,"MAIL FROM: %s\r\n",from);
- if ((ok = SendData(mboxfd,fromBuf,1)) != SM_OK)
- return ok;
-
-/* Now here, add something for the receipt field. 7/30/96,
- HSH */
- sprintf(fromBuf,"RCPT TO: %s@%s\r\n",options->forwarduser,
- options->forwardhost);
- if ((ok=SendData(mboxfd,fromBuf,1)) != SM_OK)
- return ok;
-
- sprintf(fromBuf,"DATA\r\n");
- ok =SendData(mboxfd,fromBuf,1);
- return ok;
-
-}
-
-/******************************************************************
- function: SendData
- description: Write to socket or file, as appropriate for destination
- arguments:
- f socket or file descriptor
- buf buffer to write
- dest options destination.
- check 1 if we should check for SMTP_ok, 0 if not...
- ignored if DEST is not TO_SMTP
- 7/30/96 HSH added
-
- ret. value: 0 if ok, otherwise, non-zero..
- globals: none.
- calls: SockWrite
- *****************************************************************/
-
-static int SendData(int f,char *buf,int check)
-{
- int res;
- char smtpbuf[SMTPBUFSIZE];
- int len = strlen(buf);
-
- res = SockWrite(f,buf,len);
- if (check != 0)
- {
- res = SMTP_ok(f,smtpbuf);
- }
- return res;
-}
-
-