aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorChris Toshok <toshok@helixcode.com>2000-06-23 10:03:35 +0800
committerChris Toshok <toshok@src.gnome.org>2000-06-23 10:03:35 +0800
commit61ec5b754bb8acf189d0ac083bf8e0cb0c98ebc0 (patch)
tree10f5113029f696b542b83b549d36c570f4ceee81 /camel/providers
parentafa7176eab5a2c495a8f10de4c430f443cdcfb99 (diff)
downloadgsoc2013-evolution-61ec5b754bb8acf189d0ac083bf8e0cb0c98ebc0.tar.gz
gsoc2013-evolution-61ec5b754bb8acf189d0ac083bf8e0cb0c98ebc0.tar.zst
gsoc2013-evolution-61ec5b754bb8acf189d0ac083bf8e0cb0c98ebc0.zip
ignore test-newsrc
2000-06-22 Chris Toshok <toshok@helixcode.com> * providers/nntp/.cvsignore: ignore test-newsrc * providers/nntp/camel-nntp-store.c, providers/nntp/camel-nntp-store.h, providers/nntp/camel-nntp-folder.c, providers/nntp/camel-nntp-folder.h, providers/nntp/camel-nntp-utils.c: Bring the nntp provider up to a state where it builds and is usable with the current camel. there are still warts (semi-broken .newsrc file handling, and a lack of a subscribe ui -- in fact no way to add a new server, really), but it'll display news messages. * providers/nntp/Makefile.am (libcamelnntp_la_SOURCES): add camel-nntp-newsrc.c (libcamelnntpinclude_HEADERS): add camel-nntp-newsrc.h also, add test-newsrc stuff. * providers/nntp/test-newsrc.c: new file that tests the newsrc stuff by parsing and regurgitating a .newsrc file for a particular server. * providers/nntp/camel-nntp-newsrc.c, providers/nntp/camel-nntp-newsrc.h: new files, initial support for .newsrc files. svn path=/trunk/; revision=3702
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/nntp/.cvsignore1
-rw-r--r--camel/providers/nntp/Makefile.am15
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c666
-rw-r--r--camel/providers/nntp/camel-nntp-folder.h1
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c461
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.h27
-rw-r--r--camel/providers/nntp/camel-nntp-store.c91
-rw-r--r--camel/providers/nntp/camel-nntp-store.h3
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c37
-rw-r--r--camel/providers/nntp/test-newsrc.c10
10 files changed, 840 insertions, 472 deletions
diff --git a/camel/providers/nntp/.cvsignore b/camel/providers/nntp/.cvsignore
index fd6b811c68..1f5b9d35fb 100644
--- a/camel/providers/nntp/.cvsignore
+++ b/camel/providers/nntp/.cvsignore
@@ -5,3 +5,4 @@ Makefile.in
.deps
*.lo
*.la
+test-newsrc
diff --git a/camel/providers/nntp/Makefile.am b/camel/providers/nntp/Makefile.am
index 48f85e836d..a205f5bb83 100644
--- a/camel/providers/nntp/Makefile.am
+++ b/camel/providers/nntp/Makefile.am
@@ -17,15 +17,28 @@ INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir) \
libcamelnntp_la_SOURCES = \
camel-nntp-folder.c \
+ camel-nntp-newsrc.c \
camel-nntp-provider.c \
camel-nntp-store.c \
camel-nntp-utils.c
libcamelnntpinclude_HEADERS = \
camel-nntp-folder.h \
+ camel-nntp-newsrc.h \
camel-nntp-store.h
-
libcamelnntp_la_LDFLAGS = -version-info 0:0:0
EXTRA_DIST = libcamelnntp.urls
+
+noinst_PROGRAMS = test-newsrc
+
+LDADD = \
+ $(top_builddir)/camel/libcamel.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/libibex/libibex.la \
+ $(GNOME_LIBDIR) \
+ $(GNOMEUI_LIBS) $(INTLLIBS) $(EXTRA_GNOME_LIBS)
+# $(BONOBO_LIBS)
+
+test_newsrc_LDADD = libcamelnntp.la $(LDADD)
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 8bc623add7..a3cfc49d26 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -57,163 +57,39 @@ static CamelFolderClass *parent_class=NULL;
#define CNNTPS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass)
-static void _init (CamelFolder *folder, CamelStore *parent_store,
- CamelFolder *parent_folder, const gchar *name,
- gchar separator, CamelException *ex);
-
-static void _open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex);
-static void _close (CamelFolder *folder, gboolean expunge, CamelException *ex);
-static gboolean _exists (CamelFolder *folder, CamelException *ex);
-static gboolean _create(CamelFolder *folder, CamelException *ex);
-static gboolean _delete (CamelFolder *folder, gboolean recurse, CamelException *ex);
-static gboolean _delete_messages (CamelFolder *folder, CamelException *ex);
-static GList *_list_subfolders (CamelFolder *folder, CamelException *ex);
-static CamelMimeMessage *_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex);
-static gint _get_message_count (CamelFolder *folder, CamelException *ex);
-static void _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex);
-static GPtrArray *_get_uid_array (CamelFolder *folder, CamelException *ex);
-static CamelMimeMessage *_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex);
-#if 0
-static void _expunge (CamelFolder *folder, CamelException *ex);
-static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, CamelFolder *dest_folder, CamelException *ex);
-#endif
-static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex);
-
-static void _finalize (GtkObject *object);
-
-static void
-camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class)
-{
- CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_nntp_folder_class);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_folder_class);
-
- parent_class = gtk_type_class (camel_folder_get_type ());
-
- /* virtual method definition */
-
- /* virtual method overload */
- camel_folder_class->init = _init;
- camel_folder_class->open = _open;
- camel_folder_class->close = _close;
- camel_folder_class->exists = _exists;
- camel_folder_class->create = _create;
- camel_folder_class->delete = _delete;
- camel_folder_class->delete_messages = _delete_messages;
- camel_folder_class->list_subfolders = _list_subfolders;
- camel_folder_class->get_message_count = _get_message_count;
- camel_folder_class->get_uid_array = _get_uid_array;
- camel_folder_class->get_message_by_uid = _get_message_by_uid;
-#if 0
- camel_folder_class->append_message = _append_message;
- camel_folder_class->expunge = _expunge;
- camel_folder_class->copy_message_to = _copy_message_to;
- camel_folder_class->get_message_uid = _get_message_uid;
-#endif
-
- gtk_object_class->finalize = _finalize;
-
-}
-
-static void
-_finalize (GtkObject *object)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (object);
-
- g_free (nntp_folder->summary_file_path);
-
- GTK_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-GtkType
-camel_nntp_folder_get_type (void)
-{
- static GtkType camel_nntp_folder_type = 0;
-
- if (!camel_nntp_folder_type) {
- GtkTypeInfo camel_nntp_folder_info =
- {
- "CamelNNTPFolder",
- sizeof (CamelNNTPFolder),
- sizeof (CamelNNTPFolderClass),
- (GtkClassInitFunc) camel_nntp_folder_class_init,
- (GtkObjectInitFunc) NULL,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- camel_nntp_folder_type = gtk_type_unique (CAMEL_FOLDER_TYPE, &camel_nntp_folder_info);
- }
-
- return camel_nntp_folder_type;
-}
+static void _check_get_or_maybe_generate_summary_file (CamelNNTPFolder *nntp_folder,
+ CamelException *ex);
static void
-_init (CamelFolder *folder, CamelStore *parent_store,
- CamelFolder *parent_folder, const gchar *name, gchar separator,
- CamelException *ex)
+nntp_folder_init (CamelFolder *folder, CamelStore *parent_store,
+ CamelFolder *parent_folder, const gchar *name,
+ gchar *separator, gboolean path_begins_with_sep,
+ CamelException *ex)
{
+ const gchar *root_dir_path;
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+
/* call parent method */
parent_class->init (folder, parent_store, parent_folder,
- name, separator, ex);
+ name, separator, path_begins_with_sep,
+ ex);
if (camel_exception_get_id (ex)) return;
- /* we assume that the parent init
- method checks for the existance of @folder */
-
- if (!strcmp(name, "/"))
- {
- folder->has_summary_capability = FALSE;
- folder->can_hold_messages = FALSE;
- folder->can_hold_folders = TRUE;
- }
- else
- {
- folder->has_summary_capability = TRUE;
- folder->can_hold_messages = TRUE;
- folder->can_hold_folders = TRUE;
- }
-
- folder->has_uid_capability = TRUE;
- folder->has_search_capability = FALSE;
-}
-
-/* internal method used to :
- - test for the existence of a summary file
- - test the sync between the summary and the newsgroup
- - load the summary or create it if necessary
-*/
-static void
-_check_get_or_maybe_generate_summary_file (CamelNNTPFolder *nntp_folder,
- CamelException *ex)
-{
- CamelFolder *folder = CAMEL_FOLDER (nntp_folder);
-
- nntp_folder->summary = camel_folder_summary_new ();
- camel_folder_summary_set_filename (nntp_folder->summary, nntp_folder->summary_file_path);
+ /* set flags */
- if (-1 == camel_folder_summary_load (nntp_folder->summary)) {
- /* Bad or nonexistant summary file */
- camel_nntp_get_headers (CAMEL_FOLDER( folder )->parent_store, nntp_folder, ex);
- if (camel_exception_get_id (ex))
- return;
-
- /* XXX check return value */
- camel_folder_summary_save (nntp_folder->summary);
+ if (!strcmp (name, "/")) {
+ /* the root folder is the only folder that has "subfolders" */
+ folder->can_hold_folders = TRUE;
+ folder->can_hold_messages = FALSE;
+ }
+ else {
+ folder->can_hold_folders = FALSE;
+ folder->can_hold_messages = TRUE;
+ folder->has_summary_capability = TRUE;
}
-}
-
-
-static void
-_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- const gchar *root_dir_path;
- /* call parent class */
- parent_class->open (folder, mode, ex);
- if (camel_exception_get_id(ex))
- return;
+ /* XX */
+ nntp_folder->group_name = g_strdup (strrchr (name, '/') + 1);
#if 0
/* get (or create) uid list */
@@ -223,135 +99,43 @@ _open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex)
root_dir_path = camel_nntp_store_get_toplevel_dir (CAMEL_NNTP_STORE(folder->parent_store));
- nntp_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", root_dir_path, folder->name);
-
- _check_get_or_maybe_generate_summary_file (nntp_folder, ex);
+ nntp_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary",
+ root_dir_path, nntp_folder->group_name);
}
-
static void
-_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
-{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- CamelFolderSummary *summary = nntp_folder->summary;
-
- /* call parent implementation */
- parent_class->close (folder, expunge, ex);
-
- /* XXX only if dirty? */
- camel_folder_summary_save (summary);
-}
-
-static gboolean
-_exists (CamelFolder *folder, CamelException *ex)
-{
-#if 0
- CamelNNTPFolder *nntp_folder;
- struct stat stat_buf;
- gint stat_error;
- gboolean exists;
-
- g_assert(folder != NULL);
-
- nntp_folder = CAMEL_NNTP_FOLDER (folder);
-
- /* check if the nntp summary path is determined */
- if (!nntp_folder->summary_file_path) {
- camel_exception_set (ex,
- CAMEL_EXCEPTION_FOLDER_INVALID,
- "undetermined folder summary path. Maybe use set_name ?");
- return FALSE;
- }
-
- /* check if the nntp file exists */
- stat_error = stat (nntp_folder->summary_file_path, &stat_buf);
- if (stat_error == -1)
- return FALSE;
-
- exists = S_ISREG (stat_buf.st_mode);
- /* we should check the rights here */
-
- return exists;
-#endif
- return TRUE;
-}
-
-static gboolean
-_create (CamelFolder *folder, CamelException *ex)
+nntp_folder_sync (CamelFolder *folder, gboolean expunge,
+ CamelException *ex)
{
-#if 0
- CamelNNTPSummary *summary;
- g_assert(folder != NULL);
-
- /* call default implementation */
- parent_class->create (folder, ex);
-
- /* create the summary object */
- summary = CAMEL_NNTP_SUMMARY (gtk_object_new (camel_nntp_summary_get_type (), NULL));
- summary->nb_message = 0;
- summary->next_uid = 1;
- summary->nntp_file_size = 0;
- summary->message_info = g_array_new (FALSE, FALSE, sizeof (CamelNNTPSummaryInformation));
-#endif
-
- return TRUE;
+ camel_folder_summary_save (CAMEL_NNTP_FOLDER(folder)->summary);
}
-static gboolean
-_delete (CamelFolder *folder, gboolean recurse, CamelException *ex)
+static const gchar *
+nntp_folder_get_name (CamelFolder *folder)
{
-#if 0
- gboolean folder_already_exists;
-
- g_assert(folder != NULL);
-
- /* check if the folder object exists */
-
- /* in the case where the folder does not exist,
- return immediatly */
- folder_already_exists = camel_folder_exists (folder, ex);
- if (camel_exception_get_id (ex))
- return FALSE;
-
- if (!folder_already_exists)
- return TRUE;
-
-
- /* call default implementation.
- It should delete the messages in the folder
- and recurse the operation to subfolders */
- parent_class->delete (folder, recurse, ex);
-#endif
- return TRUE;
+ g_assert(0);
+ return NULL;
}
-gboolean
-_delete_messages (CamelFolder *folder, CamelException *ex)
+static const gchar *
+nntp_folder_get_full_name (CamelFolder *folder)
{
-
- gboolean folder_already_exists;
-
- g_assert(folder!=NULL);
-
- /* in the case where the folder does not exist,
- return immediatly */
- folder_already_exists = camel_folder_exists (folder, ex);
- if (camel_exception_get_id (ex)) return FALSE;
-
- if (!folder_already_exists) return TRUE;
-
- return TRUE;
+ g_assert(0);
+ return NULL;
}
-static GList *
-_list_subfolders (CamelFolder *folder, CamelException *ex)
+static CamelFolder*
+nntp_folder_get_subfolder (CamelFolder *folder,
+ const gchar *folder_name,
+ gboolean create,
+ CamelException *ex)
{
- /* newsgroups don't have subfolders */
+ g_assert (0);
return NULL;
}
static gint
-_get_message_count (CamelFolder *folder, CamelException *ex)
+nntp_folder_get_message_count (CamelFolder *folder, CamelException *ex)
{
CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER(folder);
@@ -361,155 +145,50 @@ _get_message_count (CamelFolder *folder, CamelException *ex)
return camel_folder_summary_count(nntp_folder->summary);
}
-#if 0
-static void
-_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex)
+static guint32
+nntp_folder_get_message_flags (CamelFolder *folder, const char *uid, CamelException *ex)
{
CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
-#if 0
- CamelNNTPSummary *summary = CAMEL_NNTP_SUMMARY (folder->summary);
-#endif
- CamelStream *output_stream;
- guint32 tmp_file_size;
- guint32 next_uid;
- gint tmp_file_fd;
- GArray *message_info_array;
-#if 0
- GArray *nntp_summary_info;
-#endif
- gchar *tmp_message_filename;
- gint fd1, fd2;
- int i;
-
- /* write the message itself */
- output_stream = camel_stream_fs_new_with_name (tmp_message_filename,
- CAMEL_STREAM_FS_WRITE);
- if (output_stream != NULL) {
- camel_stream_write_string (output_stream, "From - \n");
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream);
- }
- camel_stream_flush (output_stream);
- gtk_object_unref (GTK_OBJECT (output_stream));
-
- /* at this point we have saved the message to a
- temporary file, now, we have to add the x-evolution
- field and also update the main summary */
-
- /*
- First : parse the nntp file, but only from the
- position where the message has been added,
- wich happens to be the last postion in the
- nntp file before we added the message.
- This position is still stored in the summary
- for the moment
- */
- next_uid = summary->next_uid;
- tmp_file_fd = open (tmp_message_filename, O_RDONLY);
- message_info_array =
- camel_nntp_parse_file (tmp_file_fd, "From - ", 0,
- &tmp_file_size, &next_uid, TRUE,
- NULL, 0, ex);
-
- close (tmp_file_fd);
-
- /* get the value of the last available UID
- as saved in the summary file, again */
- next_uid = summary->next_uid;
-
- /* make sure all our of message info's have 0 uid - ignore any
- set elsewhere */
- for (i=0;i<message_info_array->len;i++) {
- g_array_index(message_info_array, CamelNNTPParserMessageInfo, i).uid = 0;
- }
-
- /*
- OK, this is not very efficient, we should not use the same
- method as for parsing an entire mail file,
- but I have no time to write a simpler parser
- */
-#if 0
- next_uid = camel_nntp_write_xev (nntp_folder, tmp_message_filename,
- message_info_array, &tmp_file_size, next_uid, ex);
-
-#endif
- if (camel_exception_get_id (ex)) {
- /* ** FIXME : free the preparsed information */
- return;
- }
+ CamelMessageInfo *info = camel_folder_summary_uid (nntp_folder->summary, uid);
-#if 0
- nntp_summary_info =
- parsed_information_to_nntp_summary (message_info_array);
-#endif
-
- /* store the number of messages as well as the summary array */
- summary->nb_message += 1;
- summary->next_uid = next_uid;
+ return info->flags;
+}
- ((CamelNNTPSummaryInformation *)(nntp_summary_info->data))->position +=
- summary->nntp_file_size;
- summary->nntp_file_size += tmp_file_size;
+static void
+nntp_folder_set_message_flags (CamelFolder *folder, const char *uid,
+ guint32 flags, guint32 set, CamelException *ex)
+{
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+ CamelMessageInfo *info = camel_folder_summary_uid (nntp_folder->summary, uid);
- camel_nntp_summary_append_entries (summary, nntp_summary_info);
- g_array_free (nntp_summary_info, TRUE);
-
+ info->flags = set;
- /* append the temporary file message to the nntp file */
- fd1 = open (tmp_message_filename, O_RDONLY);
- fd2 = open (nntp_folder->folder_file_path,
- O_WRONLY | O_CREAT | O_APPEND,
- 0600);
+ camel_folder_summary_touch (nntp_folder->summary);
+ if (set & CAMEL_MESSAGE_SEEN) {
+ CamelNNTPStore *store;
+ CamelException *ex;
+
+ ex = camel_exception_new ();
+ store = CAMEL_NNTP_STORE (camel_folder_get_parent_store (folder, ex));
+ camel_exception_free (ex);
- if (fd2 == -1) {
- camel_exception_setv (ex,
- CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
- "could not open the nntp folder file for appending the message\n"
- "\t%s\n"
- "Full error is : %s\n",
- nntp_folder->folder_file_path,
- strerror (errno));
- return;
+ camel_nntp_newsrc_mark_article_read (store->newsrc,
+ nntp_folder->group_name,
+ 1 /* XXX */);
}
-
- camel_nntp_copy_file_chunk (fd1,
- fd2,
- tmp_file_size,
- ex);
- close (fd1);
- close (fd2);
-
- /* remove the temporary file */
- unlink (tmp_message_filename);
-
- g_free (tmp_message_filename);
}
-#endif
-
-
-static GPtrArray *
-_get_uid_array (CamelFolder *folder, CamelException *ex)
+static const gchar*
+nntp_folder_get_message_uid (CamelFolder *folder,
+ CamelMimeMessage *message,
+ CamelException *ex)
{
- CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- GPtrArray *message_info_array, *out;
- CamelMessageInfo *message_info;
- int i;
-
- message_info_array = nntp_folder->summary->messages;
-
- out = g_ptr_array_new ();
- g_ptr_array_set_size (out, message_info_array->len);
-
- for (i=0; i<message_info_array->len; i++) {
- message_info = (CamelMessageInfo *)(message_info_array->pdata) + i;
- out->pdata[i] = g_strdup (message_info->uid);
- }
-
- return out;
+ g_assert (0);
+ return NULL;
}
static CamelMimeMessage *
-_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
+nntp_folder_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
CamelStream *nntp_istream;
CamelStream *message_stream;
@@ -550,7 +229,7 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
buf[0] = 0;
while (!done) {
- char *line = camel_stream_buffer_read_line ( CAMEL_STREAM_BUFFER ( nntp_istream ), ex);
+ char *line = camel_stream_buffer_read_line ( CAMEL_STREAM_BUFFER ( nntp_istream ));
int line_length;
/* XXX check exception */
@@ -589,9 +268,7 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
gtk_object_unref ((GtkObject *)message_stream);
/* init other fields? */
- message->folder = folder;
gtk_object_ref((GtkObject *)folder);
- message->message_uid = g_strdup(uid);
#if 0
gtk_signal_connect((GtkObject *)message, "message_changed", message_changed, folder);
@@ -600,18 +277,193 @@ _get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
return message;
}
-/* get message info for a range of messages */
+static void
+nntp_folder_delete_message_by_uid (CamelFolder *folder,
+ const gchar *uid,
+ CamelException *ex)
+{
+ g_assert (0);
+}
+
+static GPtrArray *
+nntp_folder_get_uids (CamelFolder *folder,
+ CamelException *ex)
+{
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+ GPtrArray *message_info_array, *out;
+ CamelMessageInfo *message_info;
+ int i;
+
+ message_info_array = nntp_folder->summary->messages;
+
+ out = g_ptr_array_new ();
+ g_ptr_array_set_size (out, message_info_array->len);
+
+ for (i=0; i<message_info_array->len; i++) {
+ message_info = (CamelMessageInfo *)(message_info_array->pdata) + i;
+ out->pdata[i] = g_strdup (message_info->uid);
+ }
+
+ return out;
+}
+
+static void
+nntp_folder_free_uids (CamelFolder *folder,
+ GPtrArray *array)
+{
+ int i;
+ for (i = 0; i < array->len; i ++) {
+ g_free (g_ptr_array_index (array, i));
+ }
+ g_ptr_array_free (array, TRUE /* XXX? */);
+}
+
+static GPtrArray *
+nntp_folder_get_summary (CamelFolder *folder,
+ CamelException *ex)
+{
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+ _check_get_or_maybe_generate_summary_file (nntp_folder, ex);
+
+ return nntp_folder->summary->messages;
+}
+
+static void
+nntp_folder_free_summary (CamelFolder *folder,
+ GPtrArray *summary)
+{
+ g_assert (0);
+}
+
static GPtrArray *
-summary_get_message_info (CamelFolder *folder, int first, int count)
+nntp_folder_get_subfolder_names (CamelFolder *folder, CamelException *ex)
+{
+ if (!strcmp (folder->name, "/")) {
+ CamelStore *store = camel_folder_get_parent_store (folder, ex);
+ GPtrArray *array = camel_nntp_newsrc_get_subscribed_group_names (CAMEL_NNTP_STORE (store)->newsrc);
+ return array;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static void
+nntp_folder_free_subfolder_names (CamelFolder *folder, GPtrArray *subfolders)
+{
+ if (subfolders) {
+ CamelException *ex = camel_exception_new ();
+ CamelStore *store = camel_folder_get_parent_store (folder, ex);
+ camel_nntp_newsrc_free_group_names (CAMEL_NNTP_STORE (store)->newsrc, subfolders);
+ camel_exception_free (ex);
+ }
+}
+
+static GList*
+nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
{
- GPtrArray *array = g_ptr_array_new();
- int i, maxcount;
- CamelNNTPFolder *nntp_folder = (CamelNNTPFolder *)folder;
+ g_assert (0);
+ return NULL;
+}
+
+static const CamelMessageInfo*
+nntp_folder_summary_get_by_uid (CamelFolder *folder, const char *uid)
+{
+ g_assert(0);
+ return NULL;
+}
+
+static void
+nntp_folder_finalize (GtkObject *object)
+{
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (object);
+
+ g_free (nntp_folder->summary_file_path);
+
+ GTK_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class)
+{
+ CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_nntp_folder_class);
+ GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_folder_class);
+
+ parent_class = gtk_type_class (camel_folder_get_type ());
+
+ /* virtual method definition */
+
+ /* virtual method overload */
+ camel_folder_class->init = nntp_folder_init;
+ camel_folder_class->sync = nntp_folder_sync;
+ camel_folder_class->get_name = nntp_folder_get_name;
+ camel_folder_class->get_full_name = nntp_folder_get_full_name;
+ camel_folder_class->get_subfolder = nntp_folder_get_subfolder;
+ camel_folder_class->get_message_count = nntp_folder_get_message_count;
+ camel_folder_class->set_message_flags = nntp_folder_set_message_flags;
+ camel_folder_class->get_message_flags = nntp_folder_get_message_flags;
+ camel_folder_class->get_message_uid = nntp_folder_get_message_uid;
+ camel_folder_class->get_message_by_uid = nntp_folder_get_message_by_uid;
+ camel_folder_class->delete_message_by_uid = nntp_folder_delete_message_by_uid;
+ camel_folder_class->get_uids = nntp_folder_get_uids;
+ camel_folder_class->free_uids = nntp_folder_free_uids;
+ camel_folder_class->get_summary = nntp_folder_get_summary;
+ camel_folder_class->free_summary = nntp_folder_free_summary;
+ camel_folder_class->get_subfolder_names = nntp_folder_get_subfolder_names;
+ camel_folder_class->free_subfolder_names = nntp_folder_free_subfolder_names;
+ camel_folder_class->search_by_expression = nntp_folder_search_by_expression;
+ camel_folder_class->summary_get_by_uid = nntp_folder_summary_get_by_uid;
+
+ gtk_object_class->finalize = nntp_folder_finalize;
+
+}
+
+GtkType
+camel_nntp_folder_get_type (void)
+{
+ static GtkType camel_nntp_folder_type = 0;
+
+ if (!camel_nntp_folder_type) {
+ GtkTypeInfo camel_nntp_folder_info =
+ {
+ "CamelNNTPFolder",
+ sizeof (CamelNNTPFolder),
+ sizeof (CamelNNTPFolderClass),
+ (GtkClassInitFunc) camel_nntp_folder_class_init,
+ (GtkObjectInitFunc) NULL,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ camel_nntp_folder_type = gtk_type_unique (CAMEL_FOLDER_TYPE, &camel_nntp_folder_info);
+ }
+
+ return camel_nntp_folder_type;
+}
+
+
+/* internal method used to :
+ - test for the existence of a summary file
+ - test the sync between the summary and the newsgroup
+ - load the summary or create it if necessary
+*/
+static void
+_check_get_or_maybe_generate_summary_file (CamelNNTPFolder *nntp_folder,
+ CamelException *ex)
+{
+ CamelFolder *folder = CAMEL_FOLDER (nntp_folder);
- maxcount = camel_folder_summary_count(nntp_folder->summary);
- maxcount = MIN(first + count, maxcount);
- for (i=first;i<maxcount;i++)
- g_ptr_array_add(array, g_ptr_array_index(nntp_folder->summary->messages, i));
+ nntp_folder->summary = camel_folder_summary_new ();
+ camel_folder_summary_set_filename (nntp_folder->summary, nntp_folder->summary_file_path);
- return array;
+ if (-1 == camel_folder_summary_load (nntp_folder->summary)) {
+ /* Bad or nonexistant summary file */
+ camel_nntp_get_headers (CAMEL_FOLDER( folder )->parent_store, nntp_folder, ex);
+ if (camel_exception_get_id (ex))
+ return;
+
+ /* XXX check return value */
+ camel_folder_summary_save (nntp_folder->summary);
+ }
}
diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h
index 7a445d697f..f6c04bb005 100644
--- a/camel/providers/nntp/camel-nntp-folder.h
+++ b/camel/providers/nntp/camel-nntp-folder.h
@@ -47,6 +47,7 @@ extern "C" {
typedef struct {
CamelFolder parent_object;
+ gchar *group_name;
gchar *summary_file_path; /* contains the messages summary */
CamelFolderSummary *summary;
} CamelNNTPFolder;
diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c
new file mode 100644
index 0000000000..fc0f4c2a1a
--- /dev/null
+++ b/camel/providers/nntp/camel-nntp-newsrc.c
@@ -0,0 +1,461 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* camel-nntp-newsrc.c - .newsrc parsing/regurgitating code */
+/*
+ *
+ * Copyright (C) 2000 Helix Code, Inc. <toshok@helixcode.com>
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include "camel-nntp-newsrc.h"
+
+typedef struct {
+ guint low;
+ guint high;
+} ArticleRange;
+
+typedef struct {
+ char *name;
+ GArray *ranges;
+ gboolean subscribed;
+} NewsrcGroup;
+
+struct CamelNNTPNewsrc {
+ gchar *filename;
+ GHashTable *groups;
+ GHashTable *subscribed_groups;
+ gboolean dirty;
+} ;
+
+static NewsrcGroup *
+camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, char *group_name, gboolean subscribed)
+{
+ NewsrcGroup *new_group = g_malloc(sizeof(NewsrcGroup));
+
+ new_group->name = g_strdup(group_name);
+ new_group->subscribed = subscribed;
+ new_group->ranges = g_array_new (FALSE, FALSE, sizeof (ArticleRange));
+
+ g_hash_table_insert (newsrc->groups, new_group->name, new_group);
+ if (subscribed)
+ g_hash_table_insert (newsrc->subscribed_groups, new_group->name, new_group);
+
+ newsrc->dirty = TRUE;
+
+ return new_group;
+}
+
+static long
+camel_nntp_newsrc_group_get_highest_article_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group)
+{
+ if (group->ranges->len == 0)
+ return 0;
+
+ return g_array_index(group->ranges, ArticleRange, group->ranges->len - 1).high;
+}
+
+static void
+camel_nntp_newsrc_group_mark_range_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *group, long low, long high)
+{
+ int i;
+
+ if (group->ranges->len == 1
+ && g_array_index (group->ranges, ArticleRange, 0).low == 0
+ && g_array_index (group->ranges, ArticleRange, 0).high == 0) {
+ g_array_index (group->ranges, ArticleRange, 0).low = low;
+ g_array_index (group->ranges, ArticleRange, 0).high = high;
+
+ newsrc->dirty = TRUE;
+ }
+ else {
+ ArticleRange tmp_range;
+
+ for (i = 0; i < group->ranges->len; i ++) {
+ guint range_low = g_array_index (group->ranges, ArticleRange, i).low;
+ guint range_high = g_array_index (group->ranges, ArticleRange, i).high;
+
+ /* if it's already part of a range, return immediately. */
+ if (low >= range_low &&
+ low <= range_high &&
+ high >= range_low &&
+ high <= range_high) {
+ return;
+ }
+ /* if we have a new lower bound for this range, set it. */
+ else if (low <= range_low
+ && high >= range_low
+ && high <= range_high) {
+ g_array_index (group->ranges, ArticleRange, i).low = low;
+ newsrc->dirty = TRUE;
+ return;
+ }
+ /* if we have a new upper bound for this range, set it. */
+ else if (high >= range_high
+ && low >= range_low
+ && low <= range_high) {
+ g_array_index (group->ranges, ArticleRange, i).high = high;
+ newsrc->dirty = TRUE;
+ return;
+ }
+ /* if we would be inserting another range that
+ starts one index higher than an existing
+ one, make the upper value of the existing
+ range the upper value of the new one. */
+ else if (low == range_high + 1) {
+ g_array_index (group->ranges, ArticleRange, i).high = high;
+ newsrc->dirty = TRUE;
+ return;
+ }
+ /* if we would be inserting another range that
+ ends one index lower than an existing one,
+ group the existing range by setting its low
+ to the new low */
+ else if (high == range_low - 1) {
+ g_array_index (group->ranges, ArticleRange, i).low = low;
+ newsrc->dirty = TRUE;
+ return;
+ }
+ /* if the range lies entirely outside another
+ range, doesn't coincide with it's
+ endpoints, and has lower values, insert it
+ into the middle of the list. */
+ else if (low < range_low
+ && high < range_low) {
+ tmp_range.low = low;
+ tmp_range.high = high;
+
+ group->ranges = g_array_insert_val (group->ranges, i, tmp_range);
+ newsrc->dirty = TRUE;
+
+ return;
+ }
+ }
+
+ /* if we made it here, the range needs to go at the end */
+ tmp_range.low = low;
+ tmp_range.high = high;
+ group->ranges = g_array_append_val (group->ranges, tmp_range);
+ newsrc->dirty = TRUE;
+ }
+}
+
+int
+camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group_name)
+{
+ NewsrcGroup *group;
+
+ group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ return camel_nntp_newsrc_group_get_highest_article_read (newsrc, group);
+}
+
+void
+camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, char *group_name, int num)
+{
+ camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num);
+}
+
+void
+camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, char *group_name, long low, long high)
+{
+ NewsrcGroup *group;
+
+ /* swap them if they're in the wrong order. */
+ if (low > high) {
+ long tmp;
+
+ tmp = high;
+ high = low;
+ low = tmp;
+ }
+
+ group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high);
+}
+
+gboolean
+camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, char *group_name, long num)
+{
+ int i;
+ NewsrcGroup *group;
+
+ group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ for (i = 0; i < group->ranges->len; i++) {
+ if (num >= g_array_index (group->ranges, ArticleRange, i).low &&
+ num <= g_array_index (group->ranges, ArticleRange, i).high) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+struct newsrc_ptr_array {
+ GPtrArray *ptr_array;
+ gboolean subscribed_only;
+};
+
+static void
+get_group_foreach (char *group_name, NewsrcGroup *group, struct newsrc_ptr_array *npa)
+{
+ if (group->subscribed || !npa->subscribed_only) {
+ g_ptr_array_add (npa->ptr_array, group_name);
+ }
+}
+
+GPtrArray *
+camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc)
+{
+ struct newsrc_ptr_array npa;
+
+ npa.ptr_array = g_ptr_array_new();
+ npa.subscribed_only = TRUE;
+
+ g_hash_table_foreach (newsrc->subscribed_groups,
+ (GHFunc)get_group_foreach, &npa);
+
+ return npa.ptr_array;
+}
+
+GPtrArray *
+camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc)
+{
+ struct newsrc_ptr_array npa;
+
+ npa.ptr_array = g_ptr_array_new();
+ npa.subscribed_only = FALSE;
+
+ g_hash_table_foreach (newsrc->groups,
+ (GHFunc)get_group_foreach, &npa);
+
+ return npa.ptr_array;
+}
+
+void
+camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names)
+{
+ g_ptr_array_free (group_names, TRUE);
+}
+
+struct newsrc_fp {
+ CamelNNTPNewsrc *newsrc;
+ FILE *fp;
+};
+
+static void
+camel_nntp_newsrc_write_group_line(gpointer key, NewsrcGroup *group, struct newsrc_fp *newsrc_fp)
+{
+ CamelNNTPNewsrc *newsrc;
+ FILE *fp;
+ int i;
+ int line_length = 0;
+
+ fp = newsrc_fp->fp;
+ newsrc = newsrc_fp->newsrc;
+
+ fprintf (fp, "%s%c", group->name, group->subscribed ? ':' : '!');
+
+ line_length += strlen(group->name) + 1;
+
+ if (group->ranges->len == 1
+ && g_array_index (group->ranges, ArticleRange, 0).low == 0
+ && g_array_index (group->ranges, ArticleRange, 0).high == 0) {
+ fprintf (fp, "\n");
+
+ return; /* special case since our parsing code will insert this
+ bogus range if there were no read articles. The code
+ to add a range is smart enough to remove this one if we
+ ever mark an article read, but we still need to deal with
+ it if that code doesn't get hit. */
+ }
+
+ fprintf (fp, " ");
+ line_length += 1;
+
+ for (i = 0; i < group->ranges->len; i ++) {
+ char range_buffer[100];
+ guint low = g_array_index (group->ranges, ArticleRange, i).low;
+ guint high = g_array_index (group->ranges, ArticleRange, i).high;
+
+ if (low == high)
+ sprintf(range_buffer, "%d", low);
+ else if (low == high - 1)
+ sprintf(range_buffer, "%d,%d", low, high);
+ else
+ sprintf(range_buffer, "%d-%d", low, high);
+
+ if (i != group->ranges->len - 1)
+ strcat(range_buffer, ",");
+
+ /* this constant (991) gives the same line breaking as faried's .newsrc file */
+ if (line_length + strlen(range_buffer) > 991 /*XXX*/) {
+ char range_buffer2[101];
+ int num_to_print = 991 - line_length;
+
+ strcpy(range_buffer2, range_buffer);
+ range_buffer2[num_to_print] = '!';
+ range_buffer2[num_to_print+1] = '\n';
+ range_buffer2[num_to_print+2] = '\0';
+
+ fprintf (fp, range_buffer2);
+
+ fprintf (fp, range_buffer + num_to_print);
+
+ line_length = strlen(range_buffer) - num_to_print;
+ }
+ else {
+ fprintf (fp, range_buffer);
+ line_length += strlen(range_buffer);
+ }
+ }
+
+ fprintf (fp, "\n");
+}
+
+void
+camel_nntp_newsrc_write_to_file(CamelNNTPNewsrc *newsrc, FILE *fp)
+{
+ struct newsrc_fp newsrc_fp;
+
+ newsrc_fp.newsrc = newsrc;
+ newsrc_fp.fp = fp;
+
+ g_hash_table_foreach (newsrc->groups,
+ (GHFunc)camel_nntp_newsrc_write_group_line,
+ &newsrc_fp);
+}
+
+void
+camel_nntp_newsrc_write(CamelNNTPNewsrc *newsrc)
+{
+ FILE *fp;
+
+ if (!newsrc->dirty)
+ return;
+
+ if ((fp = fopen(newsrc->filename, "w")) == NULL) {
+ g_warning ("Couldn't open newsrc file '%s'.\n", newsrc->filename);
+ return;
+ }
+
+ camel_nntp_newsrc_write_to_file(newsrc, fp);
+
+ fclose(fp);
+}
+
+static void
+camel_nntp_newsrc_parse_line(CamelNNTPNewsrc *newsrc, char *line)
+{
+ char *p, sep, *comma, *dash;
+ gboolean is_subscribed;
+ NewsrcGroup *group;
+
+ p = strchr(line, ':');
+
+ if (p) {
+ is_subscribed = TRUE;
+ }
+ else {
+ p = strchr(line, '!');
+ if (p)
+ is_subscribed = FALSE;
+ else
+ return; /* bogus line. */
+ }
+
+ sep = *p;
+ *p = '\0';
+
+ group = camel_nntp_newsrc_group_add (newsrc, line, is_subscribed);
+
+ *p = sep;
+
+ p++;
+
+ do {
+ guint high, low;
+
+ comma = strchr(p, ',');
+
+ if (comma)
+ *comma = '\0';
+
+ dash = strchr(p, '-');
+
+ if (!dash) { /* there wasn't a dash. must be just one number */
+ high = low = atol(p);
+ }
+ else { /* there was a dash. */
+ *dash = '\0';
+ low = atol(p);
+ *dash = '-';
+ p = dash + 1;
+ high = atol(p);
+ }
+
+ camel_nntp_newsrc_group_mark_range_read (newsrc, group, low, high);
+
+ if (comma) {
+ *comma = ',';
+ p = comma + 1;
+ }
+
+ } while(comma);
+}
+
+#define MAX_LINE_LENGTH 1500
+#define BUFFER_LENGTH (20 * MAX_LINE_LENGTH)
+
+CamelNNTPNewsrc *
+camel_nntp_newsrc_read_for_server (const char *server)
+{
+ FILE *fp;
+ char buf[BUFFER_LENGTH];
+ CamelNNTPNewsrc *newsrc = g_new0(CamelNNTPNewsrc, 1);
+
+ newsrc->filename = g_strdup_printf ("%s/.newsrc-%s", g_get_home_dir(), server);
+ newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal);
+ newsrc->subscribed_groups = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if ((fp = fopen(newsrc->filename, "r")) == NULL) {
+ g_free (newsrc->filename);
+ g_free (newsrc);
+ return NULL;
+ }
+
+ while (fgets(buf, MAX_LINE_LENGTH, fp) != NULL) {
+ /* we silently ignore (and lose!) lines longer than 20 * 1500 chars.
+ Too bad for them. */
+ while(strlen(buf) < sizeof(buf)
+ && buf[strlen(buf) - 2] == '!') {
+ fgets(&buf[strlen(buf) - 2], MAX_LINE_LENGTH, fp);
+ }
+
+ camel_nntp_newsrc_parse_line(newsrc, buf);
+ }
+
+ fclose(fp);
+
+ return newsrc;
+}
diff --git a/camel/providers/nntp/camel-nntp-newsrc.h b/camel/providers/nntp/camel-nntp-newsrc.h
new file mode 100644
index 0000000000..3f4be6de8d
--- /dev/null
+++ b/camel/providers/nntp/camel-nntp-newsrc.h
@@ -0,0 +1,27 @@
+
+#ifndef _CAMEL_NNTP_NEWSRC_H_
+#define _CAMEL_NNTP_NEWSRC_H_
+
+#include <stdio.h>
+#include "glib.h"
+
+typedef struct CamelNNTPNewsrc CamelNNTPNewsrc;
+
+int camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group_name);
+void camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc,
+ char *group_name, int num);
+void camel_nntp_newsrc_mark_range_read (CamelNNTPNewsrc *newsrc,
+ char *group_name, long low, long high);
+
+gboolean camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc,
+ char *group_name, long num);
+
+GPtrArray *camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc);
+GPtrArray *camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc);
+void camel_nntp_newsrc_free_group_names (CamelNNTPNewsrc *newsrc, GPtrArray *group_names);
+
+void camel_nntp_newsrc_write_to_file (CamelNNTPNewsrc *newsrc, FILE *fp);
+void camel_nntp_newsrc_write (CamelNNTPNewsrc *newsrc);
+CamelNNTPNewsrc *camel_nntp_newsrc_read_for_server (const char *server);
+
+#endif /* _CAMEL_NNTP_NEWSRC_H_ */
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index 2a0084eee2..765cd8796b 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -55,13 +55,48 @@ static CamelServiceClass *service_class = NULL;
#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass)
#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (GTK_OBJECT(so)->klass)
-static CamelFolder *_get_folder (CamelStore *store, const gchar *folder_name, CamelException *ex);
-static char *_get_folder_name (CamelStore *store, const char *folder_name,
- CamelException *ex);
-
static gboolean nntp_connect (CamelService *service, CamelException *ex);
static gboolean nntp_disconnect (CamelService *service, CamelException *ex);
+
+static CamelFolder *
+nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
+ gboolean get_folder, CamelException *ex)
+{
+ CamelNNTPFolder *new_nntp_folder;
+ CamelFolder *new_folder;
+ CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+ /* if we haven't already read our .newsrc, read it now */
+ if (!nntp_store->newsrc)
+ nntp_store->newsrc = camel_nntp_newsrc_read_for_server (CAMEL_SERVICE(store)->url->host);
+
+ /* check if folder has already been created */
+ /* call the standard routine for that when */
+ /* it is done ... */
+
+ new_nntp_folder = gtk_type_new (CAMEL_NNTP_FOLDER_TYPE);
+ new_folder = CAMEL_FOLDER (new_nntp_folder);
+
+ /* XXX We shouldn't be passing NULL here, but it's equivalent to
+ * what was there before, and there's no
+ * CamelNNTPFolder::get_subfolder yet anyway...
+ */
+ CF_CLASS (new_folder)->init (new_folder, store, NULL,
+ folder_name, ".", FALSE, ex);
+
+ return new_folder;
+}
+
+
+static char *
+nntp_store_get_folder_name (CamelStore *store, const char *folder_name,
+ CamelException *ex)
+{
+ return g_strdup (folder_name);
+}
+
+
static void
camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
{
@@ -70,8 +105,8 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
service_class = gtk_type_class (camel_service_get_type ());
/* virtual method overload */
- camel_store_class->get_folder = _get_folder;
- camel_store_class->get_folder_name = _get_folder_name;
+ camel_store_class->get_folder = nntp_store_get_folder;
+ camel_store_class->get_folder_name = nntp_store_get_folder_name;
}
@@ -108,37 +143,6 @@ camel_nntp_store_get_type (void)
return camel_nntp_store_type;
}
-static CamelFolder *
-_get_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
-{
- CamelNNTPFolder *new_nntp_folder;
- CamelFolder *new_folder;
-
- /* check if folder has already been created */
- /* call the standard routine for that when */
- /* it is done ... */
-
- new_nntp_folder = gtk_type_new (CAMEL_NNTP_FOLDER_TYPE);
- new_folder = CAMEL_FOLDER (new_nntp_folder);
-
- /* XXX We shouldn't be passing NULL here, but it's equivalent to
- * what was there before, and there's no
- * CamelNNTPFolder::get_subfolder yet anyway...
- */
- CF_CLASS (new_folder)->init (new_folder, store, NULL,
- folder_name, '/', ex);
-
- return new_folder;
-}
-
-
-static char *
-_get_folder_name (CamelStore *store, const char *folder_name,
- CamelException *ex)
-{
- return g_strdup (folder_name);
-}
-
/**
* camel_nntp_store_open: Connect to the server if we are currently
* disconnected.
@@ -206,7 +210,7 @@ nntp_connect (CamelService *service, CamelException *ex)
CAMEL_STREAM_BUFFER_READ);
/* Read the greeting */
- buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream), ex /* XX check this */);
+ buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
if (!buf) {
return -1;
}
@@ -286,12 +290,12 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...)
}
/* Send the command */
- camel_stream_write (store->ostream, cmdbuf, strlen (cmdbuf), ex /* XXX */);
+ camel_stream_write (store->ostream, cmdbuf, strlen (cmdbuf));
g_free (cmdbuf);
- camel_stream_write (store->ostream, "\r\n", 2, ex /* XXX */);
+ camel_stream_write (store->ostream, "\r\n", 2);
/* Read the response */
- respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream), ex /* XXX */);
+ respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
resp_code = atoi (respbuf);
if (resp_code < 400)
@@ -333,11 +337,10 @@ camel_nntp_command_get_additional_data (CamelNNTPStore *store)
GPtrArray *data;
char *buf;
int i, status = CAMEL_NNTP_OK;
- CamelException *ex = camel_exception_new();
data = g_ptr_array_new ();
while (1) {
- buf = camel_stream_buffer_read_line (stream, ex /* XXX */);
+ buf = camel_stream_buffer_read_line (stream);
if (!buf) {
status = CAMEL_NNTP_FAIL;
break;
@@ -376,8 +379,6 @@ camel_nntp_store_subscribe_group (CamelStore *store,
char *ret = NULL;
CamelException *ex = camel_exception_new();
- camel_nntp_store_open(CAMEL_NNTP_STORE(store), ex);
-
if (camel_exception_get_id (ex)) {
g_free (root_dir);
camel_exception_free (ex);
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
index 257772d7cb..9d4d6edebc 100644
--- a/camel/providers/nntp/camel-nntp-store.h
+++ b/camel/providers/nntp/camel-nntp-store.h
@@ -33,6 +33,7 @@ extern "C" {
#include <gtk/gtk.h>
#include "camel-store.h"
+#include "camel-nntp-newsrc.h"
#define CAMEL_NNTP_STORE_TYPE (camel_nntp_store_get_type ())
#define CAMEL_NNTP_STORE(obj) (GTK_CHECK_CAST((obj), CAMEL_NNTP_STORE_TYPE, CamelNNTPStore))
@@ -46,6 +47,8 @@ typedef struct {
#define CAMEL_NNTP_EXT_XOVER 0x01
guint32 extensions;
+ CamelNNTPNewsrc *newsrc;
+
CamelStream *istream, *ostream;
} CamelNNTPStore;
diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c
index 7100be0aed..ae1f676cc3 100644
--- a/camel/providers/nntp/camel-nntp-utils.c
+++ b/camel/providers/nntp/camel-nntp-utils.c
@@ -51,8 +51,7 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
while (!done) {
char *line;
- line = camel_stream_buffer_read_line (
- CAMEL_STREAM_BUFFER ( nntp_istream ), ex /* XXX */);
+ line = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER ( nntp_istream ));
if (*line == '.') {
done = TRUE;
@@ -63,9 +62,9 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
new_info->subject = g_strdup(split_line[1]);
new_info->from = g_strdup(split_line[2]);
- new_info->to = g_strdup(folder->name);
+ new_info->to = g_strdup(nntp_folder->group_name);
+ new_info->date_sent = header_decode_date(split_line[3], NULL);
#if 0
- new_info->date_sent = g_strdup(split_line[3]);
/* XXX do we need to fill in both dates? */
new_info->headers.date_received = g_strdup(split_line[3]);
#endif
@@ -87,10 +86,6 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
{
int i;
int status;
- GArray *array;
- CamelMessageInfo info;
-
- array = g_array_new(FALSE, FALSE, sizeof(CamelMessageInfo));
for (i = first_message; i < last_message; i ++) {
status = camel_nntp_command (nntp_store, NULL,
@@ -105,6 +100,7 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
CamelStream *header_stream;
GArray *header_array;
CamelStream *nntp_istream;
+ CamelMessageInfo *new_info = g_new0(CamelMessageInfo, 1);
buf_alloc = 2048;
buf_len = 0;
@@ -150,21 +146,23 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
for (h = 0; h < header_array->len; h ++) {
Rfc822Header *header = &((Rfc822Header*)header_array->data)[h];
if (!g_strcasecmp(header->name, "From"))
- info.from = g_strdup(header->value);
+ new_info->from = g_strdup(header->value);
else if (!g_strcasecmp(header->name, "To"))
- info.to = g_strdup(header->value);
+ new_info->to = g_strdup(header->value);
else if (!g_strcasecmp(header->name, "Subject"))
- info.subject = g_strdup(header->value);
+ new_info->subject = g_strdup(header->value);
else if (!g_strcasecmp(header->name, "Message-ID"))
- info.uid = g_strdup(header->value);
+ new_info->uid = g_strdup(header->value);
else if (!g_strcasecmp(header->name, "Date")) {
+ new_info->date_sent = header_decode_date (header->value);
#if 0
- info.date_sent = g_strdup(header->value);
- info.date_received = g_strdup(header->value);
+ new_info->date_sent = g_strdup(header->value);
+ new_info->date_received = g_strdup(header->value);
#endif
}
}
- g_array_append_val(array, info);
+
+ camel_folder_summary_add (nntp_folder->summary, new_info);
}
else if (status == CAMEL_NNTP_FAIL) {
/* nasty things are afoot */
@@ -172,7 +170,6 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
break;
}
}
- return array;
}
#endif
@@ -188,7 +185,7 @@ camel_nntp_get_headers (CamelStore *store,
int status;
status = camel_nntp_command (nntp_store, &ret,
- "GROUP %s", folder->name);
+ "GROUP %s", CAMEL_NNTP_FOLDER (folder)->group_name);
sscanf (ret, "%d %d %d", &nb_message, &first_message, &last_message);
g_free (ret);
@@ -199,13 +196,15 @@ camel_nntp_get_headers (CamelStore *store,
return;
}
+#if 0
if (nntp_store->extensions & CAMEL_NNTP_EXT_XOVER) {
+#endif
get_XOVER_headers (nntp_store, folder, first_message, last_message, ex);
+#if 0
}
else {
-#if 0
get_HEAD_headers (nntp_store, folder, first_message, last_message, ex);
-#endif
}
+#endif
}
diff --git a/camel/providers/nntp/test-newsrc.c b/camel/providers/nntp/test-newsrc.c
new file mode 100644
index 0000000000..c4b985e565
--- /dev/null
+++ b/camel/providers/nntp/test-newsrc.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <glib.h>
+#include "camel-nntp-newsrc.h"
+
+int
+main(int argc, char *argv[])
+{
+ CamelNNTPNewsrc *newsrc = camel_nntp_newsrc_read_for_server (argv[1]);
+ camel_nntp_newsrc_write_to_file (newsrc, stdout);
+}