Do not try to destroy a NULL session after an unsuccesful NNTP connect attempt.
[claws.git] / src / news.c
index 1f0ddc2ed9f9739286a25fff68bf078b72709dc1..7f2e00cf6c1fed766756d57b72b93dd927cbd40a 100644 (file)
@@ -292,6 +292,8 @@ static gboolean nntp_ping(gpointer data)
        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) {
@@ -301,10 +303,15 @@ static gboolean nntp_ping(gpointer data)
                            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;
 }
@@ -344,14 +351,14 @@ 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);
-               session_destroy(SESSION(session));
+               log_error(LOG_PROTOCOL, _("Error logging in to %s:%d...\n"), server, port);
+               if (session != NULL)
+                       session_destroy(SESSION(session));
                return NULL;
        }
 
        session->folder = folder;
 
-       session_register_ping(SESSION(session), nntp_ping);
        return SESSION(session);
 }
 
@@ -437,7 +444,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);
@@ -450,7 +458,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) {
@@ -482,6 +490,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);
        }
 
@@ -490,6 +499,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;
        }
        
@@ -498,8 +508,10 @@ static NewsSession *news_session_get(Folder *folder)
                return NEWS_SESSION(rfolder->session);
        }
 
-       if (!nntp_ping(rfolder->session))
+       if (!nntp_ping(rfolder->session)) {
                rfolder->session = news_session_new_for_folder(folder);
+               session_register_ping(SESSION(rfolder->session), nntp_ping);
+       }
 
 newsession:
        if (rfolder->session)
@@ -789,9 +801,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;
@@ -1380,6 +1394,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>
@@ -1456,5 +1512,8 @@ FolderClass *news_get_class(void)
        return &news_class;
 }
 
+void nntp_disconnect_all(gboolean have_connectivity)
+{
+}
 
 #endif