Improve robustness and recoverability

Many extensive changes were made to better handle network errors, while
on some cases it is now possible to recover from previously fatal
failures.
This commit is contained in:
Lefteris Chatzimparmpas 2012-02-11 22:47:08 +01:00
parent dc5b33b60a
commit 18b012c2a2
11 changed files with 416 additions and 381 deletions

View File

@ -45,13 +45,13 @@ function Account._login_user(self)
local r = ifcore.login(self._imap)
if (r == nil) then
return true
elseif (r == true) then
if (r == true) then
self._selected = nil
return true
elseif (r == false) then
error("login failure", 3)
return true
elseif (r == nil) then
error("login request failed", 3)
end
end
@ -90,7 +90,13 @@ function Account.list_all(self, folder, mbox)
return
end
local _, mailboxes, folders = ifcore.list(self._imap, '', folder .. mbox)
local r, mailboxes, folders = ifcore.list(self._imap, '', folder .. mbox)
if (r == false) then
return false
elseif (r == nil) then
error("list request failed", 2)
end
local m = {}
for s in string.gmatch(mailboxes, '%C+') do
@ -131,7 +137,13 @@ function Account.list_subscribed(self, folder, mbox)
return
end
local _, mailboxes, folders = ifcore.lsub(self._imap, '', folder .. mbox)
local r, mailboxes, folders = ifcore.lsub(self._imap, '', folder .. mbox)
if (r == false) then
return false
elseif (r == nil) then
error("lsub request failed", 2)
end
local m = {}
for s in string.gmatch(mailboxes, '%C+') do
@ -158,6 +170,8 @@ function Account.create_mailbox(self, name)
local r = ifcore.create(self._imap, name)
if (r == nil) then error("create request failed", 2) end
if (type(options) == 'table' and options.info == true) then
print(string.format("Created mailbox %s@%s/%s.",
self._imap.username, self._imap.server, name))
@ -175,6 +189,8 @@ function Account.delete_mailbox(self, name)
local r = ifcore.delete(self._imap, name)
if (r == nil) then error("delete request failed", 2) end
if (type(options) == 'table' and options.info == true) then
print(string.format("Deleted mailbox %s@%s/%s.",
self._imap.username, self._imap.server, name))
@ -193,6 +209,8 @@ function Account.rename_mailbox(self, oldname, newname)
local r = ifcore.rename(self._imap, oldname, newname)
if (r == nil) then error("rename request failed", 2) end
if (type(options) == 'table' and options.info == true) then
print(string.format("Renamed mailbox %s@%s/%s to %s@%s/%s.",
self._imap.username, self._imap.server, oldname,
@ -211,6 +229,8 @@ function Account.subscribe_mailbox(self, name)
local r = ifcore.subscribe(self._imap, name)
if (r == nil) then error("subscribe request failed", 2) end
if (type(options) == 'table' and options.info == true) then
print(string.format("Subscribed mailbox %s@%s/%s.",
self._imap.username, self._imap.server, name))
@ -228,6 +248,8 @@ function Account.unsubscribe_mailbox(self, name)
local r = ifcore.unsubscribe(self._imap, name)
if (r == nil) then error("unsubscribe request failed", 2) end
if (type(options) == 'table' and options.info == true) then
print(string.format("Unsubscribed mailbox %s@%s/%s.",
self._imap.username, self._imap.server, name))

View File

@ -38,7 +38,7 @@ get_cert(session *ssn)
mdlen = 0;
if (!(cert = SSL_get_peer_certificate(ssn->ssl)))
if (!(cert = SSL_get_peer_certificate(ssn->sslsocket)))
return -1;
if (!(X509_digest(cert, EVP_md5(), md, &mdlen)))

View File

@ -106,6 +106,9 @@ ifcore_noop(lua_State *lua)
r = request_noop(s, p, u);
lua_pop(lua, 1);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
@ -139,7 +142,7 @@ ifcore_login(lua_State *lua)
lua_pop(lua, 1);
if (r == STATUS_RESPONSE_NONE)
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK ||
@ -173,6 +176,9 @@ ifcore_logout(lua_State *lua)
lua_pop(lua, 1);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -210,6 +216,9 @@ ifcore_status(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
lua_pushnumber(lua, (lua_Number) (exists));
lua_pushnumber(lua, (lua_Number) (recent));
@ -247,6 +256,9 @@ ifcore_select(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -277,6 +289,9 @@ ifcore_close(lua_State *lua)
lua_pop(lua, 1);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -307,6 +322,9 @@ ifcore_expunge(lua_State *lua)
lua_pop(lua, 1);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -345,6 +363,9 @@ ifcore_list(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!mboxs && !folders)
@ -392,6 +413,9 @@ ifcore_lsub(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!mboxs)
@ -482,6 +506,9 @@ ifcore_fetchfast(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!flags || !date || !size)
@ -529,6 +556,9 @@ ifcore_fetchflags(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!flags)
@ -572,6 +602,9 @@ ifcore_fetchdate(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!date)
@ -658,6 +691,9 @@ ifcore_fetchstructure(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!structure)
@ -701,6 +737,9 @@ ifcore_fetchheader(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!header)
@ -744,6 +783,9 @@ ifcore_fetchtext(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!text)
@ -789,6 +831,9 @@ ifcore_fetchfields(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!fields)
@ -834,6 +879,9 @@ ifcore_fetchpart(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
if (!part)
@ -875,6 +923,9 @@ ifcore_store(lua_State *lua)
lua_pop(lua, 4);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -909,6 +960,9 @@ ifcore_copy(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -955,6 +1009,9 @@ ifcore_append(lua_State *lua)
lua_pop(lua, lua_gettop(lua));
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -988,6 +1045,9 @@ ifcore_create(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -1021,6 +1081,9 @@ ifcore_delete(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -1055,6 +1118,9 @@ ifcore_rename(lua_State *lua)
lua_pop(lua, 3);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -1088,6 +1154,9 @@ ifcore_subscribe(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -1121,6 +1190,9 @@ ifcore_unsubscribe(lua_State *lua)
lua_pop(lua, 2);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;
@ -1151,6 +1223,9 @@ ifcore_idle(lua_State *lua)
lua_pop(lua, 1);
if (r == -1)
return 0;
lua_pushboolean(lua, (r == STATUS_RESPONSE_OK));
return 1;

View File

@ -250,10 +250,12 @@ imap_delete(session *ssn, const char *mbox)
* IMAP RENAME: renames mailbox.
*/
int
imap_rename(session *ssn, const char *oldmbox, const char *newmbox)
imap_rename(session *ssn, char *oldmbox, char *newmbox)
{
prepare_command("%04X RENAME \"%s\" \"%s\"\r\n", tag, oldmbox, newmbox);
xfree(oldmbox);
xfree(newmbox);
return send_command(ssn, obuf.data, NULL);
}

View File

@ -49,7 +49,6 @@
#define STATUS_RESPONSE_TRYCREATE 9
#define STATUS_RESPONSE_TIMEOUT 10
/* Initial buffer size for input, output and namespace buffers. */
#define INPUT_BUF 4096
#define OUTPUT_BUF 1024
@ -114,7 +113,7 @@ int imap_select(session *ssn, const char *mbox);
int imap_examine(session *ssn, const char *mbox);
int imap_create(session *ssn, const char *mbox);
int imap_delete(session *ssn, const char *mbox);
int imap_rename(session *ssn, const char *oldmbox, const char *newmbox);
int imap_rename(session *ssn, char *oldmbox, char *newmbox);
int imap_subscribe(session *ssn, const char *mbox);
int imap_unsubscribe(session *ssn, const char *mbox);
int imap_list(session *ssn, const char *refer, const char *name);
@ -184,7 +183,7 @@ LUALIB_API int luaopen_ifre(lua_State *lua);
/* request.c */
int request_noop(const char *server, const char *port, const char *user);
int request_login(const char *server, const char *port, const char *ssl,
int request_login(const char *server, const char *port, const char *protocol,
const char *user, const char *pass);
int request_logout(const char *server, const char *port, const char *user);
int request_status(const char *server, const char *port, const char *user,
@ -266,15 +265,13 @@ void catch_signals(void);
void release_signals(void);
/* socket.c */
int open_connection(session *ssn, const char *server, const char *port,
const char *protocol);
int open_connection(session *ssn);
int close_connection(session *ssn);
ssize_t socket_read(session *ssn, char *buf, size_t len, long timeout,
int timeoutfail);
ssize_t socket_write(session *ssn, const char *buf, size_t len);
#ifndef NO_SSLTLS
int open_secure_connection(session *ssn, const char *server, const char *port,
const char *protocol);
int open_secure_connection(session *ssn);
int close_secure_connection(session *ssn);
ssize_t socket_secure_read(session *ssn, char *buf, size_t len);
ssize_t socket_secure_write(session *ssn, const char *buf, size_t len);

View File

@ -41,11 +41,14 @@ end
function Mailbox._cached_select(self)
if (self._account._selected == nil or
self._account._selected ~= self._mailbox) then
if (ifcore.select(self._account._imap, self._mailbox) == true) then
local r = ifcore.select(self._account._imap, self._mailbox)
if (r == true) then
self._account._selected = self._mailbox
return true
else
elseif (r == false) then
return false
elseif (r == nil) then
error("select request failed", 3)
end
else
return true
@ -54,7 +57,9 @@ end
function Mailbox._cached_close(self)
self._account._selected = nil
return ifcore.close(self._account._imap)
local r = ifcore.close(self._account._imap)
if (r == nil) then error("close request failed", 3) end
return r
end
@ -87,7 +92,13 @@ function Mailbox._send_query(self, criteria, charset)
return {}
end
local _, results = ifcore.search(self._account._imap, query, charset)
local r, results = ifcore.search(self._account._imap, query, charset)
if (r == false) then
return false
elseif (r == nil) then
error("search request failed", 3)
end
if (type(options) == 'table' and options.close == true) then
self._cached_close(self)
@ -134,8 +145,10 @@ function Mailbox._flag_messages(self, mode, flags, messages)
end
r = ifcore.store(self._account._imap, table.concat(m, ',', i, j),
mode, f)
if r == false then
if (r == false) then
break
elseif (r == nil) then
error("store request failed", 3)
end
end
@ -171,8 +184,10 @@ function Mailbox._copy_messages(self, dest, messages)
end
r = ifcore.copy(self._account._imap, table.concat(m, ',', i, j),
dest._mailbox)
if r == false then
if (r == false) then
break
elseif (r == nil) then
error("copy request failed", 3)
end
end
@ -196,6 +211,7 @@ function Mailbox._copy_messages(self, dest, messages)
r = ifcore.append(dest._account._imap, dest._mailbox, mesgs[i],
table.concat(fast[i]['flags'], ' '), fast[i]['date'])
if (r == nil) then error("append request failed", 3) end
end
end
@ -218,8 +234,13 @@ function Mailbox._fetch_fast(self, messages)
local results = {}
for _, m in ipairs(messages) do
local _, flags, date, size = ifcore.fetchfast(self._account._imap,
local r, flags, date, size = ifcore.fetchfast(self._account._imap,
tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchfast request failed", 3)
end
if (flags ~= nil and date ~= nil and size ~= nil ) then
local f = {}
for s in string.gmatch(flags, '%S+') do
@ -254,7 +275,12 @@ function Mailbox._fetch_flags(self, messages)
local results = {}
for _, m in ipairs(messages) do
local _, flags = ifcore.fetchflags(self._account._imap, tostring(m))
local r, flags = ifcore.fetchflags(self._account._imap, tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchflags request failed", 3)
end
if (flags ~= nil) then
local f = {}
for s in string.gmatch(flags, '%S+') do
@ -290,7 +316,12 @@ function Mailbox._fetch_date(self, messages)
self[m]._date) then
results[m] = self[m]._date
else
local _, date = ifcore.fetchdate(self._account._imap, tostring(m))
local r, date = ifcore.fetchdate(self._account._imap, tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchdate request failed", 3)
end
if (date ~= nil) then
results[m] = date
if (type(options) == 'table' and options.cache == true) then
@ -326,7 +357,12 @@ function Mailbox._fetch_size(self, messages)
self[m]._size) then
results[m] = self[m]._size
else
local _, size = ifcore.fetchsize(self._account._imap, tostring(m))
local r, size = ifcore.fetchsize(self._account._imap, tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchsize request failed", 3)
end
if (size ~= nil) then
results[m] = tonumber(size)
if (type(options) == 'table' and options.cache == true) then
@ -362,8 +398,13 @@ function Mailbox._fetch_header(self, messages)
self[m]._header) then
results[m] = self[m]._header
else
local _, header = ifcore.fetchheader(self._account._imap,
local r, header = ifcore.fetchheader(self._account._imap,
tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchheader request failed", 3)
end
if (header ~= nil) then
results[m] = header
if (type(options) == 'table' and options.cache == true) then
@ -399,7 +440,12 @@ function Mailbox._fetch_body(self, messages)
self[m]._body) then
results[m] = self[m]._body
else
local _, body = ifcore.fetchbody(self._account._imap, tostring(m))
local r, body = ifcore.fetchbody(self._account._imap, tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchbody request failed", 3)
end
if (body ~= nil) then
results[m] = body
if (type(options) == 'table' and options.cache == true) then
@ -460,8 +506,13 @@ function Mailbox._fetch_fields(self, fields, messages)
self[m]._fields[f]) then
results[m] = results[m] .. self[m]._fields[f]
else
local _, field = ifcore.fetchfields(self._account._imap,
local r, field = ifcore.fetchfields(self._account._imap,
tostring(m), f)
if (r == false) then
return false
elseif (r == nil) then
error("fetchfields request failed", 3)
end
if (field ~= nil) then
field = string.gsub(field, "\r\n\r\n$", "\n")
results[m] = results[m] .. field
@ -500,8 +551,13 @@ function Mailbox._fetch_structure(self, messages)
self[m]._structure) then
results[m] = self[m]._structure
else
local _, structure = ifcore.fetchstructure(self._account._imap,
local r, structure = ifcore.fetchstructure(self._account._imap,
tostring(m))
if (r == false) then
return false
elseif (r == nil) then
error("fetchstructure request failed", 3)
end
if (structure ~= nil) then
local parsed = _parse_structure({ ['s'] = structure, ['i'] = 1 })
results[m] = parsed
@ -535,8 +591,13 @@ function Mailbox._fetch_parts(self, parts, message)
self[message]._parts[part]) then
results[part] = self[message]._parts[part]
else
local _, bodypart = ifcore.fetchpart(self._account._imap,
local r, bodypart = ifcore.fetchpart(self._account._imap,
tostring(message), part)
if (r == false) then
return false
elseif (r == nil) then
error("fetchparts request failed", 3)
end
if (bodypart ~= nil) then
results[part] = bodypart
self[message]._parts[part] = bodypart
@ -557,8 +618,13 @@ function Mailbox.check_status(self)
return
end
local _, exist, recent, unseen, uidnext = ifcore.status(self._account._imap,
local r, exist, recent, unseen, uidnext = ifcore.status(self._account._imap,
self._mailbox)
if (r == false) then
return false
elseif (r == nil) then
error("status request failed", 2)
end
if (type(options) == 'table' and options.info == true) then
print(string.format("%d messages, %d recent, %d unseen, in %s@%s/%s.",
@ -924,8 +990,11 @@ function Mailbox.append_message(self, message, flags, date)
flags = table.concat(flags, ' ')
end
return ifcore.append(self._account._imap, self._mailbox, message, flags,
r = ifcore.append(self._account._imap, self._mailbox, message, flags,
date)
if (r == nil) then error("append request failed", 2) end
return r
end
@ -1239,7 +1308,10 @@ function Mailbox.enter_idle(self)
return false
end
return ifcore.idle(self._account._imap)
local r = ifcore.idle(self._account._imap)
if (r == nil) then error("idle request failed", 2) end
return r
end
Mailbox._mt.__index = function () end

View File

@ -10,7 +10,24 @@
extern options opts;
int create_mailbox(session *ssn, const char *mbox);
#define TRY(F) \
switch ((F)) { \
case -1: \
if (request_login(s->server, \
s->port, \
s->ssl, \
s->username, \
s->password) != -1) \
F; \
else \
return -1; \
break; \
case STATUS_RESPONSE_BYE: \
close_connection(s); \
session_destroy(s); \
return -1; \
break; \
}
/*
@ -19,21 +36,16 @@ int create_mailbox(session *ssn, const char *mbox);
int
request_noop(const char *server, const char *port, const char *user)
{
int r;
int t, r;
session *s;
if (!(s = session_find(server, port, user)))
return -1;
if ((r = response_generic(s, imap_noop(s))) == -1)
goto fail;
TRY(t = imap_noop(s));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -46,22 +58,26 @@ request_login(const char *server, const char *port, const char *ssl,
const char *user, const char *pass)
{
int r = -1, rg = -1;
session *s;
session *s = NULL;
if ((s = session_find(server, port, user)))
if ((s = session_find(server, port, user)) && s->socket != -1)
return STATUS_RESPONSE_NONE;
s = session_new();
if (!s) {
s = session_new();
s->server = xstrdup(server);
s->port = xstrdup(port);
s->username = xstrdup(user);
s->server = xstrdup(server);
s->port = xstrdup(port);
s->username = xstrdup(user);
s->password = xstrdup(pass);
if (ssl && strncasecmp(ssl, "tls1", 4) &&
strncasecmp(ssl, "ssl3", 4) && strncasecmp(ssl, "ssl2", 4))
ssl = NULL;
if (ssl && (!strncasecmp(ssl, "tls1", 4) ||
!strncasecmp(ssl, "ssl3", 4) ||
strncasecmp(ssl, "ssl2", 4)))
s->ssl = xstrdup(ssl);
}
if (open_connection(s, server, port, ssl) == -1)
if (open_connection(s) == -1)
goto fail;
if ((rg = response_greeting(s)) == -1)
@ -79,8 +95,7 @@ request_login(const char *server, const char *port, const char *ssl,
get_option_boolean("starttls"))
switch (response_generic(s, imap_starttls(s))) {
case STATUS_RESPONSE_OK:
if (open_secure_connection(s, server, port, "tls1")
== -1)
if (open_secure_connection(s) == -1)
goto fail;
if (response_capability(s, imap_capability(s)) == -1)
goto fail;
@ -94,10 +109,9 @@ request_login(const char *server, const char *port, const char *ssl,
if (rg != STATUS_RESPONSE_PREAUTH) {
#ifndef NO_CRAMMD5
if (s->capabilities & CAPABILITY_CRAMMD5 &&
get_option_boolean("crammd5")) {
get_option_boolean("crammd5"))
if ((r = auth_cram_md5(s, user, pass)) == -1)
goto fail;
}
#endif
if (r != STATUS_RESPONSE_OK &&
(r = response_generic(s, imap_login(s, user, pass))) == -1)
@ -116,10 +130,13 @@ request_login(const char *server, const char *port, const char *ssl,
goto fail;
if (s->capabilities & CAPABILITY_NAMESPACE &&
get_option_boolean("namespace")) {
get_option_boolean("namespace"))
if (response_namespace(s, imap_namespace(s)) == -1)
goto fail;
}
if (s->selected)
if (response_select(s, imap_select(s, s->selected)) == -1)
goto fail;
return r;
fail:
@ -169,21 +186,14 @@ request_status(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if (s->protocol == PROTOCOL_IMAP4REV1) {
t = imap_status(s, m, "MESSAGES RECENT UNSEEN UIDNEXT");
if ((r = response_status(s, t, exists, recent, unseen, uidnext)) == -1)
goto fail;
TRY(t = imap_status(s, m, "MESSAGES RECENT UNSEEN UIDNEXT"));
TRY(r = response_status(s, t, exists, recent, unseen, uidnext));
} else {
t = imap_examine(s, m);
if ((r = response_examine(s, t, exists, recent)) == -1)
goto fail;
TRY(t = imap_examine(s, m));
TRY(r = response_examine(s, t, exists, recent));
}
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -194,7 +204,7 @@ int
request_select(const char *server, const char *port, const char *user,
const char *mbox)
{
int r;
int t, r;
session *s;
const char *m;
@ -203,15 +213,16 @@ request_select(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if ((r = response_select(s, imap_select(s, m))) == -1)
goto fail;
TRY(t = imap_select(s, m));
TRY(r = response_select(s, t));
if (r == STATUS_RESPONSE_OK) {
if (s && s->selected)
xfree(s->selected);
s->selected = xstrdup(m);
}
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -221,21 +232,21 @@ fail:
int
request_close(const char *server, const char *port, const char *user)
{
int r;
int t, r;
session *s;
if (!(s = session_find(server, port, user)))
return -1;
if ((r = response_generic(s, imap_close(s))) == -1)
goto fail;
TRY(t = imap_close(s));
TRY(r = response_generic(s, t));
if (r == STATUS_RESPONSE_OK && s->selected) {
xfree(s->selected);
s->selected = NULL;
}
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -245,21 +256,16 @@ fail:
int
request_expunge(const char *server, const char *port, const char *user)
{
int r;
int t, r;
session *s;
if (!(s = session_find(server, port, user)))
return -1;
if ((r = response_generic(s, imap_expunge(s))) == -1)
goto fail;
TRY(t = imap_expunge(s));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -279,16 +285,10 @@ request_list(const char *server, const char *port, const char *user,
n = apply_namespace(name, s->ns.prefix, s->ns.delim);
t = imap_list(s, refer, n);
if ((r = response_list(s, t, mboxs, folders)) == -1)
goto fail;
TRY(t = imap_list(s, refer, n));
TRY(r = response_list(s, t, mboxs, folders));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -308,16 +308,10 @@ request_lsub(const char *server, const char *port, const char *user,
n = apply_namespace(name, s->ns.prefix, s->ns.delim);
t = imap_lsub(s, refer, n);
if ((r = response_list(s, t, mboxs, folders)) == -1)
goto fail;
TRY(t = imap_lsub(s, refer, n));
TRY(r = response_list(s, t, mboxs, folders));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -334,16 +328,10 @@ request_search(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_search(s, charset, criteria);
if ((r = response_search(s, t, mesgs)) == -1)
goto fail;
TRY(t = imap_search(s, charset, criteria));
TRY(r = response_search(s, t, mesgs));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -360,16 +348,10 @@ request_fetchfast(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "FAST");
if ((r = response_fetchfast(s, t, flags, date, size)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "FAST"));
TRY(r = response_fetchfast(s, t, flags, date, size));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -386,16 +368,10 @@ request_fetchflags(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "FLAGS");
if ((r = response_fetchflags(s, t, flags)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "FLAGS"));
TRY(r = response_fetchflags(s, t, flags));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -412,16 +388,10 @@ request_fetchdate(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "INTERNALDATE");
if ((r = response_fetchdate(s, t, date)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "INTERNALDATE"));
TRY(r = response_fetchdate(s, t, date));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
/*
* Fetch the RFC822.SIZE of the messages.
@ -436,16 +406,10 @@ request_fetchsize(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "RFC822.SIZE");
if ((r = response_fetchsize(s, t, size)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "RFC822.SIZE"));
TRY(r = response_fetchsize(s, t, size));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -462,16 +426,10 @@ request_fetchstructure(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "BODYSTRUCTURE");
if ((r = response_fetchstructure(s, t, structure)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "BODYSTRUCTURE"));
TRY(r = response_fetchstructure(s, t, structure));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -488,16 +446,10 @@ request_fetchheader(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "BODY.PEEK[HEADER]");
if ((r = response_fetchbody(s, t, header, len)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "BODY.PEEK[HEADER]"));
TRY(r = response_fetchbody(s, t, header, len));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -514,16 +466,10 @@ request_fetchtext(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, "BODY.PEEK[TEXT]");
if ((r = response_fetchbody(s, t, text, len)) == -1)
goto fail;
TRY(t = imap_fetch(s, mesg, "BODY.PEEK[TEXT]"));
TRY(r = response_fetchbody(s, t, text, len));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -535,29 +481,24 @@ int
request_fetchfields(const char *server, const char *port, const char *user,
const char *mesg, const char *headerfields, char **fields, size_t *len)
{
int t, r, n;
int t, r;
session *s;
char *f;
n = strlen("BODY.PEEK[HEADER.FIELDS ()]") + strlen(headerfields) + 1;
f = (char *)xmalloc(n * sizeof(char));
snprintf(f, n, "%s%s%s", "BODY.PEEK[HEADER.FIELDS (", headerfields, ")]");
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, f);
if ((r = response_fetchbody(s, t, fields, len)) == -1)
goto fail;
{
int n = strlen("BODY.PEEK[HEADER.FIELDS ()]") +
strlen(headerfields) + 1;
char f[n];
xfree(f);
snprintf(f, n, "%s%s%s", "BODY.PEEK[HEADER.FIELDS (",
headerfields, ")]");
TRY(t = imap_fetch(s, mesg, f));
}
TRY(r = response_fetchbody(s, t, fields, len));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -569,29 +510,22 @@ int
request_fetchpart(const char *server, const char *port, const char *user,
const char *mesg, const char *part, char **bodypart, size_t *len)
{
int t, r, n;
int t, r;
session *s;
char *f;
n = strlen("BODY.PEEK[]") + strlen(part) + 1;
f = (char *)xmalloc(n * sizeof(char));
snprintf(f, n, "%s%s%s", "BODY.PEEK[", part, "]");
if (!(s = session_find(server, port, user)))
return -1;
t = imap_fetch(s, mesg, f);
if ((r = response_fetchbody(s, t, bodypart, len)) == -1)
goto fail;
{
int n = strlen("BODY.PEEK[]") + strlen(part) + 1;
char f[n];
xfree(f);
snprintf(f, n, "%s%s%s", "BODY.PEEK[", part, "]");
TRY(t = imap_fetch(s, mesg, f));
}
TRY(r = response_fetchbody(s, t, bodypart, len));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -608,20 +542,15 @@ request_store(const char *server, const char *port, const char *user,
if (!(s = session_find(server, port, user)))
return -1;
t = imap_store(s, mesg, mode, flags);
if ((r = response_generic(s, t)) == -1)
goto fail;
TRY(t = imap_store(s, mesg, mode, flags));
TRY(r = response_generic(s, t));
if (xstrcasestr(flags, "\\Deleted") && get_option_boolean("expunge"))
if (response_generic(s, imap_expunge(s)) == -1)
goto fail;
if (xstrcasestr(flags, "\\Deleted") && get_option_boolean("expunge")) {
TRY(t = imap_expunge(s));
TRY(response_generic(s, t));
}
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -642,24 +571,25 @@ request_copy(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
do {
t = imap_copy(s, mesg, m);
switch (r = response_generic(s, t)) {
TRY(t = imap_copy(s, mesg, m));
TRY(r = response_generic(s, t));
switch (r) {
case STATUS_RESPONSE_TRYCREATE:
if (create_mailbox(s, mbox) == -1)
goto fail;
TRY(t = imap_create(s, m));
TRY(response_generic(s, t));
if (get_option_boolean("subscribe")) {
TRY(t = imap_subscribe(s, m));
TRY(response_generic(s, t));
}
break;
case -1:
goto fail;
return -1;
break;
}
} while (r == STATUS_RESPONSE_TRYCREATE);
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -681,34 +611,30 @@ request_append(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
do {
if ((t = imap_append(s, m, flags, date, mesglen)) == -1)
goto fail;
if ((r = response_continuation(s)) == -1)
goto fail;
TRY(t = imap_append(s, m, flags, date, mesglen));
TRY(r = response_continuation(s));
switch (r) {
case STATUS_RESPONSE_CONTINUE:
if (imap_continuation(s, mesg, mesglen) == -1)
goto fail;
if ((r = response_generic(s, t)) == -1)
goto fail;
TRY(imap_continuation(s, mesg, mesglen));
TRY(r = response_generic(s, t));
break;
case STATUS_RESPONSE_TRYCREATE:
if (create_mailbox(s, mbox) == -1)
goto fail;
TRY(t = imap_create(s, m));
TRY(response_generic(s, t));
if (get_option_boolean("subscribe")) {
TRY(t = imap_subscribe(s, m));
TRY(response_generic(s, t));
}
break;
case -1:
goto fail;
return -1;
break;
}
} while (r == STATUS_RESPONSE_TRYCREATE);
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -719,7 +645,7 @@ int
request_create(const char *server, const char *port, const char *user,
const char *mbox)
{
int r;
int t, r;
session *s;
const char *m;
@ -728,15 +654,10 @@ request_create(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if ((r = response_generic(s, imap_create(s, m))) == -1)
goto fail;
TRY(t = imap_create(s, m));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -747,7 +668,7 @@ int
request_delete(const char *server, const char *port, const char *user,
const char *mbox)
{
int r;
int t, r;
session *s;
const char *m;
@ -756,15 +677,10 @@ request_delete(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if ((r = response_generic(s, imap_delete(s, m))) == -1)
goto fail;
TRY(t = imap_delete(s, m));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -775,7 +691,7 @@ int
request_rename(const char *server, const char *port, const char *user,
const char *oldmbox, const char *newmbox)
{
int r;
int t, r;
session *s;
char *o, *n;
@ -785,20 +701,10 @@ request_rename(const char *server, const char *port, const char *user,
o = xstrdup(apply_namespace(oldmbox, s->ns.prefix, s->ns.delim));
n = xstrdup(apply_namespace(newmbox, s->ns.prefix, s->ns.delim));
r = response_generic(s, imap_rename(s, o, n));
xfree(o);
xfree(n);
if (r == -1)
goto fail;
TRY(t = imap_rename(s, o, n));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -809,7 +715,7 @@ int
request_subscribe(const char *server, const char *port, const char *user,
const char *mbox)
{
int r;
int t, r;
session *s;
const char *m;
@ -818,15 +724,10 @@ request_subscribe(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if ((r = response_generic(s, imap_subscribe(s, m))) == -1)
goto fail;
TRY(t = imap_subscribe(s, m));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
@ -837,7 +738,7 @@ int
request_unsubscribe(const char *server, const char *port, const char *user,
const char *mbox)
{
int r;
int t, r;
session *s;
const char *m;
@ -846,22 +747,17 @@ request_unsubscribe(const char *server, const char *port, const char *user,
m = apply_namespace(mbox, s->ns.prefix, s->ns.delim);
if ((r = response_generic(s, imap_unsubscribe(s, m))) == -1)
goto fail;
TRY(t = imap_unsubscribe(s, m));
TRY(r = response_generic(s, t));
return r;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
int
request_idle(const char *server, const char *port, const char *user)
{
int t, rg, ri;
int t, r, ri;
session *s;
if (!(s = session_find(server, port, user)))
@ -874,49 +770,14 @@ request_idle(const char *server, const char *port, const char *user)
do {
ri = 0;
t = imap_idle(s);
if ((rg = response_continuation(s)) == -1)
goto fail;
if (rg == STATUS_RESPONSE_CONTINUE) {
if ((ri = response_idle(s, t)) == -1)
goto fail;
imap_done(s);
if ((rg = response_generic(s, t)) == -1)
goto fail;
TRY(t = imap_idle(s));
TRY(r = response_continuation(s));
if (r == STATUS_RESPONSE_CONTINUE) {
TRY(ri = response_idle(s, t));
TRY(imap_done(s));
TRY(r = response_generic(s, t));
}
} while (ri == STATUS_RESPONSE_TIMEOUT);
return rg;
fail:
close_connection(s);
session_destroy(s);
return -1;
}
/*
* Auxiliary function to create a mailbox.
*/
int
create_mailbox(session *ssn, const char *mbox)
{
int r;
const char *m;
m = apply_namespace(mbox, ssn->ns.prefix, ssn->ns.delim);
if ((r = response_generic(ssn, imap_create(ssn, m))) == -1)
return -1;
if (get_option_boolean("subscribe"))
if (response_generic(ssn, imap_subscribe(ssn, m)) == -1)
return -1;
return r;
}

View File

@ -224,7 +224,7 @@ response_generic(session *ssn, int tag)
ibuf.len += n;
if (check_bye(ibuf.data))
return -1;
return STATUS_RESPONSE_BYE;
} while ((r = check_tag(ibuf.data, ssn, tag)) == STATUS_RESPONSE_NONE);
if (r == STATUS_RESPONSE_NO &&
@ -252,7 +252,7 @@ response_continuation(session *ssn)
ibuf.len += n;
if (check_bye(ibuf.data))
return -1;
return STATUS_RESPONSE_BYE;
} while (!check_continuation(ibuf.data));
return STATUS_RESPONSE_CONTINUE;
@ -274,7 +274,7 @@ response_greeting(session *ssn)
verbose("S (%d): %s", ssn->socket, ibuf.data);
if (check_bye(ibuf.data))
return -1;
return STATUS_RESPONSE_BYE;
if (check_preauth(ibuf.data))
return STATUS_RESPONSE_PREAUTH;
@ -793,7 +793,7 @@ response_fetchbody(session *ssn, int tag, char **body, size_t *len)
if (offset != 0 && ibuf.len >= offset) {
if (check_bye(ibuf.data + offset))
return -1;
return STATUS_RESPONSE_BYE;
}
} while (ibuf.len < offset || (r = check_tag(ibuf.data + offset, ssn,
tag)) == STATUS_RESPONSE_NONE);
@ -820,6 +820,9 @@ response_idle(session *ssn, int tag)
{
regexp *re;
if (tag == -1)
return -1;
re = &responses[DATA_RESPONSE_IDLE];
do {
@ -838,7 +841,7 @@ response_idle(session *ssn, int tag)
verbose("S (%d): %s", ssn->socket, ibuf.data);
if (check_bye(ibuf.data))
return -1;
return STATUS_RESPONSE_BYE;
} while (regexec(re->preg, ibuf.data, re->nmatch, re->pmatch, 0));

View File

@ -36,47 +36,50 @@ session_init(session *ssn)
ssn->server = NULL;
ssn->port = NULL;
ssn->ssl = NULL;
ssn->username = NULL;
ssn->password = NULL;
ssn->socket = -1;
#ifndef NO_SSLTLS
ssn->ssl = NULL;
ssn->sslsocket = NULL;
#endif
ssn->protocol = PROTOCOL_NONE;
ssn->capabilities = CAPABILITY_NONE;
ssn->ns.prefix = NULL;
ssn->ns.delim = '\0';
ssn->selected = NULL;
}
/*
* Remove session from sessions linked list.
* Remove session from sessions linked list and free allocated memory.
*/
void
session_destroy(session *ssn)
{
if (!ssn)
return;
sessions = list_remove(sessions, ssn);
session_free(ssn);
}
/*
* Free session allocated memory.
*/
void
session_free(session *ssn)
{
if (ssn->server)
xfree(ssn->server);
if (ssn->port)
xfree(ssn->port);
if (ssn->ssl)
xfree(ssn->ssl);
if (ssn->username)
xfree(ssn->username);
if (ssn->password)
xfree(ssn->password);
if (ssn->ns.prefix)
xfree(ssn->ns.prefix);
if (ssn->selected)
xfree(ssn->selected);
xfree(ssn);
ssn = NULL;
}

View File

@ -11,10 +11,12 @@
typedef struct session {
char *server; /* Server hostname. */
char *port; /* Server port. */
char *ssl; /* SSL protocol. */
char *username; /* User name. */
char *password; /* User password. */
int socket; /* Socket. */
#ifndef NO_SSLTLS
SSL *ssl; /* SSL socket. */
SSL *sslsocket; /* SSL socket. */
#endif
unsigned int protocol; /* IMAP protocol. Currently IMAP4rev1 and
* IMAP4 are supported. */
@ -23,6 +25,7 @@ typedef struct session {
char *prefix; /* Namespace prefix. */
char delim; /* Namespace delimiter. */
} ns;
char *selected;
} session;
@ -30,7 +33,6 @@ typedef struct session {
session *session_new(void);
void session_init(session *ssn);
void session_destroy(session *ssn);
void session_free(session *ssn);
session *session_find(const char *server, const char *port, const char *user);

View File

@ -23,14 +23,13 @@
* Connect to mail server.
*/
int
open_connection(session *ssn, const char *server, const char *port,
const char *protocol)
open_connection(session *ssn)
{
struct addrinfo hints, *res, *ressave;
int n, sockfd;
#ifdef NO_SSLTLS
if (protocol) {
if (ssn->ssl) {
error("SSL not supported by this build\n");
return -1;
}
@ -41,7 +40,7 @@ open_connection(session *ssn, const char *server, const char *port,
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
n = getaddrinfo(server, port, &hints, &res);
n = getaddrinfo(ssn->server, ssn->port, &hints, &res);
if (n < 0) {
error("gettaddrinfo; %s\n", gai_strerror(n));
@ -70,15 +69,15 @@ open_connection(session *ssn, const char *server, const char *port,
if (sockfd == -1) {
error("error while initiating connection to %s at port %s\n",
server, port);
ssn->server, ssn->port);
return -1;
}
ssn->socket = sockfd;
#ifndef NO_SSLTLS
if (protocol) {
if (open_secure_connection(ssn, server, port, protocol) == -1) {
if (ssn->ssl) {
if (open_secure_connection(ssn) == -1) {
close_connection(ssn);
return -1;
}
@ -94,8 +93,7 @@ open_connection(session *ssn, const char *server, const char *port,
* Initialize SSL/TLS connection.
*/
int
open_secure_connection(session *ssn, const char *server, const char *port,
const char *protocol)
open_secure_connection(session *ssn)
{
int r, e;
SSL_CTX *ctx;
@ -103,28 +101,28 @@ open_secure_connection(session *ssn, const char *server, const char *port,
method = NULL;
if (!strncasecmp(protocol, "tls1", 4))
method = TLSv1_client_method();
else if (!strncasecmp(protocol, "ssl3", 4) ||
!strncasecmp(protocol, "ssl2", 4))
if (!strncasecmp(ssn->ssl, "ssl3", 4) ||
!strncasecmp(ssn->ssl, "ssl2", 4))
method = SSLv23_client_method();
else
method = TLSv1_client_method();
if (!(ctx = SSL_CTX_new(method)))
goto fail;
if (!(ssn->ssl = SSL_new(ctx)))
if (!(ssn->sslsocket = SSL_new(ctx)))
goto fail;
SSL_set_fd(ssn->ssl, ssn->socket);
SSL_set_fd(ssn->sslsocket, ssn->socket);
for (;;) {
if ((r = SSL_connect(ssn->ssl)) > 0)
if ((r = SSL_connect(ssn->sslsocket)) > 0)
break;
switch (SSL_get_error(ssn->ssl, r)) {
switch (SSL_get_error(ssn->sslsocket, r)) {
case SSL_ERROR_ZERO_RETURN:
error("initiating SSL connection to %s; the "
"connection has been closed cleanly\n", server);
"connection has been closed cleanly\n", ssn->server);
goto fail;
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_ACCEPT:
@ -136,13 +134,13 @@ open_secure_connection(session *ssn, const char *server, const char *port,
e = ERR_get_error();
if (e == 0)
error("initiating SSL connection to %s; EOF "
"in violation of the protocol\n", server);
"in violation of the protocol\n", ssn->server);
else if (e == -1)
error("initiating SSL connection to %s; %s\n",
server, strerror(errno));
ssn->server, strerror(errno));
goto fail;
case SSL_ERROR_SSL:
error("initiating SSL connection to %s; %s\n", server,
error("initiating SSL connection to %s; %s\n", ssn->server,
ERR_error_string(ERR_get_error(), NULL));
goto fail;
default:
@ -157,7 +155,7 @@ open_secure_connection(session *ssn, const char *server, const char *port,
return 0;
fail:
ssn->ssl = NULL;
ssn->sslsocket = NULL;
SSL_CTX_free(ctx);
return -1;
@ -198,10 +196,10 @@ int
close_secure_connection(session *ssn)
{
if (ssn->ssl) {
SSL_shutdown(ssn->ssl);
SSL_free(ssn->ssl);
ssn->ssl = NULL;
if (ssn->sslsocket) {
SSL_shutdown(ssn->sslsocket);
SSL_free(ssn->sslsocket);
ssn->sslsocket = NULL;
}
return 0;
@ -239,8 +237,8 @@ socket_read(session *ssn, char *buf, size_t len, long timeout, int timeoutfail)
FD_SET(ssn->socket, &fds);
#ifndef NO_SSLTLS
if (ssn->ssl) {
if (SSL_pending(ssn->ssl) > 0 ||
if (ssn->sslsocket) {
if (SSL_pending(ssn->sslsocket) > 0 ||
((s = select(ssn->socket + 1, &fds, NULL, NULL, tvp)) > 0 &&
FD_ISSET(ssn->socket, &fds))) {
r = socket_secure_read(ssn, buf, len);
@ -291,12 +289,12 @@ socket_secure_read(session *ssn, char *buf, size_t len)
int r, e;
for (;;) {
r = (ssize_t) SSL_read(ssn->ssl, buf, len);
r = (ssize_t) SSL_read(ssn->sslsocket, buf, len);
if (r > 0)
break;
switch (SSL_get_error(ssn->ssl, r)) {
switch (SSL_get_error(ssn->sslsocket, r)) {
case SSL_ERROR_ZERO_RETURN:
error("reading data; the connection has been closed "
"cleanly\n");
@ -349,7 +347,7 @@ socket_write(session *ssn, const char *buf, size_t len)
if ((s = select(ssn->socket + 1, NULL, &fds, NULL, NULL) > 0 &&
FD_ISSET(ssn->socket, &fds))) {
#ifndef NO_SSLTLS
if (ssn->ssl) {
if (ssn->sslsocket) {
w = socket_secure_write(ssn, buf, len);
if (w <= 0)
@ -402,12 +400,12 @@ socket_secure_write(session *ssn, const char *buf, size_t len)
int w, e;
for (;;) {
w = (ssize_t) SSL_write(ssn->ssl, buf, len);
w = (ssize_t) SSL_write(ssn->sslsocket, buf, len);
if (w > 0)
break;
switch (SSL_get_error(ssn->ssl, w)) {
switch (SSL_get_error(ssn->sslsocket, w)) {
case SSL_ERROR_ZERO_RETURN:
error("writing data; the connection has been closed "
"cleanly\n");