X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fcommon%2Fsession.c;h=959c7a28e6785e6956dd765c893df4476fe371ad;hp=d4c5dbcf8e81dfcf12fd20b90b52d67193d29d05;hb=8f81dc6211b3c5bf353e62d69d93317c59ce8d24;hpb=094bee48a0efd097739a917542f830425c6f5abe diff --git a/src/common/session.c b/src/common/session.c index d4c5dbcf8..959c7a28e 100644 --- a/src/common/session.c +++ b/src/common/session.c @@ -1,10 +1,10 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2005 Hiroyuki Yamamoto + * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -13,17 +13,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program. If not, see . + * */ #ifdef HAVE_CONFIG_H # include "config.h" +#include "claws-features.h" #endif #include "defs.h" #include +#include #include #include @@ -34,6 +36,7 @@ #include "session.h" #include "utils.h" +#include "log.h" static gint session_connect_cb (SockInfo *sock, gpointer data); @@ -58,13 +61,13 @@ static gboolean session_write_data_cb (SockInfo *source, gpointer data); -void session_init(Session *session) +void session_init(Session *session, const void *prefs_account, gboolean is_smtp) { session->type = SESSION_UNKNOWN; session->sock = NULL; session->server = NULL; session->port = 0; -#if USE_OPENSSL +#ifdef USE_GNUTLS session->ssl_type = SSL_NONE; #endif session->nonblocking = TRUE; @@ -95,6 +98,10 @@ void session_init(Session *session) session->timeout_interval = 0; session->data = NULL; + session->account = prefs_account; + session->is_smtp = is_smtp; + + session->ping_tag = -1; } /*! @@ -137,6 +144,7 @@ gint session_connect(Session *session, const gchar *server, gushort port) session_close(session); return -1; } + sock->is_smtp = session->is_smtp; return session_connect_cb(sock, session); #endif @@ -155,18 +163,29 @@ static gint session_connect_cb(SockInfo *sock, gpointer data) } session->sock = sock; + sock->account = session->account; + sock->is_smtp = session->is_smtp; + sock->ssl_cert_auto_accept = session->ssl_cert_auto_accept; + +#ifdef USE_GNUTLS + sock->gnutls_priority = session->gnutls_priority; -#if USE_OPENSSL if (session->ssl_type == SSL_TUNNEL) { sock_set_nonblocking_mode(sock, FALSE); if (!ssl_init_socket(sock)) { g_warning("can't initialize SSL."); + log_error(LOG_PROTOCOL, _("SSL handshake failed\n")); session->state = SESSION_ERROR; return -1; } } #endif + /* we could have gotten a timeout while waiting for user input in + * an SSL certificate dialog */ + if (session->state == SESSION_TIMEOUT) + return -1; + sock_set_nonblocking_mode(sock, session->nonblocking); debug_print("session (%p): connected\n", session); @@ -199,8 +218,10 @@ gint session_disconnect(Session *session) */ void session_destroy(Session *session) { - g_return_if_fail(session != NULL); - g_return_if_fail(session->destroy != NULL); + cm_return_if_fail(session != NULL); + cm_return_if_fail(session->destroy != NULL); + + session_register_ping(session, NULL); session_close(session); session->destroy(session); @@ -209,19 +230,28 @@ void session_destroy(Session *session) g_byte_array_free(session->read_data_buf, TRUE); g_free(session->read_data_terminator); g_free(session->write_buf); +#ifdef USE_GNUTLS + g_free(session->gnutls_priority); +#endif debug_print("session (%p): destroyed\n", session); g_free(session); } -gboolean session_is_connected(Session *session) +gboolean session_is_running(Session *session) { return (session->state == SESSION_READY || session->state == SESSION_SEND || session->state == SESSION_RECV); } +gboolean session_is_connected(Session *session) +{ + return (session->state == SESSION_SEND || + session->state == SESSION_RECV); +} + void session_set_access_time(Session *session) { session->last_access_time = time(NULL); @@ -233,10 +263,14 @@ void session_set_timeout(Session *session, guint interval) g_source_remove(session->timeout_tag); session->timeout_interval = interval; - if (interval > 0) - session->timeout_tag = - g_timeout_add(interval, session_timeout_cb, session); - else + if (interval > 0) { + if (interval % 1000 == 0) + session->timeout_tag = + g_timeout_add_seconds(interval/1000, session_timeout_cb, session); + else + session->timeout_tag = + g_timeout_add(interval, session_timeout_cb, session); + } else session->timeout_tag = 0; } @@ -305,7 +339,7 @@ void session_set_send_data_notify(Session *session, SendDataNotify notify_func, */ static gint session_close(Session *session) { - g_return_val_if_fail(session != NULL, -1); + cm_return_val_if_fail(session != NULL, -1); #ifdef G_OS_UNIX if (session->conn_id > 0) { @@ -332,20 +366,22 @@ static gint session_close(Session *session) return 0; } -#if USE_OPENSSL +#ifdef USE_GNUTLS gint session_start_tls(Session *session) { gboolean nb_mode; nb_mode = sock_is_nonblocking_mode(session->sock); + session->sock->ssl_cert_auto_accept = session->ssl_cert_auto_accept; + if (nb_mode) sock_set_nonblocking_mode(session->sock, FALSE); if (!ssl_init_socket_with_method(session->sock, SSL_METHOD_TLSv1)) { - g_warning("can't start TLS session.\n"); + g_warning("couldn't start TLS session.\n"); if (nb_mode) - sock_set_nonblocking_mode(session->sock, TRUE); + sock_set_nonblocking_mode(session->sock, session->nonblocking); return -1; } @@ -360,9 +396,9 @@ gint session_send_msg(Session *session, SessionMsgType type, const gchar *msg) { gboolean ret; - g_return_val_if_fail(session->write_buf == NULL, -1); - g_return_val_if_fail(msg != NULL, -1); - g_return_val_if_fail(msg[0] != '\0', -1); + cm_return_val_if_fail(session->write_buf == NULL, -1); + cm_return_val_if_fail(msg != NULL, -1); + cm_return_val_if_fail(msg[0] != '\0', -1); session->state = SESSION_SEND; session->write_buf = g_strconcat(msg, "\r\n", NULL); @@ -382,7 +418,7 @@ gint session_send_msg(Session *session, SessionMsgType type, const gchar *msg) gint session_recv_msg(Session *session) { - g_return_val_if_fail(session->read_msg_buf->len == 0, -1); + cm_return_val_if_fail(session->read_msg_buf->len == 0, -1); session->state = SESSION_RECV; @@ -423,9 +459,9 @@ gint session_send_data(Session *session, const guchar *data, guint size) { gboolean ret; - g_return_val_if_fail(session->write_data == NULL, -1); - g_return_val_if_fail(data != NULL, -1); - g_return_val_if_fail(size != 0, -1); + cm_return_val_if_fail(session->write_data == NULL, -1); + cm_return_val_if_fail(data != NULL, -1); + cm_return_val_if_fail(size != 0, -1); session->state = SESSION_SEND; @@ -448,7 +484,7 @@ gint session_send_data(Session *session, const guchar *data, guint size) gint session_recv_data(Session *session, guint size, const gchar *terminator) { - g_return_val_if_fail(session->read_data_buf->len == 0, -1); + cm_return_val_if_fail(session->read_data_buf->len == 0, -1); session->state = SESSION_RECV; @@ -489,14 +525,15 @@ static gboolean session_read_msg_cb(SockInfo *source, GIOCondition condition, gchar *msg; gint ret; - g_return_val_if_fail(condition == G_IO_IN, FALSE); + cm_return_val_if_fail(condition == G_IO_IN, FALSE); session_set_timeout(session, session->timeout_interval); if (session->read_buf_len == 0) { - gint read_len; + gint read_len = -1; - read_len = sock_read(session->sock, session->read_buf, + if (session->sock) + read_len = sock_read(session->sock, session->read_buf, SESSION_BUFFSIZE - 1); if (read_len == -1 && session->state == SESSION_DISCONNECTED) { @@ -584,7 +621,7 @@ static gboolean session_read_data_cb(SockInfo *source, GIOCondition condition, guint data_len; gint ret; - g_return_val_if_fail(condition == G_IO_IN, FALSE); + cm_return_val_if_fail(condition == G_IO_IN, FALSE); session_set_timeout(session, session->timeout_interval); @@ -684,9 +721,9 @@ static gint session_write_buf(Session *session) gint write_len; gint to_write_len; - g_return_val_if_fail(session->write_buf != NULL, -1); - g_return_val_if_fail(session->write_buf_p != NULL, -1); - g_return_val_if_fail(session->write_buf_len > 0, -1); + cm_return_val_if_fail(session->write_buf != NULL, -1); + cm_return_val_if_fail(session->write_buf_p != NULL, -1); + cm_return_val_if_fail(session->write_buf_len > 0, -1); to_write_len = session->write_buf_len - (session->write_buf_p - session->write_buf); @@ -727,9 +764,9 @@ static gint session_write_data(Session *session) gint write_len; gint to_write_len; - g_return_val_if_fail(session->write_data != NULL, -1); - g_return_val_if_fail(session->write_data_p != NULL, -1); - g_return_val_if_fail(session->write_data_len > 0, -1); + cm_return_val_if_fail(session->write_data != NULL, -1); + cm_return_val_if_fail(session->write_data_p != NULL, -1); + cm_return_val_if_fail(session->write_data_len > 0, -1); to_write_len = session->write_data_len - (session->write_data_p - session->write_data); @@ -770,10 +807,10 @@ static gboolean session_write_msg_cb(SockInfo *source, GIOCondition condition, Session *session = SESSION(data); gint ret; - g_return_val_if_fail(condition == G_IO_OUT, FALSE); - g_return_val_if_fail(session->write_buf != NULL, FALSE); - g_return_val_if_fail(session->write_buf_p != NULL, FALSE); - g_return_val_if_fail(session->write_buf_len > 0, FALSE); + cm_return_val_if_fail(condition == G_IO_OUT, FALSE); + cm_return_val_if_fail(session->write_buf != NULL, FALSE); + cm_return_val_if_fail(session->write_buf_p != NULL, FALSE); + cm_return_val_if_fail(session->write_buf_len > 0, FALSE); ret = session_write_buf(session); @@ -800,10 +837,10 @@ static gboolean session_write_data_cb(SockInfo *source, guint write_data_len; gint ret; - g_return_val_if_fail(condition == G_IO_OUT, FALSE); - g_return_val_if_fail(session->write_data != NULL, FALSE); - g_return_val_if_fail(session->write_data_p != NULL, FALSE); - g_return_val_if_fail(session->write_data_len > 0, FALSE); + cm_return_val_if_fail(condition == G_IO_OUT, FALSE); + cm_return_val_if_fail(session->write_data != NULL, FALSE); + cm_return_val_if_fail(session->write_data_p != NULL, FALSE); + cm_return_val_if_fail(session->write_data_len > 0, FALSE); write_data_len = session->write_data_len; @@ -842,3 +879,16 @@ static gboolean session_write_data_cb(SockInfo *source, return FALSE; } + +void session_register_ping(Session *session, gboolean (*ping_cb)(gpointer data)) +{ + if (!session) + return; + if (session->ping_tag > -1) + g_source_remove(session->ping_tag); + + session->ping_tag = -1; + + if (ping_cb != NULL) + session->ping_tag = g_timeout_add_seconds(60, ping_cb, session); +}