]> Pileus Git - ~andy/fetchmail/blob - smtp.c
475b847af6deaceaf678f15a0ef6f70a8424ec08
[~andy/fetchmail] / smtp.c
1 /*
2  * smtp.c -- code for speaking SMTP to a listener port
3  *
4  * Concept due to Harry Hochheiser.  Implementation by ESR.  Cleanup and
5  * strict RFC821 compliance by Cameron MacPherson.
6  *
7  * Copyright 1996 Eric S. Raymond
8  * All rights reserved.
9  * For license terms, see the file COPYING in this directory.
10  */
11
12 #include <stdio.h>
13 #include <config.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <string.h>
17 #include "socket.h"
18 #include "fetchmail.h"
19 #include "smtp.h"
20
21 int SMTP_helo(FILE *sockfp,char *host)
22 /* send a "HELO" message to the SMTP listener */
23 {
24   int ok;
25
26   SockPrintf(sockfp,"HELO %s\r\n", host);
27   if (outlevel == O_VERBOSE)
28       fprintf(stderr, "SMTP> HELO %s\n", host);
29   ok = SMTP_ok(sockfp,NULL);
30   return ok;
31 }
32
33 int SMTP_from(FILE *sockfp, char *from)
34 /* send a "MAIL FROM:" message to the SMTP listener */
35 {
36   int ok;
37
38   SockPrintf(sockfp,"MAIL FROM:<%s>\r\n", from);
39   if (outlevel == O_VERBOSE)
40       fprintf(stderr, "SMTP> MAIL FROM:<%s>\n", from);
41   ok = SMTP_ok(sockfp,NULL);
42   return ok;
43 }
44
45 int SMTP_rcpt(FILE *sockfp, char *to)
46 /* send a "RCPT TO:" message to the SMTP listener */
47 {
48   int ok;
49
50   SockPrintf(sockfp,"RCPT TO:<%s>\r\n", to);
51   if (outlevel == O_VERBOSE)
52       fprintf(stderr, "SMTP> RCPT TO:<%s>\n", to);
53   ok = SMTP_ok(sockfp,NULL);
54   return ok;
55 }
56
57 int SMTP_data(FILE *sockfp)
58 /* send a "DATA" message to the SMTP listener */
59 {
60   int ok;
61
62   SockPrintf(sockfp,"DATA\r\n");
63   if (outlevel == O_VERBOSE)
64       fprintf(stderr, "SMTP> DATA\n");
65   ok = SMTP_ok(sockfp,NULL);
66   return ok;
67 }
68
69 int SMTP_quit(FILE *sockfp)
70 /* send a "QUIT" message to the SMTP listener */
71 {
72   int ok;
73
74   SockPrintf(sockfp,"QUIT\r\n");
75   if (outlevel == O_VERBOSE)
76       fprintf(stderr, "SMTP> QUIT\n");
77   ok = SMTP_ok(sockfp,NULL);
78   return ok;
79 }
80
81 int SMTP_eom(FILE *sockfp)
82 /* send a message data terminator to the SMTP listener */
83 {
84   int ok;
85
86   SockPrintf(sockfp,".\r\n");
87   if (outlevel == O_VERBOSE)
88       fprintf(stderr, "SMTP>. (EOM)\n");
89   ok = SMTP_ok(sockfp,NULL);
90   return ok;
91 }
92
93 void SMTP_rset(FILE *sockfp)
94 /* send a "RSET" message to the SMTP listener */
95 {
96   SockPrintf(sockfp,"RSET\r\n");
97   if (outlevel == O_VERBOSE)
98       fprintf(stderr, "SMTP> RSET\n");
99 }
100
101 static int SMTP_check(FILE *sockfp,char *argbuf)
102 /* returns status of SMTP connection */
103 {
104   int  ok;  
105   char buf[SMTPBUFSIZE];
106   
107   if ((ok = SockGets(buf, sizeof(buf)-1, sockfp)) > 0) {
108     buf[ok] = '\0';
109     if (outlevel == O_VERBOSE)
110         fprintf(stderr, "SMTP< %s", buf);
111     if (argbuf)
112       strcpy(argbuf,buf);
113     if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3')
114       ok = SM_OK;
115     else 
116       ok = SM_ERROR;
117   }
118   else
119     ok = SM_UNRECOVERABLE;
120   return (ok);
121 }
122
123 int SMTP_ok(FILE *sockfp,char *argbuf)
124 /* accepts SMTP response, returns status of SMTP connection */
125 {
126   int  ok;  
127
128   /* I can tell that the SMTP server connection is ok if I can read a
129      status message that starts with "1xx" ,"2xx" or "3xx".
130      Therefore, it can't be ok if there's no data waiting to be read
131      
132      Tried to deal with this with a call to SockDataWaiting, but 
133      it failed badly.
134
135     */
136
137   ok = SMTP_check(sockfp,argbuf);
138   if (ok == SM_ERROR) /* if we got an error, */
139     {
140       SMTP_rset(sockfp);
141       ok = SMTP_check(sockfp,argbuf);  /* how does it look now ? */
142       if (ok == SM_OK)  
143         ok = SM_ERROR;                /* It's just a simple error, for*/
144                                       /*         the current message  */
145       else
146         ok = SM_UNRECOVERABLE;       /* if it still says error, we're */
147                                      /* in bad shape                  */ 
148     }
149   return ok;
150 }
151
152 /* smtp.c ends here */