2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 typedef struct private_smtp_t private_smtp_t
;
26 * Private data of an smtp_t object.
28 struct private_smtp_t
{
31 * Public smtp_t interface.
36 * file stream to SMTP server
42 * Read the response code from an SMTP server
44 static int read_response(private_smtp_t
*this)
51 if (!fgets(buf
, sizeof(buf
), this->f
))
55 res
= strtol(buf
, &end
, 10);
73 * write a SMTP command to the server, read response code
75 static int write_cmd(private_smtp_t
*this, char *fmt
, ...)
81 vsnprintf(buf
, sizeof(buf
), fmt
, args
);
84 if (fprintf(this->f
, "%s\n", buf
) < 1)
86 DBG1("sending SMTP command failed");
89 return read_response(this);
92 METHOD(smtp_t
, send_mail
, bool,
93 private_smtp_t
*this, char *from
, char *to
, char *subject
, char *fmt
, ...)
97 if (write_cmd(this, "MAIL FROM:<%s>", from
) != 250)
99 DBG1("SMTP MAIL FROM failed");
102 if (write_cmd(this, "RCPT TO:<%s>", to
) != 250)
104 DBG1("SMTP RCPT TO failed");
107 if (write_cmd(this, "DATA") != 354)
109 DBG1("SMTP DATA failed");
113 fprintf(this->f
, "From: %s\n", from
);
114 fprintf(this->f
, "To: %s\n", to
);
115 fprintf(this->f
, "Subject: %s\n", subject
);
116 fprintf(this->f
, "\n");
118 vfprintf(this->f
, fmt
, args
);
120 fprintf(this->f
, "\n.\n");
121 return read_response(this) == 250;
125 METHOD(smtp_t
, destroy
, void,
126 private_smtp_t
*this)
128 write_cmd(this, "QUIT");
136 smtp_t
*smtp_create()
138 private_smtp_t
*this;
139 struct sockaddr_in addr
;
144 .send_mail
= _send_mail
,
149 s
= socket(AF_INET
, SOCK_STREAM
, 0);
152 DBG1("opening SMTP socket failed: %s", strerror(errno
));
156 addr
.sin_family
= AF_INET
;
157 addr
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
158 addr
.sin_port
= htons(25);
159 if (connect(s
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0)
161 DBG1("connecting to SMTP server failed: %s", strerror(errno
));
166 this->f
= fdopen(s
, "a+");
169 DBG1("opening stream to SMTP server failed: %s", strerror(errno
));
174 if (read_response(this) != 220 ||
175 write_cmd(this, "EHLO localhost") != 250)
177 DBG1("SMTP EHLO failed");
182 return &this->public;