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