]> Pileus Git - ~andy/fetchmail/blob - smtp.c
SMTP forwarding works.
[~andy/fetchmail] / smtp.c
1 /* Copyright 1996 Eric S. Raymond
2  * All rights reserved.
3  * For license terms, see the file COPYING in this directory.
4  */
5
6 /***********************************************************************
7   module:       smtp.c
8   project:      popclient
9   programmer:   Harry Hochheiser
10   description:  Handling of SMTP connections, and processing of mail 
11                  to be forwarded via SMTP connections.
12
13  ***********************************************************************/
14
15 #include <stdio.h>
16 #include <config.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <string.h>
20 #include "socket.h"
21 #include "popclient.h"
22 #include "smtp.h"
23
24 /*********************************************************************
25   function:      SMTP_helo
26   description:   Send a "HELO" message to the SMTP server.
27
28   arguments:     
29     socket       TCP/IP socket for connection to SMTP
30   return value:  Result of SMTP_OK: based on codes in popclient.h.
31                  
32  *********************************************************************/
33
34 int SMTP_helo(int socket,char *host)
35 {
36   int ok;
37   char buf[SMTPBUFSIZE];
38
39   sprintf(buf,"HELO %s",host);
40   SockPuts(socket, buf);
41   if (outlevel == O_VERBOSE)
42       fprintf(stderr, "SMTP> %s\n", buf);
43   ok = SMTP_ok(socket,buf);
44   return ok;
45 }
46
47
48 /*********************************************************************
49   function:      SMTP_from
50   description:   Send a "MAIL FROM:" message to the SMTP server.
51
52   arguments:     
53     socket       TCP/IP socket for connection to SMTP
54     from         user name/host of originator
55
56     Note: these args are likely to change, as we get fancier about
57     handling the names.
58
59   return value:  Result of SMTP_ok: based on codes in popclient.h.
60                  
61  *********************************************************************/
62 int SMTP_from(int socket, char *from)
63 {
64   char buf[SMTPBUFSIZE];  /* it's as good as size as any... */
65   int ok;
66   SockPrintf(socket, "MAIL FROM: %s\n", from);
67   if (outlevel == O_VERBOSE)
68       fprintf(stderr, "SMTP> MAIL FROM: %s\n", from);
69   ok = SMTP_ok(socket,buf);
70
71   return ok;
72 }
73
74
75 /*********************************************************************
76   function:      SMTP_rcpt
77   description:   Send a "RCPT TO:" message to the SMTP server.
78
79   arguments:     
80     socket       TCP/IP socket for connection to SMTP
81     touser:      user name of recipient
82     tohost:      host name of recipient
83
84   return value:  Result of SMTP_OK: based on codes in popclient.h.
85                  
86  *********************************************************************/
87 int SMTP_rcpt(int socket,char *to)
88 {
89   char buf[SMTPBUFSIZE];  /* it's as good as size as any... */
90   int ok;
91
92   SockPrintf(socket, "RCPT TO: %s\n", to);
93   if (outlevel == O_VERBOSE)
94       fprintf(stderr, "SMTP> RCPT TO: %s\n", to);
95   ok = SMTP_ok(socket,buf);
96   
97   return ok;
98 }
99
100
101 /*********************************************************************
102   function:      SMTP_data
103   description:   Send a "DATA" message to the SMTP server.
104
105   arguments:     
106     socket       TCP/IP socket for connection to SMTP
107
108  *********************************************************************/
109 int SMTP_data(int socket)
110 {
111   int ok;
112
113   SockPrintf(socket,"DATA\n");
114   if (outlevel == O_VERBOSE)
115       fprintf(stderr, "SMTP> DATA\n");
116   ok = SMTP_ok(socket, NULL);
117   
118   return ok;
119 }
120
121 /*********************************************************************
122   function:      SMTP_eom
123   description:   Send a message data termination to the SMTP server.
124
125   arguments:     
126     socket       TCP/IP socket for connection to SMTP
127   return value:  Result of SMTP_OK: based on codes in popclient.h.
128                  
129  *********************************************************************/
130
131 int SMTP_eom(int socket)
132 {
133   int ok;
134
135   SockPuts(socket,".");
136   if (outlevel == O_VERBOSE)
137       fprintf(stderr, "SMTP> .\n");
138   ok = SMTP_ok(socket,NULL);
139   return ok;
140 }
141
142 /*********************************************************************
143   function:      SMTP_rset
144   description:   Send an "RSET" message to the SMTP server.
145
146   arguments:     
147     socket       TCP/IP socket for connection to SMTP
148
149  *********************************************************************/
150 void SMTP_rset(int socket)
151 {
152   SockPrintf(socket,"RSET\n");
153   if (outlevel == O_VERBOSE)
154       fprintf(stderr, "SMTP> RSET\n");
155 }
156
157 /*********************************************************************
158   function:      SMTP_check
159   description:   Returns the status of the smtp connection
160   arguments:     
161     socket       TCP/IP socket for connection to SMTP
162   return value:  based on codes in popclient.h.
163                  Do the dirty work of seeing what the status is..
164  *********************************************************************/
165 static int SMTP_check(int socket,char *argbuf)
166 {
167   int  ok;  
168   char buf[SMTPBUFSIZE];
169   
170   if ((ok = SMTP_Gets(socket, buf, sizeof(buf))) > 0) {
171     if (outlevel == O_VERBOSE)
172     {
173         buf[ok] = '\0';
174         fprintf(stderr, "SMTP< %s", buf);
175     }
176     if (argbuf)
177       strcpy(argbuf,buf);
178     if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3')
179       ok = SM_OK;
180     else 
181       ok = SM_ERROR;
182   }
183   else
184     ok = SM_UNRECOVERABLE;
185   return (ok);
186 }
187
188 /*********************************************************************
189   function:      SMTP_ok
190   description:   Returns the statsus of the smtp connection
191   arguments:     
192     socket       TCP/IP socket for connection to SMTP
193   return value:  based on codes in popclient.h.
194  *********************************************************************/
195 int SMTP_ok(int socket,char *argbuf)
196 {
197   int  ok;  
198   char buf[SMTPBUFSIZE];
199
200   /* I can tell that the SMTP server connection is ok if I can read a
201      status message that starts with "1xx" ,"2xx" or "3xx".
202      Therefore, it can't be ok if there's no data waiting to be read
203      
204      Tried to deal with this with a call to SockDataWaiting, but 
205      it failed badly.
206
207     */
208
209   ok = SMTP_check(socket,argbuf);
210   if (ok == SM_ERROR) /* if we got an error, */
211     {
212       SMTP_rset(socket);
213       ok = SMTP_check(socket,argbuf);  /* how does it look now ? */
214       if (ok == SM_OK)  
215         ok = SM_ERROR;                /* It's just a simple error, for*/
216                                       /*         the current message  */
217       else
218         ok = SM_UNRECOVERABLE;       /* if it still says error, we're */
219                                      /* in bad shape                  */ 
220     }
221   return ok;
222 }
223
224 /*********************************************************************
225   function:      SMTP_Gets
226   description:   Gets  a line from the SMTP connection
227   arguments:     
228     socket       TCP/IP socket for connection to SMTP
229   return value:  number of bytes read.
230  *********************************************************************/
231 int SMTP_Gets(int socket,char *buf,int sz)
232 {
233   return read(socket,buf,sz);
234 }
235