news scoring
[claws.git] / src / news.c
index c76781e2783c7bcc01e0b96b875751372c73403e..cb9df7d7263e37f3d203033f5d40b52529b4c374 100644 (file)
@@ -57,12 +57,16 @@ static gint news_get_header          (NNTPSession   *session,
                                          gint           num,
                                          gchar         *filename);
 
+static gint news_select_group           (NNTPSession   *session,
+                                         const char    *group);
 static GSList *news_get_uncached_articles(NNTPSession  *session,
                                          FolderItem    *item,
                                          gint           cache_last,
                                          gint          *rfirst,
                                          gint          *rlast);
 static MsgInfo *news_parse_xover        (const gchar   *xover_str);
+static gchar * news_parse_xhdr           (const gchar *xover_str,
+                                         MsgInfo * info);
 static GSList *news_delete_old_article  (GSList        *alist,
                                          gint           first);
 static void news_delete_all_article     (FolderItem    *item);
@@ -83,7 +87,7 @@ static Session *news_session_new(const gchar *server, gushort port,
                nntp_sock = nntp_open_auth(server, port, buf, userid, passwd);
        else
                nntp_sock = nntp_open(server, port, buf);
-       if (nntp_sock < 0)
+       if (nntp_sock == NULL)
                return NULL;
 
        session = g_new(NNTPSession, 1);
@@ -133,7 +137,7 @@ static Session *news_session_new_for_folder(Folder *folder)
        gchar *passwd;
 
        ac = folder->account;
-       if (ac->userid && ac->userid[0]) {
+       if (ac->use_nntp_auth && ac->userid && ac->userid[0]) {
                userid = ac->userid;
                if (ac->passwd && ac->passwd[0])
                        passwd = g_strdup(ac->passwd);
@@ -243,6 +247,14 @@ gchar *news_fetch_msg(Folder *folder, FolderItem *item, gint num)
                return NULL;
        }
 
+       ok = news_select_group(NNTP_SESSION(REMOTE_FOLDER(folder)->session),
+                              item->path);
+       if (ok != NN_SUCCESS) {
+               g_warning(_("can't select group %s\n"), item->path);
+               g_free(filename);
+               return NULL;
+       }
+
        debug_print(_("getting article %d...\n"), num);
        ok = news_get_article(NNTP_SESSION(REMOTE_FOLDER(folder)->session),
                              num, filename);
@@ -321,6 +333,36 @@ static gint news_get_header(NNTPSession *session, gint num, gchar *filename)
        return news_get_article_cmd(session, "HEAD", num, filename);
 }
 
+/**
+ * news_select_group:
+ * @session: Active NNTP session.
+ * @group: Newsgroup name.
+ * 
+ * Select newsgroup @group with the GROUP command if it is not already
+ * selected in @session.
+ * 
+ * Return value: NNTP result code.
+ **/
+static gint news_select_group(NNTPSession *session,
+                             const char *group)
+{
+       gint ok;
+       gint num, first, last;
+
+       if (g_strcasecmp(session->group, group) == 0)
+               return NN_SUCCESS;
+
+       g_free(session->group);
+       session->group = NULL;
+
+       ok = nntp_group(session->nntp_sock, group, &num, &first, &last);
+
+       if (ok == NN_SUCCESS)
+               session->group = g_strdup(group);
+
+       return ok;
+}
+
 static GSList *news_get_uncached_articles(NNTPSession *session,
                                          FolderItem *item, gint cache_last,
                                          gint *rfirst, gint *rlast)
@@ -340,6 +382,9 @@ static GSList *news_get_uncached_articles(NNTPSession *session,
        g_return_val_if_fail(item->folder != NULL, NULL);
        g_return_val_if_fail(item->folder->type == F_NEWS, NULL);
 
+       g_free(session->group);
+       session->group = NULL;
+
        ok = nntp_group(session->nntp_sock, item->path,
                        &num, &first, &last);
        if (ok != NN_SUCCESS) {
@@ -347,6 +392,8 @@ static GSList *news_get_uncached_articles(NNTPSession *session,
                return NULL;
        }
 
+       session->group = g_strdup(item->path);
+
        /* calculate getting overview range */
        if (first > last) {
                log_warning(_("invalid article range: %d - %d\n"),
@@ -376,7 +423,7 @@ static GSList *news_get_uncached_articles(NNTPSession *session,
        }
 
        for (;;) {
-               if (sock_read(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
+               if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
                        log_warning(_("error occurred while getting xover.\n"));
                        return newlist;
                }
@@ -400,6 +447,61 @@ static GSList *news_get_uncached_articles(NNTPSession *session,
                }
        }
 
+       if (nntp_xhdr(session->nntp_sock, "to", begin, end) != NN_SUCCESS) {
+               log_warning(_("can't get xhdr\n"));
+               return NULL;
+       }
+
+       llast = newlist;
+
+       for (;;) {
+               gchar * value;
+               
+               if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
+                       log_warning(_("error occurred while getting xover.\n"));
+                       return newlist;
+               }
+
+               if (buf[0] == '.' && buf[1] == '\r') break;
+
+               msginfo = (MsgInfo *) llast->data;
+
+               value = news_parse_xhdr(buf, msginfo);
+
+               if (value)
+                       msginfo->to = value;
+
+               llast = llast->next;
+               
+       }
+
+       if (nntp_xhdr(session->nntp_sock, "cc", begin, end) != NN_SUCCESS) {
+               log_warning(_("can't get xhdr\n"));
+               return NULL;
+       }
+
+       llast = newlist;
+
+       for (;;) {
+               gchar * value;
+               
+               if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
+                       log_warning(_("error occurred while getting xover.\n"));
+                       return newlist;
+               }
+
+               if (buf[0] == '.' && buf[1] == '\r') break;
+
+               msginfo = (MsgInfo *) llast->data;
+
+               value = news_parse_xhdr(buf, msginfo);
+
+               if (value)
+                       msginfo->cc = value;
+
+               llast = llast->next;
+       }
+
        if (rfirst) *rfirst = first;
        if (rlast)  *rlast  = last;
        return newlist;
@@ -473,6 +575,26 @@ static MsgInfo *news_parse_xover(const gchar *xover_str)
        return msginfo;
 }
 
+static gchar * news_parse_xhdr(const gchar *xover_str, MsgInfo * info)
+{
+       gchar buf[NNTPBUFSIZE];
+       gchar *p;
+       gint num;
+
+       p = strchr(xover_str, ' ');
+       if (!p)
+               return NULL;
+       else
+               p++;
+
+       num = atoi(xover_str);
+
+       if (info->msgnum != num)
+               return NULL;
+
+       return g_strdup(p);
+}
+
 static GSList *news_delete_old_article(GSList *alist, gint first)
 {
        GSList *cur, *next;