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