ec99637784792a043c4ae4f3b4951911f415f431
[claws.git] / src / smtp.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999,2000 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <glib.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "smtp.h"
25 #include "esmtp.h"
26 #include "socket.h"
27 #include "utils.h"
28
29 #define MSGBUFSIZE      8192
30
31 static gint verbose = 1;
32 static gchar smtp_response[MSGBUFSIZE];
33
34 gint smtp_helo(SockInfo *sock, const char *hostname, gboolean use_smtp_auth)
35 {
36         if (use_smtp_auth) {
37                 sock_printf(sock, "EHLO %s\r\n", hostname);
38                 if (verbose)
39                         log_print("ESMTP> EHLO %s\n", hostname);
40
41                 return esmtp_ok(sock);
42         } else {
43                 sock_printf(sock, "HELO %s\r\n", hostname);
44                 if (verbose)
45                         log_print("SMTP> HELO %s\n", hostname);
46
47                 return smtp_ok(sock);
48         }
49 }
50
51 gint smtp_from(SockInfo *sock, const gchar *from,
52                const gchar *userid, const gchar *passwd,
53                gboolean use_smtp_auth)
54 {
55         gchar buf[MSGBUFSIZE];
56         SMTPAuthType authtype;
57
58         if (use_smtp_auth) {
59                 /* exist AUTH-Type CRAM_MD5 */
60                 if (esmtp_auth_cram_md5(sock) == SM_ERROR) {
61                         /* exist AUTH-Type LOGIN */
62                         if (esmtp_auth_login(sock) == SM_ERROR)
63                                 return SM_ERROR;
64                         else
65                                 authtype = SMTPAUTH_LOGIN;
66                 } else
67                         authtype = SMTPAUTH_CRAM_MD5;
68
69                 esmtp_auth(sock, authtype, userid, passwd, use_smtp_auth);
70         }
71
72         if (strchr(from, '<'))
73                 g_snprintf(buf, sizeof(buf), "MAIL FROM: %s", from);
74         else
75                 g_snprintf(buf, sizeof(buf), "MAIL FROM: <%s>", from);
76
77         sock_printf(sock, "%s\r\n", buf);
78         if (verbose)
79                 log_print("SMTP> %s\n", buf);
80
81         return smtp_ok(sock);
82 }
83
84 gint smtp_rcpt(SockInfo *sock, const gchar *to)
85 {
86         gchar buf[MSGBUFSIZE];
87
88         if (strchr(to, '<'))
89                 g_snprintf(buf, sizeof(buf), "RCPT TO: %s", to);
90         else
91                 g_snprintf(buf, sizeof(buf), "RCPT TO: <%s>", to);
92
93         sock_printf(sock, "%s\r\n", buf);
94         if (verbose)
95                 log_print("SMTP> %s\n", buf);
96
97         return smtp_ok(sock);
98 }
99
100 gint smtp_data(SockInfo *sock)
101 {
102         sock_printf(sock, "DATA\r\n");
103         if (verbose)
104                 log_print("SMTP> DATA\n");
105
106         return smtp_ok(sock);
107 }
108
109 gint smtp_rset(SockInfo *sock)
110 {
111         sock_printf(sock, "RSET\r\n");
112         if (verbose)
113                 log_print("SMTP> RSET\n");
114
115         return smtp_ok(sock);
116 }
117
118 gint smtp_quit(SockInfo *sock)
119 {
120         sock_printf(sock, "QUIT\r\n");
121         if (verbose)
122                 log_print("SMTP> QUIT\n");
123
124         return smtp_ok(sock);
125 }
126
127 gint smtp_eom(SockInfo *sock)
128 {
129         sock_printf(sock, ".\r\n");
130         if (verbose)
131                 log_print("SMTP> . (EOM)\n");
132
133         return smtp_ok(sock);
134 }
135
136 gint smtp_ok(SockInfo *sock)
137 {
138         while ((sock_read(sock, smtp_response, sizeof(smtp_response) - 1))
139                != 1) {
140                 if (strlen(smtp_response) < 4)
141                         return SM_ERROR;
142                 strretchomp(smtp_response);
143
144                 if (verbose)
145                         log_print("SMTP< %s\n", smtp_response);
146
147                 if ((smtp_response[0] == '1' || smtp_response[0] == '2' ||
148                      smtp_response[0] == '3') && smtp_response[3] == ' ')
149                         return SM_OK;
150                 else if (smtp_response[3] != '-')
151                         return SM_ERROR;
152                         else if (smtp_response[0] == '5' && smtp_response[1] == '0' &&
153                                  (smtp_response[3] == '4' || smtp_response[3] == '3' || smtp_response[3] == '1'))
154                                 return SM_ERROR;
155         }
156
157         return SM_UNRECOVERABLE;
158 }