/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2006 Hiroyuki Yamamoto and the Sylpheed-Claws 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
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <time.h>
#include "news.h"
+#include "news_gtk.h"
#include "nntp.h"
#include "socket.h"
#include "recv.h"
#include "progressindicator.h"
#include "remotefolder.h"
#include "alertpanel.h"
+#include "inc.h"
+
#if USE_OPENSSL
# include "ssl.h"
#endif
RemoteFolder rfolder;
gboolean use_auth;
+ gboolean lock_count;
};
static void news_folder_init (Folder *folder,
static gchar *news_folder_get_path (Folder *folder);
gchar *news_item_get_path (Folder *folder,
FolderItem *item);
-
+static void news_synchronise (FolderItem *item);
+static int news_remove_msg (Folder *folder,
+ FolderItem *item,
+ gint msgnum);
+static gint news_remove_folder (Folder *folder,
+ FolderItem *item);
static FolderClass news_class;
FolderClass *news_get_class(void)
news_class.item_get_path = news_item_get_path;
news_class.get_num_list = news_get_num_list;
news_class.scan_required = news_scan_required;
+ news_class.remove_folder = news_remove_folder;
/* Message functions */
news_class.get_msginfo = news_get_msginfo;
news_class.get_msginfos = news_get_msginfos;
news_class.fetch_msg = news_fetch_msg;
+ news_class.synchronise = news_synchronise;
+ news_class.remove_msg = news_remove_msg;
};
return &news_class;
}
+static int news_remove_msg (Folder *folder,
+ FolderItem *item,
+ gint msgnum)
+{
+ gchar *path, *filename;
+
+ g_return_val_if_fail(folder != NULL, -1);
+ g_return_val_if_fail(item != NULL, -1);
+
+ path = folder_item_get_path(item);
+ if (!is_dir_exist(path))
+ make_dir_hier(path);
+
+ filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(msgnum), NULL);
+ g_free(path);
+ g_unlink(filename);
+ g_free(filename);
+ return 0;
+}
+
+static void news_folder_lock(NewsFolder *folder)
+{
+ folder->lock_count++;
+}
+
+static void news_folder_unlock(NewsFolder *folder)
+{
+ if (folder->lock_count > 0)
+ folder->lock_count--;
+}
+
+int news_folder_locked(Folder *folder)
+{
+ if (folder == NULL)
+ return 0;
+
+ return NEWS_FOLDER(folder)->lock_count;
+}
+
static Folder *news_folder_new(const gchar *name, const gchar *path)
{
Folder *folder;
session = news_session_new(ac->nntp_server, port, userid, passwd,
ac->ssl_nntp);
#else
+ if (ac->ssl_nntp != SSL_NONE) {
+ if (alertpanel_full(_("Insecure connection"),
+ _("This connection is configured to be secured "
+ "using SSL, but SSL is not available in this "
+ "build of Sylpheed-Claws. \n\n"
+ "Do you want to continue connecting to this "
+ "server? The communication would not be "
+ "secure."),
+ GTK_STOCK_CANCEL, _("Con_tinue connecting"),
+ NULL, FALSE, NULL, ALERT_WARNING,
+ G_ALERTDEFAULT) != G_ALERTALTERNATE)
+ return NULL;
+ }
port = ac->set_nntpport ? ac->nntpport : NNTP_PORT;
session = news_session_new(ac->nntp_server, port, userid, passwd);
#endif
g_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, NULL);
g_return_val_if_fail(folder->account != NULL, NULL);
- if (prefs_common.work_offline)
+ if (prefs_common.work_offline &&
+ !inc_offline_should_override(
+ _("Sylpheed-Claws needs network access in order "
+ "to access the News server."))) {
return NULL;
+ }
if (!rfolder->session) {
rfolder->session = news_session_new_for_folder(folder);
g_free(filename);
return NULL;
}
-
+ GTK_EVENTS_FLUSH();
return filename;
}
filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL);
g_free(path);
- if ((fp = fopen(filename, "rb")) == NULL) {
+ if ((fp = g_fopen(filename, "rb")) == NULL) {
NNTPSession *session;
gint ok;
return NULL;
}
- if ((fp = fopen(filename, "rb")) == NULL) {
+ if ((fp = g_fopen(filename, "rb")) == NULL) {
FILE_OP_ERROR(filename, "fopen");
g_free(filename);
return NULL;
g_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, -1);
g_return_val_if_fail(file != NULL, -1);
- if ((fp = fopen(file, "rb")) == NULL) {
+ if ((fp = g_fopen(file, "rb")) == NULL) {
FILE_OP_ERROR(file, "fopen");
return -1;
}
msginfo->subject = conv_unmime_header(subject, NULL);
+ remove_return(msginfo->from);
+ remove_return(msginfo->fromname);
+ remove_return(msginfo->subject);
+
if (msgid) {
extract_parenthesis(msgid, '<', '>');
remove_space(msgid);
* into having the actual list of references in the References: header.
* We need a GSList here, so msginfo_free() and msginfo_copy() can do
* their things properly. */
- if (ref) {
- msginfo->references = g_slist_append(msginfo->references, g_strdup(ref));
+ if (ref && strlen(ref)) {
+ gchar **ref_tokens = g_strsplit(ref, " ", -1);
+ guint i = 0;
+
+ while (ref_tokens[i]) {
+ gchar *cur_ref = ref_tokens[i];
+ msginfo->references = references_list_append(msginfo->references,
+ cur_ref);
+ i++;
+ }
+ g_strfreev(ref_tokens);
+
eliminate_parenthesis(ref, '(', ')');
if ((p = strrchr(ref, '<')) != NULL) {
extract_parenthesis(p, '<', '>');
if (*p != '\0')
msginfo->inreplyto = g_strdup(p);
}
- }
-
- /*
- msginfo->xref = g_strdup(xref);
- p = msginfo->xref+strlen(msginfo->xref) - 1;
- while (*p == '\r' || *p == '\n') {
- *p = '\0';
- p--;
- }
- */
+ }
return msginfo;
}
if (tmp == NULL)
return -1;
- if ((tmpfp = fopen(tmp, "wb")) == NULL) {
+ if ((tmpfp = g_fopen(tmp, "wb")) == NULL) {
FILE_OP_ERROR(tmp, "fopen");
return -1;
}
g_return_val_if_fail(session != NULL, -1);
*old_uids_valid = TRUE;
+
+ news_folder_lock(NEWS_FOLDER(item->folder));
ok = news_select_group(session, item->path, &num, &first, &last);
if (ok != NN_SUCCESS) {
log_warning(_("can't set group: %s\n"), item->path);
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return -1;
}
remove_numbered_files(dir, 1, first - 1);
}
g_free(dir);
-
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return nummsgs;
}
} \
}
+static void news_set_msg_flags(FolderItem *item, MsgInfo *msginfo)
+{
+ msginfo->flags.tmp_flags = 0;
+ if (item->folder->account->mark_crosspost_read && msginfo->msgid) {
+ if (item->folder->newsart &&
+ g_hash_table_lookup(item->folder->newsart, msginfo->msgid) != NULL) {
+ msginfo->flags.perm_flags = MSG_COLORLABEL_TO_FLAGS(item->folder->account->crosspost_col);
+
+ } else {
+ if (!item->folder->newsart)
+ item->folder->newsart = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(item->folder->newsart,
+ g_strdup(msginfo->msgid), GINT_TO_POINTER(1));
+ msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
+ }
+ } else {
+ msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
+ }
+}
+
MsgInfo *news_get_msginfo(Folder *folder, FolderItem *item, gint num)
{
NNTPSession *session;
log_message(_("getting xover %d in %s...\n"),
num, item->path);
ok = nntp_xover(session, num, num);
+
+ news_folder_lock(NEWS_FOLDER(item->folder));
+
if (ok != NN_SUCCESS) {
log_warning(_("can't get xover\n"));
if (ok == NN_SOCKET) {
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return NULL;
}
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xover.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return NULL;
}
READ_TO_LISTEND("xover");
- if(!msginfo)
+ if(!msginfo) {
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return NULL;
-
+ }
+
msginfo->folder = item;
- msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
- msginfo->flags.tmp_flags = MSG_NEWS;
+
+ news_set_msg_flags(item, msginfo);
+ msginfo->flags.tmp_flags |= MSG_NEWS;
msginfo->newsgroups = g_strdup(item->path);
ok = nntp_xhdr(session, "to", num, num);
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return msginfo;
}
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xhdr.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return msginfo;
}
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return msginfo;
}
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xhdr.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return msginfo;
}
msginfo->cc = news_parse_xhdr(buf, msginfo);
READ_TO_LISTEND("xhdr (cc)");
-
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return msginfo;
}
GSList *newlist = NULL;
GSList *llast = NULL;
MsgInfo *msginfo;
- guint count = 0, lines = (end - begin + 2) * 3;
+ guint count = 0, lines = (end - begin) + 2;
gint ok;
g_return_val_if_fail(session != NULL, NULL);
return NULL;
}
+ news_folder_lock(NEWS_FOLDER(item->folder));
+
for (;;) {
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xover.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return newlist;
}
count++;
}
msginfo->folder = item;
- msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
- msginfo->flags.tmp_flags = MSG_NEWS;
+ news_set_msg_flags(item, msginfo);
+ msginfo->flags.tmp_flags |= MSG_NEWS;
msginfo->newsgroups = g_strdup(item->path);
if (!newlist)
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return newlist;
}
for (;;) {
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xhdr.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return newlist;
}
- count++;
- progressindicator_set_percentage
- (PROGRESS_TYPE_NETWORK,
- session->fetch_base_percentage +
- (((gfloat) count) / ((gfloat) lines)) * session->fetch_total_percentage);
if (buf[0] == '.' && buf[1] == '\r') break;
if (!llast) {
session_destroy(SESSION(session));
REMOTE_FOLDER(item->folder)->session = NULL;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return newlist;
}
for (;;) {
if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
log_warning(_("error occurred while getting xhdr.\n"));
+ news_folder_unlock(NEWS_FOLDER(item->folder));
return newlist;
}
- count++;
- progressindicator_set_percentage
- (PROGRESS_TYPE_NETWORK,
- session->fetch_base_percentage +
- (((gfloat) count) / ((gfloat) lines)) * session->fetch_total_percentage);
if (buf[0] == '.' && buf[1] == '\r') break;
if (!llast) {
llast = llast->next;
}
+ news_folder_unlock(NEWS_FOLDER(item->folder));
session_set_access_time(SESSION(session));
first = GPOINTER_TO_INT(tmp_msgnum_list->data);
last = first;
+
+ news_folder_lock(NEWS_FOLDER(item->folder));
+
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)) {
}
last = next;
}
+
+ 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);
{
return TRUE;
}
+
+void news_synchronise(FolderItem *item)
+{
+ news_gtk_synchronise(item);
+}
+
+static gint news_remove_folder(Folder *folder, FolderItem *item)
+{
+ gchar *path;
+
+ g_return_val_if_fail(folder != NULL, -1);
+ g_return_val_if_fail(item != NULL, -1);
+ g_return_val_if_fail(item->path != NULL, -1);
+
+ path = folder_item_get_path(item);
+ if (remove_dir_recursive(path) < 0) {
+ g_warning("can't remove directory `%s'\n", path);
+ g_free(path);
+ return -1;
+ }
+
+ g_free(path);
+ folder_item_remove(item);
+ return 0;
+}