diff options
Diffstat (limited to 'camel/providers/nntp/camel-nntp-folder.c')
-rw-r--r-- | camel/providers/nntp/camel-nntp-folder.c | 617 |
1 files changed, 0 insertions, 617 deletions
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c deleted file mode 100644 index 8bc623add7..0000000000 --- a/camel/providers/nntp/camel-nntp-folder.c +++ /dev/null @@ -1,617 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-nntp-folder.c : Abstract class for an email folder */ - -/* - * Author : Chris Toshok <toshok@helixcode.com> - * - * Copyright (C) 2000 Helix Code . - * - * 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 <stdlib.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#include "camel-folder-summary.h" -#include "camel-nntp-store.h" -#include "camel-nntp-folder.h" -#include "camel-nntp-store.h" -#include "camel-nntp-utils.h" - -#include "string-utils.h" -#include "camel-stream-mem.h" -#include "camel-stream-buffer.h" -#include "camel-data-wrapper.h" -#include "camel-mime-message.h" -#include "camel-folder-summary.h" - -#include "camel-exception.h" - -static CamelFolderClass *parent_class=NULL; - -/* Returns the class for a CamelNNTPFolder */ -#define CNNTPF_CLASS(so) CAMEL_NNTP_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) -#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 -_init (CamelFolder *folder, CamelStore *parent_store, - CamelFolder *parent_folder, const gchar *name, gchar separator, - CamelException *ex) -{ - /* call parent method */ - parent_class->init (folder, parent_store, parent_folder, - name, separator, 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); - - 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 -_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; - -#if 0 - /* get (or create) uid list */ - if (!(nntp_load_uid_list (nntp_folder) > 0)) - nntp_generate_uid_list (nntp_folder); -#endif - - 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); -} - - -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) -{ -#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; -} - -static gboolean -_delete (CamelFolder *folder, gboolean recurse, CamelException *ex) -{ -#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; -} - -gboolean -_delete_messages (CamelFolder *folder, CamelException *ex) -{ - - 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; -} - -static GList * -_list_subfolders (CamelFolder *folder, CamelException *ex) -{ - /* newsgroups don't have subfolders */ - return NULL; -} - -static gint -_get_message_count (CamelFolder *folder, CamelException *ex) -{ - CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER(folder); - - g_assert (folder); - g_assert (nntp_folder->summary); - - return camel_folder_summary_count(nntp_folder->summary); -} - -#if 0 -static void -_append_message (CamelFolder *folder, CamelMimeMessage *message, 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; - } - -#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; - - ((CamelNNTPSummaryInformation *)(nntp_summary_info->data))->position += - summary->nntp_file_size; - summary->nntp_file_size += tmp_file_size; - - camel_nntp_summary_append_entries (summary, nntp_summary_info); - g_array_free (nntp_summary_info, TRUE); - - - /* 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); - - 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_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) -{ - 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 CamelMimeMessage * -_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) -{ - CamelStream *nntp_istream; - CamelStream *message_stream; - CamelMimeMessage *message = NULL; - CamelStore *parent_store; - char *buf; - int buf_len; - int buf_alloc; - int status; - gboolean done; - - /* get the parent store */ - parent_store = camel_folder_get_parent_store (folder, ex); - if (camel_exception_get_id (ex)) { - return NULL; - } - - status = camel_nntp_command (CAMEL_NNTP_STORE( parent_store ), NULL, "ARTICLE %s", uid); - - nntp_istream = CAMEL_NNTP_STORE (parent_store)->istream; - - /* if the uid was not found, raise an exception and return */ - if (status != CAMEL_NNTP_OK) { - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, - "message %s not found.", - uid); - return NULL; - } - - /* XXX ick ick ick. read the entire message into a buffer and - then create a stream_mem for it. */ - buf_alloc = 2048; - buf_len = 0; - buf = malloc(buf_alloc); - done = FALSE; - - buf[0] = 0; - - while (!done) { - char *line = camel_stream_buffer_read_line ( CAMEL_STREAM_BUFFER ( nntp_istream ), ex); - int line_length; - - /* XXX check exception */ - - line_length = strlen ( line ); - - if (!strcmp(line, ".")) { - done = TRUE; - g_free (line); - } - else { - if (buf_len + line_length > buf_alloc) { - buf_alloc *= 2; - buf = realloc (buf, buf_alloc); - } - strcat(buf, line); - strcat(buf, "\n"); - buf_len += strlen(line) + 1; - g_free (line); - } - } - - /* create a stream bound to the message */ - message_stream = camel_stream_mem_new_with_buffer(buf, buf_len); - - message = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream) == -1) { - gtk_object_unref ((GtkObject *)message); - gtk_object_unref ((GtkObject *)message_stream); - camel_exception_setv (ex, - CAMEL_EXCEPTION_FOLDER_INVALID_UID, /* XXX */ - "Could not create message for uid %s.", uid); - - return NULL; - } - 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); -#endif - - return message; -} - -/* get message info for a range of messages */ -static GPtrArray * -summary_get_message_info (CamelFolder *folder, int first, int count) -{ - GPtrArray *array = g_ptr_array_new(); - int i, maxcount; - CamelNNTPFolder *nntp_folder = (CamelNNTPFolder *)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)); - - return array; -} |