Coverity fixes
[claws.git] / src / news.c
index f3e56b627c99f11034f45da804229ee983fd1617..d678e8f507a57cafe011378ee5a84151948844f1 100644 (file)
 #include "remotefolder.h"
 #include "alertpanel.h"
 #include "inc.h"
+#include "account.h"
 #ifdef USE_GNUTLS
 #  include "ssl.h"
 #endif
+#include "main.h"
 
 #define NNTP_PORT      119
 #ifdef USE_GNUTLS
@@ -83,7 +85,7 @@ struct _NewsFolder
 struct _NewsSession
 {
        Session session;
-
+       Folder *folder;
        gchar *group;
 };
 
@@ -158,6 +160,7 @@ FolderClass *news_get_class(void)
                news_class.type = F_NEWS;
                news_class.idstr = "news";
                news_class.uistr = "News";
+               news_class.supports_server_search = FALSE;
 
                /* Folder functions */
                news_class.new_folder = news_folder_new;
@@ -175,6 +178,7 @@ FolderClass *news_get_class(void)
                news_class.get_msginfos = news_get_msginfos;
                news_class.fetch_msg = news_fetch_msg;
                news_class.synchronise = news_synchronise;
+               news_class.search_msgs = folder_item_search_msgs_local;
                news_class.remove_msg = news_remove_msg;
                news_class.remove_cached_msg = news_remove_cached_msg;
        };
@@ -280,6 +284,41 @@ static void news_session_destroy(Session *session)
                g_free(news_session->group);
 }
 
+static gboolean nntp_ping(gpointer data)
+{
+       Session *session = (Session *)data;
+       NewsSession *news_session = NEWS_SESSION(session);
+       int r;
+       struct tm lt;
+
+       if (session->state != SESSION_READY || news_folder_locked(news_session->folder))
+               return FALSE;
+       
+       news_folder_lock(NEWS_FOLDER(news_session->folder));
+
+       if ((r = nntp_threaded_date(news_session->folder, &lt)) != NEWSNNTP_NO_ERROR) {
+               if (r != NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED &&
+                   r != NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD) {
+                       log_warning(LOG_PROTOCOL, _("NNTP connection to %s:%d has been"
+                             " disconnected.\n"),
+                           news_session->folder->account->nntp_server,
+                           news_session->folder->account->set_nntpport ?
+                           news_session->folder->account->nntpport : NNTP_PORT);
+                       REMOTE_FOLDER(news_session->folder)->session = NULL;
+                       news_folder_unlock(NEWS_FOLDER(news_session->folder));
+                       session->state = SESSION_DISCONNECTED;
+                       session->sock = NULL;
+                       session_destroy(session);
+                       return FALSE;
+               }
+       }
+
+       news_folder_unlock(NEWS_FOLDER(news_session->folder));
+       session_set_access_time(session);
+       return TRUE;
+}
+
+
 #ifdef USE_GNUTLS
 static Session *news_session_new(Folder *folder, const gchar *server, gushort port,
                                 const gchar *userid, const gchar *passwd,
@@ -293,8 +332,8 @@ static Session *news_session_new(Folder *folder, const gchar *server, gushort po
        int r = 0;
        cm_return_val_if_fail(server != NULL, NULL);
 
-       log_message(LOG_PROTOCOL, _("Account '%s': Connecting to NNTP server: %s...\n"),
-                                   folder->account->account_name, server);
+       log_message(LOG_PROTOCOL, _("Account '%s': Connecting to NNTP server: %s:%d...\n"),
+                                   folder->account->account_name, server, port);
 
        session = g_new0(NewsSession, 1);
        session_init(SESSION(session), folder->account, FALSE);
@@ -314,11 +353,13 @@ static Session *news_session_new(Folder *folder, const gchar *server, gushort po
                r = nntp_threaded_connect(folder, server, port);
        
        if (r != NEWSNNTP_NO_ERROR) {
-               log_error(LOG_PROTOCOL, _("Error logging in to %s:%d ...\n"), server, port);
+               log_error(LOG_PROTOCOL, _("Error logging in to %s:%d...\n"), server, port);
                session_destroy(SESSION(session));
                return NULL;
        }
-       
+
+       session->folder = folder;
+
        return SESSION(session);
 }
 
@@ -335,15 +376,6 @@ static Session *news_session_new_for_folder(Folder *folder)
        cm_return_val_if_fail(folder->account != NULL, NULL);
 
        ac = folder->account;
-       if (ac->use_nntp_auth && ac->userid && ac->userid[0]) {
-               userid = ac->userid;
-               if (ac->passwd && ac->passwd[0])
-                       passwd = g_strdup(ac->passwd);
-               else
-                       passwd = input_dialog_query_password_keep(ac->nntp_server,
-                                                                 userid,
-                                                                 &(ac->session_passwd));
-       }
 
 #ifdef USE_GNUTLS
        port = ac->set_nntpport ? ac->nntpport
@@ -368,6 +400,18 @@ static Session *news_session_new_for_folder(Folder *folder)
        session = news_session_new(folder, ac->nntp_server, port, userid, passwd);
 #endif
 
+       if (ac->use_nntp_auth && ac->userid && ac->userid[0]) {
+               userid = ac->userid;
+               if (password_get(userid, ac->nntp_server, "nntp", port, &passwd)) {
+                       /* NOP */;
+               } else if (ac->passwd && ac->passwd[0])
+                       passwd = g_strdup(ac->passwd);
+               else
+                       passwd = input_dialog_query_password_keep(ac->nntp_server,
+                                                                 userid,
+                                                                 &(ac->session_passwd));
+       }
+
        if (session != NULL)
                r = nntp_threaded_mode_reader(folder);
        else
@@ -404,7 +448,8 @@ static Session *news_session_new_for_folder(Folder *folder)
            else {
                /* An error state bail out */
                log_error(LOG_PROTOCOL, _("Error creating session with %s:%d\n"), ac->nntp_server, port);
-               session_destroy(SESSION(session));
+               if (session != NULL)
+                       session_destroy(SESSION(session));
                g_free(passwd);
                if (ac->session_passwd) {
                        g_free(ac->session_passwd);
@@ -417,7 +462,7 @@ static Session *news_session_new_for_folder(Folder *folder)
        if ((session != NULL) && ac->use_nntp_auth) { /* FIXME:  && ac->use_nntp_auth_onconnect */
                if (nntp_threaded_login(folder, userid, passwd) !=
                        NEWSNNTP_NO_ERROR) {
-                       log_error(LOG_PROTOCOL, _("Error authenticating to %s:%d ...\n"), ac->nntp_server, port);
+                       log_error(LOG_PROTOCOL, _("Error authenticating to %s:%d...\n"), ac->nntp_server, port);
                        session_destroy(SESSION(session));
                        g_free(passwd);
                        if (ac->session_passwd) {
@@ -435,8 +480,6 @@ static Session *news_session_new_for_folder(Folder *folder)
 static NewsSession *news_session_get(Folder *folder)
 {
        RemoteFolder *rfolder = REMOTE_FOLDER(folder);
-       struct tm lt;
-       int r;
        
        cm_return_val_if_fail(folder != NULL, NULL);
        cm_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, NULL);
@@ -451,6 +494,7 @@ static NewsSession *news_session_get(Folder *folder)
 
        if (!rfolder->session) {
                rfolder->session = news_session_new_for_folder(folder);
+               session_register_ping(SESSION(rfolder->session), nntp_ping);
                return NEWS_SESSION(rfolder->session);
        }
 
@@ -459,6 +503,7 @@ static NewsSession *news_session_get(Folder *folder)
        if (rfolder->session->port != folder->account->nntpport) {
                session_destroy(rfolder->session);
                rfolder->session = news_session_new_for_folder(folder);
+               session_register_ping(SESSION(rfolder->session), nntp_ping);
                goto newsession;
        }
        
@@ -467,17 +512,9 @@ static NewsSession *news_session_get(Folder *folder)
                return NEWS_SESSION(rfolder->session);
        }
 
-       if ((r = nntp_threaded_date(folder, &lt)) != NEWSNNTP_NO_ERROR) {
-               if (r != NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED &&
-                   r != NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD) {
-                       log_warning(LOG_PROTOCOL, _("NNTP connection to %s:%d has been"
-                             " disconnected. Reconnecting...\n"),
-                           folder->account->nntp_server,
-                           folder->account->set_nntpport ?
-                           folder->account->nntpport : NNTP_PORT);
-                       session_destroy(rfolder->session);
-                       rfolder->session = news_session_new_for_folder(folder);
-               }
+       if (!nntp_ping(rfolder->session)) {
+               rfolder->session = news_session_new_for_folder(folder);
+               session_register_ping(SESSION(rfolder->session), nntp_ping);
        }
 
 newsession:
@@ -725,7 +762,7 @@ void news_remove_group_list_cache(Folder *folder)
        g_free(path);
 
        if (is_file_exist(filename)) {
-               if (remove(filename) < 0)
+               if (claws_unlink(filename) < 0)
                        FILE_OP_ERROR(filename, "remove");
        }
        g_free(filename);
@@ -768,9 +805,11 @@ static gint news_get_article(Folder *folder, gint num, gchar *filename)
        r = nntp_threaded_article(folder, num, &result, &len);
        
        if (r == NEWSNNTP_NO_ERROR) {
-               if (str_write_to_file(result, filename) < 0)
+               if (str_write_to_file(result, filename) < 0) {
+                       mmap_string_unref(result);
                        return -1;
-               g_free(result);
+               }
+               mmap_string_unref(result);
        }
        
        return r;
@@ -937,7 +976,7 @@ gint news_cancel_article(Folder * folder, MsgInfo * msginfo)
        }
 
        news_post(folder, tmp);
-       remove(tmp);
+       claws_unlink(tmp);
 
        g_free(tmp);
 
@@ -1255,7 +1294,6 @@ static GSList *news_get_msginfos(Folder *folder, FolderItem *item, GSList *msgnu
        NewsSession *session;
        GSList *elem, *msginfo_list = NULL, *tmp_msgnum_list, *tmp_msginfo_list;
        guint first, last, next;
-       guint tofetch, fetched;
        
        cm_return_val_if_fail(folder != NULL, NULL);
        cm_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, NULL);
@@ -1269,8 +1307,6 @@ static GSList *news_get_msginfos(Folder *folder, FolderItem *item, GSList *msgnu
        tmp_msgnum_list = g_slist_sort(tmp_msgnum_list, g_int_compare);
 
        progressindicator_start(PROGRESS_TYPE_NETWORK);
-       tofetch = g_slist_length(tmp_msgnum_list);
-       fetched = 0;
 
        first = GPOINTER_TO_INT(tmp_msgnum_list->data);
        last = first;
@@ -1280,12 +1316,8 @@ static GSList *news_get_msginfos(Folder *folder, FolderItem *item, GSList *msgnu
        for(elem = g_slist_next(tmp_msgnum_list); elem != NULL; elem = g_slist_next(elem)) {
                next = GPOINTER_TO_INT(elem->data);
                if(next != (last + 1)) {
-/*                     session->fetch_base_percentage = ((gfloat) fetched) / ((gfloat) tofetch);
-                       session->fetch_total_percentage = ((gfloat) (last - first + 1)) / ((gfloat) tofetch);
-*/
                        tmp_msginfo_list = news_get_msginfos_for_range(session, item, first, last);
                        msginfo_list = g_slist_concat(msginfo_list, tmp_msginfo_list);
-                       fetched = last - first + 1;
                        first = next;
                }
                last = next;
@@ -1293,9 +1325,6 @@ static GSList *news_get_msginfos(Folder *folder, FolderItem *item, GSList *msgnu
        
        news_folder_unlock(NEWS_FOLDER(item->folder));
        
-/*     session->fetch_base_percentage = ((gfloat) fetched) / ((gfloat) tofetch);
-       session->fetch_total_percentage = ((gfloat) (last - first + 1)) / ((gfloat) tofetch);
-*/
        tmp_msginfo_list = news_get_msginfos_for_range(session, item, first, last);
        msginfo_list = g_slist_concat(msginfo_list, tmp_msginfo_list);
 
@@ -1356,6 +1385,48 @@ static gint news_remove_folder(Folder *folder, FolderItem *item)
        return 0;
 }
 
+void nntp_disconnect_all(gboolean have_connectivity)
+{
+       GList *list;
+       gboolean short_timeout;
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+       GError *error;
+#endif
+
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+       error = NULL;
+       short_timeout = !networkmanager_is_online(&error);
+       if(error) {
+               short_timeout = TRUE;
+               g_error_free(error);
+       }
+#else
+       short_timeout = TRUE;
+#endif
+
+       if(short_timeout)
+               nntp_main_set_timeout(1);
+
+       for (list = account_get_list(); list != NULL; list = list->next) {
+               PrefsAccount *account = list->data;
+               if (account->protocol == A_NNTP) {
+                       RemoteFolder *folder = (RemoteFolder *)account->folder;
+                       if (folder && folder->session) {
+                               NewsSession *session = (NewsSession *)folder->session;
+                               if (have_connectivity)
+                                       nntp_threaded_disconnect(FOLDER(folder));
+                               SESSION(session)->state = SESSION_DISCONNECTED;
+                               SESSION(session)->sock = NULL;
+                               session_destroy(SESSION(session));
+                               folder->session = NULL;
+                       }
+               }
+       }
+
+       if(short_timeout)
+               nntp_main_set_timeout(prefs_common.io_timeout_secs);
+}
+
 #else
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -1432,5 +1503,8 @@ FolderClass *news_get_class(void)
        return &news_class;
 }
 
+void nntp_disconnect_all(gboolean have_connectivity)
+{
+}
 
 #endif