2011-09-18 [colin] 3.7.10cvs17
[claws.git] / src / news.c
index 0d4d6fa71a891762453a654e124ca269c2d413c5..3f0e0e7104d5305e1ab6d10d897a040e7e3ff278 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2011 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
@@ -292,12 +292,14 @@ 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, _("creating NNTP connection to %s:%d ...\n"), server, port);
+       log_message(LOG_PROTOCOL, _("Account '%s': Connecting to NNTP server: %s...\n"),
+                                   folder->account->account_name, server);
 
        session = g_new0(NewsSession, 1);
        session_init(SESSION(session), folder->account, FALSE);
        SESSION(session)->type             = SESSION_NEWS;
        SESSION(session)->server           = g_strdup(server);
+       SESSION(session)->port             = port;
        SESSION(session)->sock             = NULL;
        SESSION(session)->destroy          = news_session_destroy;
        
@@ -326,6 +328,7 @@ static Session *news_session_new_for_folder(Folder *folder)
        const gchar *userid = NULL;
        gchar *passwd = NULL;
        gushort port;
+       int r;
 
        cm_return_val_if_fail(folder != NULL, NULL);
        cm_return_val_if_fail(folder->account != NULL, NULL);
@@ -364,6 +367,52 @@ static Session *news_session_new_for_folder(Folder *folder)
        session = news_session_new(folder, ac->nntp_server, port, userid, passwd);
 #endif
 
+       if (session != NULL)
+               r = nntp_threaded_mode_reader(folder);
+       else
+               r = NEWSNNTP_ERROR_CONNECTION_REFUSED;
+
+       if (r != NEWSNNTP_NO_ERROR) {
+           if (r == NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME) {
+               /*
+                  FIX ME when libetpan implements 480 to indicate authorization
+                  is required to use this capability. Libetpan treats a 480 as a
+                  381 which is clearly wrong.
+                  RFC 4643 section 2.
+                  Response code 480
+                  Generic response
+                  Meaning: command unavailable until the client
+                  has authenticated itself.
+               */
+               /* if the server does not advertise the capability MODE-READER,
+                  we normally should not send MODE READER. However this can't
+                  hurt: a transit-only server returns 502 and closes the cnx.
+                  Ref.: http://tools.ietf.org/html/rfc3977#section-5.3
+               */
+               log_error(LOG_PROTOCOL, _("Libetpan does not support return code 480 "
+               "so for now we choose to continue\n"));
+           }
+           else if (r == NEWSNNTP_ERROR_UNEXPECTED_RESPONSE) {
+               /* if the server does not advertise the capability MODE-READER,
+                  we normally should not send MODE READER. However this can't
+                  hurt: a transit-only server returns 502 and closes the cnx.
+                  Ref.: http://tools.ietf.org/html/rfc3977#section-5.3
+               */
+               log_error(LOG_PROTOCOL, _("Mode reader failed, continuing nevertheless\n")); 
+           }
+           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));
+               g_free(passwd);
+               if (ac->session_passwd) {
+                       g_free(ac->session_passwd);
+                       ac->session_passwd = NULL;
+               }
+               return NULL;
+           }
+       }
+
        if ((session != NULL) && ac->use_nntp_auth) { /* FIXME:  && ac->use_nntp_auth_onconnect */
                if (nntp_threaded_login(folder, userid, passwd) !=
                        NEWSNNTP_NO_ERROR) {
@@ -404,6 +453,14 @@ static NewsSession *news_session_get(Folder *folder)
                return NEWS_SESSION(rfolder->session);
        }
 
+       /* Handle port change (also ssl/nossl change) without needing to
+        * restart application. */
+       if (rfolder->session->port != folder->account->nntpport) {
+               session_destroy(rfolder->session);
+               rfolder->session = news_session_new_for_folder(folder);
+               goto newsession;
+       }
+       
        if (time(NULL) - rfolder->session->last_access_time <
                SESSION_TIMEOUT_INTERVAL) {
                return NEWS_SESSION(rfolder->session);
@@ -421,7 +478,8 @@ static NewsSession *news_session_get(Folder *folder)
                        rfolder->session = news_session_new_for_folder(folder);
                }
        }
-       
+
+newsession:
        if (rfolder->session)
                session_set_access_time(rfolder->session);
 
@@ -690,11 +748,6 @@ gint news_post(Folder *folder, const gchar *file)
        
        ok = nntp_threaded_post(folder, contents, strlen(contents));
 
-       if (ok != NEWSNNTP_NO_ERROR && ok != NEWSNNTP_ERROR_STREAM) {
-               ok = nntp_threaded_mode_reader(folder);
-               if (ok == NEWSNNTP_NO_ERROR)
-                       ok = nntp_threaded_post(folder, contents, strlen(contents));
-       }
        g_free(contents);
 
        if (ok == NEWSNNTP_ERROR_STREAM) {
@@ -758,14 +811,6 @@ static gint news_select_group(Folder *folder, const gchar *group,
 
        ok = nntp_threaded_group(folder, group, &info);
        
-       if (ok != NEWSNNTP_NO_ERROR && 
-           ok != NEWSNNTP_ERROR_STREAM && 
-           ok != NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME) {
-               ok = nntp_threaded_mode_reader(folder);
-               if (ok == NEWSNNTP_NO_ERROR)
-                       ok = nntp_threaded_group(folder, group, &info);
-       }
-
        if (ok == NEWSNNTP_NO_ERROR && info) {
                session->group = g_strdup(group);
                *num = info->grp_first;
@@ -790,10 +835,10 @@ static MsgInfo *news_parse_xover(struct newsnntp_xover_resp_item *item)
        msginfo->date = g_strdup(item->ovr_date);
        msginfo->date_t = procheader_date_parse(NULL, item->ovr_date, 0);
 
-        msginfo->from = conv_unmime_header(item->ovr_author, NULL);
+       msginfo->from = conv_unmime_header(item->ovr_author, NULL, TRUE);
        msginfo->fromname = procheader_get_fromname(msginfo->from);
 
-        msginfo->subject = conv_unmime_header(item->ovr_subject, NULL);
+       msginfo->subject = conv_unmime_header(item->ovr_subject, NULL, TRUE);
 
        remove_return(msginfo->from);
        remove_return(msginfo->fromname);
@@ -1130,6 +1175,13 @@ static GSList *news_get_msginfos_for_range(NewsSession *session, FolderItem *ite
 
        news_folder_lock(NEWS_FOLDER(item->folder));
        
+       ok = news_select_group(item->folder, item->path, NULL, NULL, NULL);
+       if (ok != NEWSNNTP_NO_ERROR) {
+               log_warning(LOG_PROTOCOL, _("couldn't set group: %s\n"), item->path);
+               news_folder_unlock(NEWS_FOLDER(item->folder));
+               return NULL;
+       }
+
        ok = nntp_threaded_xover(item->folder, begin, end, NULL, &msglist);
        
        if (ok != NEWSNNTP_NO_ERROR) {