cbcc8f780ae617e35e48fcfd9cbf9284c9c2d722
[claws.git] / src / smtp.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 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 gchar *hostname, gboolean esmtp)
35 {
36         if (esmtp)
37                 return esmtp_ehlo(sock, hostname);
38         else {
39                 sock_printf(sock, "HELO %s\r\n", hostname);
40                 if (verbose)
41                         log_print("SMTP> HELO %s\n", hostname);
42
43                 return smtp_ok(sock);
44         }
45 }
46
47 gint smtp_from(SockInfo *sock, const gchar *from,
48                const gchar *userid, const gchar *passwd,
49                gboolean use_smtp_auth)
50 {
51         gchar buf[MSGBUFSIZE];
52         SMTPAuthType authtype;
53
54         if (use_smtp_auth) {
55                 /* exist AUTH-Type CRAM_MD5 */
56                 if (esmtp_auth_cram_md5(sock) == SM_ERROR) {
57                         /* exist AUTH-Type LOGIN */
58                         if (esmtp_auth_login(sock) == SM_ERROR)
59                                 return SM_ERROR;
60                         else
61                                 authtype = SMTPAUTH_LOGIN;
62                 } else
63                         authtype = SMTPAUTH_CRAM_MD5;
64
65                 if (esmtp_auth(sock, authtype, userid, passwd) != SM_OK)
66                         return SM_AUTHFAIL;
67         }
68
69         if (strchr(from, '<'))
70                 g_snprintf(buf, sizeof(buf), "MAIL FROM: %s", from);
71         else
72                 g_snprintf(buf, sizeof(buf), "MAIL FROM: <%s>", from);
73
74         sock_printf(sock, "%s\r\n", buf);
75         if (verbose)
76                 log_print("SMTP> %s\n", buf);
77
78         return smtp_ok(sock);
79 }
80
81 gint smtp_rcpt(SockInfo *sock, const gchar *to)
82 {
83         gchar buf[MSGBUFSIZE];
84
85         if (strchr(to, '<'))
86                 g_snprintf(buf, sizeof(buf), "RCPT TO: %s", to);
87         else
88                 g_snprintf(buf, sizeof(buf), "RCPT TO: <%s>", to);
89
90         sock_printf(sock, "%s\r\n", buf);
91         if (verbose)
92                 log_print("SMTP> %s\n", buf);
93
94         return smtp_ok(sock);
95 }
96
97 gint smtp_data(SockInfo *sock)
98 {
99         sock_printf(sock, "DATA\r\n");
100         if (verbose)
101                 log_print("SMTP> DATA\n");
102
103         return smtp_ok(sock);
104 }
105
106 gint smtp_rset(SockInfo *sock)
107 {
108         sock_printf(sock, "RSET\r\n");
109         if (verbose)
110                 log_print("SMTP> RSET\n");
111
112         return smtp_ok(sock);
113 }
114
115 gint smtp_quit(SockInfo *sock)
116 {
117         sock_printf(sock, "QUIT\r\n");
118         if (verbose)
119                 log_print("SMTP> QUIT\n");
120
121         return smtp_ok(sock);
122 }
123
124 gint smtp_eom(SockInfo *sock)
125 {
126         sock_printf(sock, ".\r\n");
127         if (verbose)
128                 log_print("SMTP> . (EOM)\n");
129
130         return smtp_ok(sock);
131 }
132
133 gint smtp_ok(SockInfo *sock)
134 {
135         while ((sock_gets(sock, smtp_response, sizeof(smtp_response) - 1))
136                != -1) {
137                 if (strlen(smtp_response) < 4)
138                         return SM_ERROR;
139                 strretchomp(smtp_response);
140
141                 if (verbose)
142                         log_print("SMTP< %s\n", smtp_response);
143
144                 if ((smtp_response[0] == '1' || smtp_response[0] == '2' ||
145                      smtp_response[0] == '3') &&
146                      (smtp_response[3] == ' ' || smtp_response[3] == '\0'))
147                         return SM_OK;
148                 else if (smtp_response[3] != '-')
149                         return SM_ERROR;
150                 else if (smtp_response[0] == '5' &&
151                          smtp_response[1] == '0' &&
152                          (smtp_response[2] == '4' ||
153                           smtp_response[2] == '3' ||
154                           smtp_response[2] == '1'))
155                         return SM_ERROR;
156         }
157
158         return SM_UNRECOVERABLE;
159 }