gint *first,
gint *last);
static MsgInfo *news_parse_xover (struct newsnntp_xover_resp_item *item);
-static gchar *news_parse_xhdr (clist *list,
- MsgInfo *msginfo);
static gint news_get_num_list (Folder *folder,
FolderItem *item,
GSList **list,
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;
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);
rfolder->session = news_session_new_for_folder(folder);
}
}
-
+
+newsession:
if (rfolder->session)
session_set_access_time(rfolder->session);
return msginfo;
}
-static gchar *news_parse_xhdr(clist *hdrlist, MsgInfo *msginfo)
-{
- struct newsnntp_xhdr_resp_item *hdr;
-
- if (!hdrlist)
- return NULL;
-
- hdr = clist_content(clist_begin(hdrlist));
- if (hdr->hdr_article != msginfo->msgnum)
- return NULL;
- return g_strdup(hdr->hdr_value);
-}
-
gint news_cancel_article(Folder * folder, MsgInfo * msginfo)
{
gchar * tmp;
}
}
-static MsgInfo *news_get_msginfo(Folder *folder, FolderItem *item, gint num)
+static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList *msglist)
{
- NewsSession *session;
MsgInfo *msginfo = NULL;
gint ok;
- struct newsnntp_xover_resp_item *result = NULL;
+ GSList *cur;
clist *hdrlist = NULL;
+ clistiter *hdr;
+ gint first = -1, last = -1;
+ GHashTable *hash_table;
+
+ cm_return_if_fail(session != NULL);
+ cm_return_if_fail(item != NULL);
+ cm_return_if_fail(item->folder != NULL);
+ cm_return_if_fail(FOLDER_CLASS(item->folder) == &news_class);
- session = news_session_get(folder);
- cm_return_val_if_fail(session != NULL, NULL);
- cm_return_val_if_fail(item != NULL, NULL);
- cm_return_val_if_fail(item->folder != NULL, NULL);
- cm_return_val_if_fail(FOLDER_CLASS(item->folder) == &news_class, NULL);
-
- log_message(LOG_PROTOCOL, _("getting xover %d in %s...\n"),
- num, item->path);
news_folder_lock(NEWS_FOLDER(item->folder));
- ok = nntp_threaded_xover(folder, num, num, &result, NULL);
+ hash_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+ for (cur = msglist; cur; cur = cur->next) {
+ msginfo = (MsgInfo *)cur->data;
+ if (first == -1 || msginfo->msgnum < first)
+ first = msginfo->msgnum;
+ if (last == -1 || msginfo->msgnum > last)
+ last = msginfo->msgnum;
+ g_hash_table_insert(hash_table,
+ GINT_TO_POINTER(msginfo->msgnum), msginfo);
+ }
+
+/* Newsgroups */
+ ok = nntp_threaded_xhdr(item->folder, "newsgroups", first, last, &hdrlist);
+
if (ok != NEWSNNTP_NO_ERROR) {
- log_warning(LOG_PROTOCOL, _("couldn't get xover\n"));
+ log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n"));
if (ok == NEWSNNTP_ERROR_STREAM) {
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
news_folder_unlock(NEWS_FOLDER(item->folder));
- return NULL;
- }
-
- msginfo = news_parse_xover(result);
- xover_resp_item_free(result);
- if (!msginfo) {
- log_warning(LOG_PROTOCOL, _("invalid xover line\n"));
+ return;
}
- if(!msginfo) {
- news_folder_unlock(NEWS_FOLDER(item->folder));
- return NULL;
+ for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) {
+ struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr);
+ msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article));
+ if (msginfo) {
+ if (msginfo->newsgroups)
+ g_free(msginfo->newsgroups);
+ msginfo->newsgroups = g_strdup(hdrval->hdr_value);
+ }
}
-
- msginfo->folder = item;
+ newsnntp_xhdr_free(hdrlist);
- news_set_msg_flags(item, msginfo);
- msginfo->flags.tmp_flags |= MSG_NEWS;
- msginfo->newsgroups = g_strdup(item->path);
+/* To */
+ ok = nntp_threaded_xhdr(item->folder, "to", first, last, &hdrlist);
- ok = nntp_threaded_xhdr(folder, "to", num, num, &hdrlist);
-
if (ok != NEWSNNTP_NO_ERROR) {
log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n"));
if (ok == NEWSNNTP_ERROR_STREAM) {
REMOTE_FOLDER(item->folder)->session = NULL;
}
news_folder_unlock(NEWS_FOLDER(item->folder));
- return msginfo;
+ return;
}
- msginfo->to = news_parse_xhdr(hdrlist, msginfo);
+ for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) {
+ struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr);
+ msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article));
+ if (msginfo) {
+ if (msginfo->to)
+ g_free(msginfo->to);
+ msginfo->to = g_strdup(hdrval->hdr_value);
+ }
+ }
newsnntp_xhdr_free(hdrlist);
-
- ok = nntp_threaded_xhdr(folder, "cc", num, num, &hdrlist);
+/* Cc */
+ ok = nntp_threaded_xhdr(item->folder, "cc", first, last, &hdrlist);
+
if (ok != NEWSNNTP_NO_ERROR) {
log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n"));
if (ok == NEWSNNTP_ERROR_STREAM) {
REMOTE_FOLDER(item->folder)->session = NULL;
}
news_folder_unlock(NEWS_FOLDER(item->folder));
- return msginfo;
+ return;
}
- msginfo->cc = news_parse_xhdr(hdrlist, msginfo);
+ for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) {
+ struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr);
+ msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article));
+ if (msginfo) {
+ if (msginfo->cc)
+ g_free(msginfo->cc);
+ msginfo->cc = g_strdup(hdrval->hdr_value);
+ }
+ }
newsnntp_xhdr_free(hdrlist);
+
+ g_hash_table_destroy(hash_table);
news_folder_unlock(NEWS_FOLDER(item->folder));
- return msginfo;
}
static GSList *news_get_msginfos_for_range(NewsSession *session, FolderItem *item, guint begin, guint end)
msginfo->folder = item;
news_set_msg_flags(item, msginfo);
msginfo->flags.tmp_flags |= MSG_NEWS;
- msginfo->newsgroups = g_strdup(item->path);
if (!newlist)
llast = newlist = g_slist_append(newlist, msginfo);
session_set_access_time(SESSION(session));
+ news_get_extra_fields(session, item, newlist);
+
return newlist;
}
+static MsgInfo *news_get_msginfo(Folder *folder, FolderItem *item, gint num)
+{
+ GSList *msglist = NULL;
+ NewsSession *session;
+ MsgInfo *msginfo = NULL;
+
+ session = news_session_get(folder);
+ cm_return_val_if_fail(session != NULL, NULL);
+ cm_return_val_if_fail(item != NULL, NULL);
+ cm_return_val_if_fail(item->folder != NULL, NULL);
+ cm_return_val_if_fail(FOLDER_CLASS(item->folder) == &news_class, NULL);
+
+ msglist = news_get_msginfos_for_range(session, item, num, num);
+
+ if (msglist)
+ msginfo = msglist->data;
+
+ g_slist_free(msglist);
+
+ return msginfo;
+}
+
static GSList *news_get_msginfos(Folder *folder, FolderItem *item, GSList *msgnum_list)
{
NewsSession *session;