]> Pileus Git - ~andy/fetchmail/blob - smtp.c
The great name change.
[~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:      fetchmail
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 "fetchmail.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 fetchmail.h.
31                  
32  *********************************************************************/
33
34 int SMTP_helo(int socket,char *host)
35 {
36   int ok;
37   char buf[SMTPBUFSIZE+1];
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 fetchmail.h.
60                  
61  *********************************************************************/
62 int SMTP_from(int socket, char *from)
63 {
64   char buf[SMTPBUFSIZE+1];  /* 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 fetchmail.h.
85                  
86  *********************************************************************/
87 int SMTP_rcpt(int socket,char *to)
88 {
89   char buf[SMTPBUFSIZE+1];  /* 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 fetchmail.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> (EOM)\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 fetchmail.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)-1)) > 0) {
171     buf[ok] = '\0';
172     if (outlevel == O_VERBOSE)
173         fprintf(stderr, "SMTP< %s", buf);
174     if (argbuf)
175       strcpy(argbuf,buf);
176     if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3')
177       ok = SM_OK;
178     else 
179       ok = SM_ERROR;
180   }
181   else
182     ok = SM_UNRECOVERABLE;
183   return (ok);
184 }
185
186 /*********************************************************************
187   function:      SMTP_ok
188   description:   Returns the statsus of the smtp connection
189   arguments:     
190     socket       TCP/IP socket for connection to SMTP
191   return value:  based on codes in fetchmail.h.
192  *********************************************************************/
193 int SMTP_ok(int socket,char *argbuf)
194 {
195   int  ok;  
196   char buf[SMTPBUFSIZE+1];
197
198   /* I can tell that the SMTP server connection is ok if I can read a
199      status message that starts with "1xx" ,"2xx" or "3xx".
200      Therefore, it can't be ok if there's no data waiting to be read
201      
202      Tried to deal with this with a call to SockDataWaiting, but 
203      it failed badly.
204
205     */
206
207   ok = SMTP_check(socket,argbuf);
208   if (ok == SM_ERROR) /* if we got an error, */
209     {
210       SMTP_rset(socket);
211       ok = SMTP_check(socket,argbuf);  /* how does it look now ? */
212       if (ok == SM_OK)  
213         ok = SM_ERROR;                /* It's just a simple error, for*/
214                                       /*         the current message  */
215       else
216         ok = SM_UNRECOVERABLE;       /* if it still says error, we're */
217                                      /* in bad shape                  */ 
218     }
219   return ok;
220 }
221
222 /*********************************************************************
223   function:      SMTP_Gets
224   description:   Gets  a line from the SMTP connection
225   arguments:     
226     socket       TCP/IP socket for connection to SMTP
227   return value:  number of bytes read.
228  *********************************************************************/
229 int SMTP_Gets(int socket,char *buf,int sz)
230 {
231   return read(socket,buf,sz);
232 }
233