aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog32
-rw-r--r--camel/providers/nntp/Makefile.am18
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c109
-rw-r--r--camel/providers/nntp/camel-nntp-store.c259
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c5
5 files changed, 244 insertions, 179 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 8e897990dd..3b00513daa 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,35 @@
+2000-07-12 Chris Toshok <toshok@helixcode.com>
+
+ * providers/nntp/Makefile.am: don't add test-newsrc to the build
+ since it needs libcamel (which isn't built at the time test-newsrc
+ needs linking.)
+
+ * providers/nntp/camel-nntp-utils.c (get_HEAD_headers): fill in
+ MessageInfo->message_id.
+ (get_XOVER_headers): same.
+
+ * providers/nntp/camel-nntp-folder.c (nntp_folder_init): move
+ summary loading here.
+ (nntp_folder_sync): summary/newsrc changes should be stored here.
+ put a comment to that effect.
+ (nntp_folder_set_message_flags): don't save the newsrc here.
+ (nntp_folder_get_uids): use g_ptr_array_index instead of the
+ cast/addition.
+ (nntp_folder_get_summary): no need to check if we should generate
+ the summary here. already done.
+ (nntp_folder_get_message_info): implement.
+
+ * providers/nntp/camel-nntp-store.c
+ (camel_nntp_store_get_toplevel_dir): use evolution_dir instead of
+ computing it ourselves.
+ (nntp_store_disconnect): call camel_nntp_newsrc_write.
+ (ensure_news_dir_exists): new function to create the news/<news
+ server> subdir.
+ (camel_nntp_store_class_init): hook up connect/disconnect and
+ finalize.
+ (nntp_store_connect): if ensure_news_dir_exists fails throw an
+ exception.
+
2000-07-12 Peter Williams <peterw@helixcode.com>
* camel-folder.c (camel_folder_set_message_flags): Emit a message_changed
diff --git a/camel/providers/nntp/Makefile.am b/camel/providers/nntp/Makefile.am
index a205f5bb83..5f96e78615 100644
--- a/camel/providers/nntp/Makefile.am
+++ b/camel/providers/nntp/Makefile.am
@@ -31,14 +31,14 @@ 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)
+#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)
+#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 ae5e371fb1..00e709b20b 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -57,9 +57,6 @@ static CamelFolderClass *parent_class=NULL;
#define CNNTPS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass)
-static void _check_get_or_maybe_generate_summary_file (CamelNNTPFolder *nntp_folder,
- CamelException *ex);
-
static void
nntp_folder_init (CamelFolder *folder, CamelStore *parent_store,
CamelFolder *parent_folder, const gchar *name,
@@ -99,8 +96,30 @@ nntp_folder_init (CamelFolder *folder, CamelStore *parent_store,
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, nntp_folder->group_name);
+
+ /* load the summary if we have that ability */
+ if (folder->has_summary_capability) {
+ nntp_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary",
+ root_dir_path,
+ nntp_folder->group_name);
+
+ nntp_folder->summary = camel_folder_summary_new ();
+ camel_folder_summary_set_filename (nntp_folder->summary,
+ nntp_folder->summary_file_path);
+
+ 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);
+ }
+ }
+
+
}
static void
@@ -108,6 +127,26 @@ nntp_folder_sync (CamelFolder *folder, gboolean expunge,
CamelException *ex)
{
camel_folder_summary_save (CAMEL_NNTP_FOLDER(folder)->summary);
+
+ /* XXX
+
+ loop through the messages in the summary and store out the .newsrc,
+ using something similar to this bit snipped from _set_message_flags:
+
+
+ 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);
+
+ camel_nntp_newsrc_mark_article_read (store->newsrc,
+ nntp_folder->group_name,
+ XXX);
+ }
+ */
}
static const gchar *
@@ -164,18 +203,6 @@ nntp_folder_set_message_flags (CamelFolder *folder, const char *uid,
info->flags = set;
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);
-
- camel_nntp_newsrc_mark_article_read (store->newsrc,
- nntp_folder->group_name,
- 1 /* XXX */);
- }
}
static const gchar*
@@ -290,17 +317,17 @@ nntp_folder_get_uids (CamelFolder *folder,
CamelException *ex)
{
CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
- GPtrArray *message_info_array, *out;
+ GPtrArray *infoarray, *out;
CamelMessageInfo *message_info;
int i;
- message_info_array = nntp_folder->summary->messages;
+ infoarray = nntp_folder->summary->messages;
out = g_ptr_array_new ();
- g_ptr_array_set_size (out, message_info_array->len);
+ g_ptr_array_set_size (out, infoarray->len);
- for (i=0; i<message_info_array->len; i++) {
- message_info = (CamelMessageInfo *)(message_info_array->pdata) + i;
+ for (i=0; i<infoarray->len; i++) {
+ message_info = (CamelMessageInfo *) g_ptr_array_index (infoarray, i);
out->pdata[i] = g_strdup (message_info->uid);
}
@@ -323,7 +350,6 @@ 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;
}
@@ -369,7 +395,16 @@ nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, C
static const CamelMessageInfo*
nntp_folder_get_message_info (CamelFolder *folder, const char *uid)
{
- g_assert(0);
+ CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
+ CamelMessageInfo *info = NULL;
+ int i;
+
+ for (i = 0; i < nntp_folder->summary->messages->len; i++) {
+ info = g_ptr_array_index (nntp_folder->summary->messages, i);
+ if (!strcmp (info->uid, uid))
+ return info;
+ }
+
return NULL;
}
@@ -441,29 +476,3 @@ camel_nntp_folder_get_type (void)
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);
-
- nntp_folder->summary = camel_folder_summary_new ();
- camel_folder_summary_set_filename (nntp_folder->summary, nntp_folder->summary_file_path);
-
- 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-store.c b/camel/providers/nntp/camel-nntp-store.c
index 96d11b4915..a7b8f7df01 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -55,8 +55,98 @@ 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 gboolean nntp_connect (CamelService *service, CamelException *ex);
-static gboolean nntp_disconnect (CamelService *service, CamelException *ex);
+static gboolean ensure_news_dir_exists (CamelNNTPStore *store);
+
+static gboolean
+nntp_store_connect (CamelService *service, CamelException *ex)
+{
+ struct hostent *h;
+ struct sockaddr_in sin;
+ int fd;
+ char *buf;
+ CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
+
+ if (!ensure_news_dir_exists(store)) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not open directory for news server: %s",
+ strerror (errno));
+ return FALSE;
+ }
+
+ if (!service_class->connect (service, ex))
+ return FALSE;
+
+ h = camel_service_gethost (service, ex);
+ if (!h)
+ return FALSE;
+
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = htons (service->url->port ? service->url->port : NNTP_PORT);
+ memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
+
+ fd = socket (h->h_addrtype, SOCK_STREAM, 0);
+ if (fd == -1 ||
+ connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "Could not connect to %s (port %s): %s",
+ service->url->host, service->url->port,
+ strerror(errno));
+ if (fd > -1)
+ close (fd);
+ return FALSE;
+ }
+
+ store->ostream = camel_stream_fs_new_with_fd (fd);
+ store->istream = camel_stream_buffer_new (store->ostream,
+ CAMEL_STREAM_BUFFER_READ);
+
+ /* Read the greeting */
+ buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
+ if (!buf) {
+ return -1;
+ }
+
+ g_free (buf);
+
+ /* get a list of extensions that the server supports */
+ if (CAMEL_NNTP_OK == camel_nntp_command (store, NULL, "LIST EXTENSIONS")) {
+ char *ext_response = camel_nntp_command_get_additional_data(store);
+
+ g_free (ext_response);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+nntp_store_disconnect (CamelService *service, CamelException *ex)
+{
+ CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
+
+ if (!service->connected)
+ return TRUE;
+
+ camel_nntp_command (store, NULL, "QUIT");
+
+ if (store->newsrc)
+ camel_nntp_newsrc_write (store->newsrc);
+
+ if (!service_class->disconnect (service, ex))
+ return FALSE;
+
+ gtk_object_unref (GTK_OBJECT (store->ostream));
+ gtk_object_unref (GTK_OBJECT (store->istream));
+ store->ostream = NULL;
+ store->istream = NULL;
+ return TRUE;
+}
+
+static char *
+nntp_store_get_name (CamelService *service, gboolean brief)
+{
+ /* Same info for long and brief... */
+ return g_strdup_printf ("USENET news via %s", service->url->host);
+}
static CamelFolder *
nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
@@ -68,7 +158,8 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
/* 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);
+ 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 */
@@ -83,11 +174,10 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
*/
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)
@@ -95,23 +185,31 @@ nntp_store_get_folder_name (CamelStore *store, const char *folder_name,
return g_strdup (folder_name);
}
-static char *
-nntp_store_get_name (CamelService *service, gboolean brief)
+static void
+finalize (GtkObject *object)
{
- /* Same info for long and brief... */
- return g_strdup_printf ("USENET news via %s", service->url->host);
-}
+ CamelException ex;
+ camel_exception_init (&ex);
+ nntp_store_disconnect (CAMEL_SERVICE (object), &ex);
+ camel_exception_clear (&ex);
+}
static void
camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
{
+ GtkObjectClass *object_class =
+ GTK_OBJECT_CLASS (camel_nntp_store_class);
CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_nntp_store_class);
CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_nntp_store_class);
service_class = gtk_type_class (camel_service_get_type ());
/* virtual method overload */
+ object_class->finalize = finalize;
+
+ camel_service_class->connect = nntp_store_connect;
+ camel_service_class->disconnect = nntp_store_disconnect;
camel_service_class->get_name = nntp_store_get_name;
camel_store_class->get_folder = nntp_store_get_folder;
@@ -152,107 +250,6 @@ camel_nntp_store_get_type (void)
return camel_nntp_store_type;
}
-/**
- * camel_nntp_store_open: Connect to the server if we are currently
- * disconnected.
- * @store: the store
- * @ex: a CamelException
- *
- **/
-void
-camel_nntp_store_open (CamelNNTPStore *store, CamelException *ex)
-{
- CamelService *service = CAMEL_SERVICE (store);
- if (!camel_service_is_connected (service))
- nntp_connect (service, ex);
-}
-
-/**
- * camel_nntp_store_close: Close the connection to the server
- * @store: the store
- * @ex: a CamelException
- *
- **/
-void
-camel_nntp_store_close (CamelNNTPStore *store, gboolean expunge,
- CamelException *ex)
-{
- camel_nntp_command (store, NULL, "QUIT");
-
- nntp_disconnect (CAMEL_SERVICE (store), ex);
-}
-
-static gboolean
-nntp_connect (CamelService *service, CamelException *ex)
-{
- struct hostent *h;
- struct sockaddr_in sin;
- int fd;
- char *buf;
- CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
-
- if (!service_class->connect (service, ex))
- return FALSE;
-
- h = camel_service_gethost (service, ex);
- if (!h)
- return FALSE;
-
- sin.sin_family = h->h_addrtype;
- sin.sin_port = htons (service->url->port ? service->url->port : NNTP_PORT);
- memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
-
- fd = socket (h->h_addrtype, SOCK_STREAM, 0);
- if (fd == -1 ||
- connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- "Could not connect to %s (port %s): %s",
- service->url->host, service->url->port,
- strerror(errno));
- if (fd > -1)
- close (fd);
- return FALSE;
- }
-
- store->ostream = camel_stream_fs_new_with_fd (fd);
- store->istream = camel_stream_buffer_new (store->ostream,
- CAMEL_STREAM_BUFFER_READ);
-
- /* Read the greeting */
- buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream));
- if (!buf) {
- return -1;
- }
-
- g_free (buf);
-
- /* get a list of extensions that the server supports */
- if (CAMEL_NNTP_OK == camel_nntp_command (store, NULL, "LIST EXTENSIONS")) {
- char *ext_response = camel_nntp_command_get_additional_data(store);
-
- g_free (ext_response);
- }
-
- return TRUE;
-}
-
-static gboolean
-nntp_disconnect (CamelService *service, CamelException *ex)
-{
- CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
-
- if (!service->connected)
- return TRUE;
-
- if (!service_class->disconnect (service, ex))
- return FALSE;
-
- gtk_object_unref (GTK_OBJECT (store->ostream));
- gtk_object_unref (GTK_OBJECT (store->istream));
- store->ostream = NULL;
- store->istream = NULL;
- return TRUE;
-}
/**
* camel_nntp_command: Send a command to a NNTP server.
@@ -291,7 +288,7 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...)
/* make sure we're connected */
if (store->ostream == NULL)
- nntp_connect (CAMEL_SERVICE (store), ex);
+ nntp_store_connect (CAMEL_SERVICE (store), ex);
if (camel_exception_get_id (ex)) {
camel_exception_free (ex);
@@ -479,18 +476,42 @@ gchar *
camel_nntp_store_get_toplevel_dir (CamelNNTPStore *store)
{
CamelURL *url = CAMEL_SERVICE (store)->url;
- char *news_dir;
char *top_dir;
+ extern char *evolution_dir;
g_assert(url != NULL);
- news_dir = gnome_util_prepend_user_home ("evolution/news");
-
- top_dir = g_strdup_printf( "%s/%s",
- news_dir,
+ top_dir = g_strdup_printf( "%s/news/%s",
+ evolution_dir,
url->host );
- g_free (news_dir);
-
return top_dir;
}
+
+static gboolean
+ensure_news_dir_exists (CamelNNTPStore *store)
+{
+ gchar *dir = camel_nntp_store_get_toplevel_dir (store);
+ struct stat sb;
+ int rv;
+
+ rv = stat (dir, &sb);
+ if (-1 == rv && errno != ENOENT) {
+ g_free (dir);
+ return FALSE;
+ }
+
+ if (S_ISDIR (sb.st_mode)) {
+ g_free (dir);
+ return TRUE;
+ }
+ else {
+ rv = mkdir (dir, 0777);
+ g_free (dir);
+
+ if (-1 == rv)
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c
index d4c2cda771..864271cd2c 100644
--- a/camel/providers/nntp/camel-nntp-utils.c
+++ b/camel/providers/nntp/camel-nntp-utils.c
@@ -70,6 +70,7 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
#endif
new_info->size = atoi(split_line[5]);
new_info->uid = g_strdup(split_line[4]);
+ new_info->message_id = g_strdup(split_line[4]);
g_strfreev (split_line);
camel_folder_summary_add (nntp_folder->summary, new_info);
@@ -151,8 +152,10 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder,
new_info->to = g_strdup(header->value);
else if (!g_strcasecmp(header->name, "Subject"))
new_info->subject = g_strdup(header->value);
- else if (!g_strcasecmp(header->name, "Message-ID"))
+ else if (!g_strcasecmp(header->name, "Message-ID")) {
new_info->uid = g_strdup(header->value);
+ new_info->message_id = g_strdup(header->value);
+ }
else if (!g_strcasecmp(header->name, "Date")) {
new_info->date_sent = header_decode_date (header->value);
#if 0