1 /* Copyright 1996 Eric S. Raymond
3 * For license terms, see the file COPYING in this directory.
6 /***********************************************************************
9 programmer: Harry Hochheiser
10 cleaned up and made rfc821 compliant by Cameron MacPherson
11 description: Handling of SMTP connections, and processing of mail
12 to be forwarded via SMTP connections.
14 ***********************************************************************/
18 #include <sys/types.h>
22 #include "fetchmail.h"
25 /*********************************************************************
27 description: Send a "HELO" message to the SMTP server.
30 socket TCP/IP socket for connection to SMTP
31 return value: Result of SMTP_OK: based on codes in fetchmail.h.
33 *********************************************************************/
35 int SMTP_helo(int socket,char *host)
39 SockPrintf(socket,"HELO %s\r\n", host);
40 if (outlevel == O_VERBOSE)
41 fprintf(stderr, "SMTP> HELO %s\n", host);
42 ok = SMTP_ok(socket,NULL);
46 /*********************************************************************
48 description: Send a "MAIL FROM:" message to the SMTP server.
51 socket TCP/IP socket for connection to SMTP
52 from user name/host of originator
54 Note: these args are likely to change, as we get fancier about
57 return value: Result of SMTP_ok: based on codes in fetchmail.h.
59 *********************************************************************/
60 int SMTP_from(int socket, char *from)
64 SockPrintf(socket,"MAIL FROM:<%s>\r\n", from);
65 if (outlevel == O_VERBOSE)
66 fprintf(stderr, "SMTP> MAIL FROM:<%s>\n", from);
67 ok = SMTP_ok(socket,NULL);
71 /*********************************************************************
73 description: Send a "RCPT TO:" message to the SMTP server.
76 socket TCP/IP socket for connection to SMTP
77 touser: user name of recipient
78 tohost: host name of recipient
80 return value: Result of SMTP_OK: based on codes in fetchmail.h.
82 *********************************************************************/
83 int SMTP_rcpt(int socket,char *to)
87 SockPrintf(socket,"RCPT TO:<%s>\r\n", to);
88 if (outlevel == O_VERBOSE)
89 fprintf(stderr, "SMTP> RCPT TO:<%s>\n", to);
90 ok = SMTP_ok(socket,NULL);
94 /*********************************************************************
96 description: Send a "DATA" message to the SMTP server.
99 socket TCP/IP socket for connection to SMTP
101 *********************************************************************/
102 int SMTP_data(int socket)
106 SockPrintf(socket,"DATA\r\n");
107 if (outlevel == O_VERBOSE)
108 fprintf(stderr, "SMTP> DATA\n");
109 ok = SMTP_ok(socket,NULL);
113 /*********************************************************************
115 description: Send a "QUIT" message to the SMTP server.
118 socket TCP/IP socket for connection to SMTP
120 return value: Result of SMTP_OK: based on codes in fetchmail.h.
122 *********************************************************************/
123 int SMTP_quit(int socket)
127 SockPrintf(socket,"QUIT\r\n");
128 if (outlevel == O_VERBOSE)
129 fprintf(stderr, "SMTP> QUIT\n");
130 ok = SMTP_ok(socket,NULL);
134 /*********************************************************************
136 description: Send a message data termination to the SMTP server.
139 socket TCP/IP socket for connection to SMTP
140 return value: Result of SMTP_OK: based on codes in fetchmail.h.
142 *********************************************************************/
144 int SMTP_eom(int socket)
148 SockPrintf(socket,".\r\n");
149 if (outlevel == O_VERBOSE)
150 fprintf(stderr, "SMTP> (EOM)\n");
151 ok = SMTP_ok(socket,NULL);
155 /*********************************************************************
157 description: Send a "RSET" message to the SMTP server.
160 socket TCP/IP socket for connection to SMTP
162 *********************************************************************/
163 void SMTP_rset(int socket)
165 SockPrintf(socket,"RSET\r\n");
166 if (outlevel == O_VERBOSE)
167 fprintf(stderr, "SMTP> RSET\n");
170 /*********************************************************************
172 description: Returns the status of the smtp connection
174 socket TCP/IP socket for connection to SMTP
175 return value: based on codes in fetchmail.h.
176 Do the dirty work of seeing what the status is..
177 *********************************************************************/
178 static int SMTP_check(int socket,char *argbuf)
181 char buf[SMTPBUFSIZE];
183 if ((ok = SMTP_Gets(socket, buf, sizeof(buf)-1)) > 0) {
185 if (outlevel == O_VERBOSE)
186 fprintf(stderr, "SMTP< %s", buf);
189 if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3')
195 ok = SM_UNRECOVERABLE;
199 /*********************************************************************
201 description: Returns the statsus of the smtp connection
203 socket TCP/IP socket for connection to SMTP
204 return value: based on codes in fetchmail.h.
205 *********************************************************************/
206 int SMTP_ok(int socket,char *argbuf)
210 /* I can tell that the SMTP server connection is ok if I can read a
211 status message that starts with "1xx" ,"2xx" or "3xx".
212 Therefore, it can't be ok if there's no data waiting to be read
214 Tried to deal with this with a call to SockDataWaiting, but
219 ok = SMTP_check(socket,argbuf);
220 if (ok == SM_ERROR) /* if we got an error, */
223 ok = SMTP_check(socket,argbuf); /* how does it look now ? */
225 ok = SM_ERROR; /* It's just a simple error, for*/
226 /* the current message */
228 ok = SM_UNRECOVERABLE; /* if it still says error, we're */
234 /*********************************************************************
236 description: Gets a line from the SMTP connection
238 socket TCP/IP socket for connection to SMTP
239 return value: number of bytes read.
240 *********************************************************************/
241 int SMTP_Gets(int socket,char *buf,int sz)
243 return read(socket,buf,sz);