diff options
Diffstat (limited to 'camel/camel-store-summary.c')
-rw-r--r-- | camel/camel-store-summary.c | 946 |
1 files changed, 0 insertions, 946 deletions
diff --git a/camel/camel-store-summary.c b/camel/camel-store-summary.c deleted file mode 100644 index d8be2e0ee6..0000000000 --- a/camel/camel-store-summary.c +++ /dev/null @@ -1,946 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2001-2003 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <ctype.h> -#include <fcntl.h> -#include <errno.h> - -#include "camel-store-summary.h" - -#include "camel-file-utils.h" - -#include "libedataserver/md5-utils.h" -#include "libedataserver/e-memory.h" - -#include "camel-private.h" -#include "camel-url.h" - -#define d(x) -#define io(x) /* io debug */ - -/* possible versions, for versioning changes */ -#define CAMEL_STORE_SUMMARY_VERSION_0 (1) -#define CAMEL_STORE_SUMMARY_VERSION_2 (2) - -/* current version */ -#define CAMEL_STORE_SUMMARY_VERSION (2) - -#define _PRIVATE(o) (((CamelStoreSummary *)(o))->priv) - -static int summary_header_load(CamelStoreSummary *, FILE *); -static int summary_header_save(CamelStoreSummary *, FILE *); - -static CamelStoreInfo * store_info_new(CamelStoreSummary *, const char *); -static CamelStoreInfo * store_info_load(CamelStoreSummary *, FILE *); -static int store_info_save(CamelStoreSummary *, FILE *, CamelStoreInfo *); -static void store_info_free(CamelStoreSummary *, CamelStoreInfo *); - -static const char *store_info_string(CamelStoreSummary *, const CamelStoreInfo *, int); -static void store_info_set_string(CamelStoreSummary *, CamelStoreInfo *, int, const char *); - -static void camel_store_summary_class_init (CamelStoreSummaryClass *klass); -static void camel_store_summary_init (CamelStoreSummary *obj); -static void camel_store_summary_finalise (CamelObject *obj); - -static CamelObjectClass *camel_store_summary_parent; - -static void -camel_store_summary_class_init (CamelStoreSummaryClass *klass) -{ - camel_store_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ()); - - klass->summary_header_load = summary_header_load; - klass->summary_header_save = summary_header_save; - - klass->store_info_new = store_info_new; - klass->store_info_load = store_info_load; - klass->store_info_save = store_info_save; - klass->store_info_free = store_info_free; - - klass->store_info_string = store_info_string; - klass->store_info_set_string = store_info_set_string; -} - -static void -camel_store_summary_init (CamelStoreSummary *s) -{ - struct _CamelStoreSummaryPrivate *p; - - p = _PRIVATE(s) = g_malloc0(sizeof(*p)); - - s->store_info_size = sizeof(CamelStoreInfo); - - s->store_info_chunks = NULL; - - s->version = CAMEL_STORE_SUMMARY_VERSION; - s->flags = 0; - s->count = 0; - s->time = 0; - - s->folders = g_ptr_array_new(); - s->folders_path = g_hash_table_new(g_str_hash, g_str_equal); - - p->summary_lock = g_mutex_new(); - p->io_lock = g_mutex_new(); - p->alloc_lock = g_mutex_new(); - p->ref_lock = g_mutex_new(); -} - -static void -camel_store_summary_finalise (CamelObject *obj) -{ - struct _CamelStoreSummaryPrivate *p; - CamelStoreSummary *s = (CamelStoreSummary *)obj; - - p = _PRIVATE(obj); - - camel_store_summary_clear(s); - g_ptr_array_free(s->folders, TRUE); - g_hash_table_destroy(s->folders_path); - - g_free(s->summary_path); - - if (s->store_info_chunks) - e_memchunk_destroy(s->store_info_chunks); - - g_mutex_free(p->summary_lock); - g_mutex_free(p->io_lock); - g_mutex_free(p->alloc_lock); - g_mutex_free(p->ref_lock); - - g_free(p); -} - -CamelType -camel_store_summary_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register (camel_object_get_type (), "CamelStoreSummary", - sizeof (CamelStoreSummary), - sizeof (CamelStoreSummaryClass), - (CamelObjectClassInitFunc) camel_store_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_store_summary_init, - (CamelObjectFinalizeFunc) camel_store_summary_finalise); - } - - return type; -} - -/** - * camel_store_summary_new: - * - * Create a new CamelStoreSummary object. - * - * Return value: A new CamelStoreSummary widget. - **/ -CamelStoreSummary * -camel_store_summary_new (void) -{ - CamelStoreSummary *new = CAMEL_STORE_SUMMARY ( camel_object_new (camel_store_summary_get_type ())); return new; -} - -/** - * camel_store_summary_set_filename: - * @s: - * @name: - * - * Set the filename where the summary will be loaded to/saved from. - **/ -void camel_store_summary_set_filename(CamelStoreSummary *s, const char *name) -{ - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - g_free(s->summary_path); - s->summary_path = g_strdup(name); - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); -} - -void camel_store_summary_set_uri_base(CamelStoreSummary *s, CamelURL *base) -{ - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - if (s->uri_base) - camel_url_free(s->uri_base); - s->uri_base = camel_url_new_with_base(base, ""); - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); -} - -/** - * camel_store_summary_count: - * @s: - * - * Get the number of summary items stored in this summary. - * - * Return value: The number of items int he summary. - **/ -int -camel_store_summary_count(CamelStoreSummary *s) -{ - return s->folders->len; -} - -/** - * camel_store_summary_index: - * @s: - * @i: - * - * Retrieve a summary item by index number. - * - * A referenced to the summary item is returned, which may be - * ref'd or free'd as appropriate. - * - * Return value: The summary item, or NULL if the index @i is out - * of range. - * It must be freed using camel_store_summary_info_free(). - **/ -CamelStoreInfo * -camel_store_summary_index(CamelStoreSummary *s, int i) -{ - CamelStoreInfo *info = NULL; - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - if (i<s->folders->len) - info = g_ptr_array_index(s->folders, i); - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - - if (info) - info->refcount++; - - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - - return info; -} - -/** - * camel_store_summary_index: - * @s: - * @i: - * - * Obtain a copy of the summary array. This is done atomically, - * so cannot contain empty entries. - * - * It must be freed using camel_store_summary_array_free(). - **/ -GPtrArray * -camel_store_summary_array(CamelStoreSummary *s) -{ - CamelStoreInfo *info; - GPtrArray *res = g_ptr_array_new(); - int i; - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - g_ptr_array_set_size(res, s->folders->len); - for (i=0;i<s->folders->len;i++) { - info = res->pdata[i] = g_ptr_array_index(s->folders, i); - info->refcount++; - } - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - - return res; -} - -/** - * camel_store_summary_array_free: - * @s: - * @array: - * - * Free the folder summary array. - **/ -void -camel_store_summary_array_free(CamelStoreSummary *s, GPtrArray *array) -{ - int i; - - for (i=0;i<array->len;i++) - camel_store_summary_info_free(s, array->pdata[i]); - - g_ptr_array_free(array, TRUE); -} - -/** - * camel_store_summary_path: - * @s: - * @path: - * - * Retrieve a summary item by path name. - * - * A referenced to the summary item is returned, which may be - * ref'd or free'd as appropriate. - * - * Return value: The summary item, or NULL if the @path name - * is not available. - * It must be freed using camel_store_summary_info_free(). - **/ -CamelStoreInfo * -camel_store_summary_path(CamelStoreSummary *s, const char *path) -{ - CamelStoreInfo *info; - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - info = g_hash_table_lookup(s->folders_path, path); - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - - if (info) - info->refcount++; - - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - - return info; -} - -int -camel_store_summary_load(CamelStoreSummary *s) -{ - FILE *in; - int i; - CamelStoreInfo *mi; - - g_assert(s->summary_path); - - in = fopen(s->summary_path, "r"); - if (in == NULL) - return -1; - - CAMEL_STORE_SUMMARY_LOCK(s, io_lock); - if ( ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in) == -1) - goto error; - - /* now read in each message ... */ - for (i=0;i<s->count;i++) { - mi = ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->store_info_load(s, in); - - if (mi == NULL) - goto error; - - camel_store_summary_add(s, mi); - } - - CAMEL_STORE_SUMMARY_UNLOCK(s, io_lock); - - if (fclose (in) != 0) - return -1; - - s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY; - - return 0; - -error: - i = ferror (in); - g_warning ("Cannot load summary file: %s", strerror (ferror (in))); - CAMEL_STORE_SUMMARY_UNLOCK(s, io_lock); - fclose (in); - s->flags |= ~CAMEL_STORE_SUMMARY_DIRTY; - errno = i; - - return -1; -} - -/** - * camel_store_summary_save: - * @s: - * - * Writes the summary to disk. The summary is only written if changes - * have occured. - * - * Return value: Returns -1 on error. - **/ -int -camel_store_summary_save(CamelStoreSummary *s) -{ - FILE *out; - int fd; - int i; - guint32 count; - CamelStoreInfo *mi; - - g_assert(s->summary_path); - - io(printf("** saving summary\n")); - - if ((s->flags & CAMEL_STORE_SUMMARY_DIRTY) == 0) { - io(printf("** summary clean no save\n")); - return 0; - } - - fd = open(s->summary_path, O_RDWR|O_CREAT|O_TRUNC, 0600); - if (fd == -1) { - io(printf("** open error: %s\n", strerror (errno))); - return -1; - } - out = fdopen(fd, "w"); - if ( out == NULL ) { - i = errno; - printf("** fdopen error: %s\n", strerror (errno)); - close(fd); - errno = i; - return -1; - } - - io(printf("saving header\n")); - - CAMEL_STORE_SUMMARY_LOCK(s, io_lock); - - if ( ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1) { - i = errno; - fclose(out); - CAMEL_STORE_SUMMARY_UNLOCK(s, io_lock); - errno = i; - return -1; - } - - /* now write out each message ... */ - - /* FIXME: Locking? */ - - count = s->folders->len; - for (i=0;i<count;i++) { - mi = s->folders->pdata[i]; - ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->store_info_save(s, out, mi); - } - - CAMEL_STORE_SUMMARY_UNLOCK(s, io_lock); - - if (fflush (out) != 0 || fsync (fileno (out)) == -1) { - i = errno; - fclose (out); - errno = i; - return -1; - } - - if (fclose (out) != 0) - return -1; - - s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY; - return 0; -} - -/** - * camel_store_summary_header_load: - * @s: Summary object. - * - * Only load the header information from the summary, - * keep the rest on disk. This should only be done on - * a fresh summary object. - * - * Return value: -1 on error. - **/ -int camel_store_summary_header_load(CamelStoreSummary *s) -{ - FILE *in; - int ret; - - g_assert(s->summary_path); - - in = fopen(s->summary_path, "r"); - if (in == NULL) - return -1; - - CAMEL_STORE_SUMMARY_LOCK(s, io_lock); - ret = ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in); - CAMEL_STORE_SUMMARY_UNLOCK(s, io_lock); - - fclose(in); - s->flags &= ~CAMEL_STORE_SUMMARY_DIRTY; - return ret; -} - -/** - * camel_store_summary_add: - * @s: - * @info: - * - * Adds a new @info record to the summary. If @info->uid is NULL, then a new - * uid is automatically re-assigned by calling :next_uid_string(). - * - * The @info record should have been generated by calling one of the - * info_new_*() functions, as it will be free'd based on the summary - * class. And MUST NOT be allocated directly using malloc. - **/ -void camel_store_summary_add(CamelStoreSummary *s, CamelStoreInfo *info) -{ - if (info == NULL) - return; - - if (camel_store_info_path(s, info) == NULL) { - g_warning("Trying to add a folder info with missing required path name\n"); - return; - } - - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - g_ptr_array_add(s->folders, info); - g_hash_table_insert(s->folders_path, (char *)camel_store_info_path(s, info), info); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); -} - -/** - * camel_store_summary_add_from_path: - * @s: - * @h: - * - * Build a new info record based on the name, and add it to the summary. - * - * Return value: The newly added record. - **/ -CamelStoreInfo *camel_store_summary_add_from_path(CamelStoreSummary *s, const char *path) -{ - CamelStoreInfo *info; - - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - - info = g_hash_table_lookup(s->folders_path, path); - if (info != NULL) { - g_warning("Trying to add folder '%s' to summary that already has it", path); - info = NULL; - } else { - info = camel_store_summary_info_new_from_path(s, path); - g_ptr_array_add(s->folders, info); - g_hash_table_insert(s->folders_path, (char *)camel_store_info_path(s, info), info); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - } - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - - return info; -} - -/** - * camel_store_summary_info_new_from_path: - * @s: - * @h: - * - * Create a new info record from a name. - * - * Return value: Guess? This info record MUST be freed using - * camel_store_summary_info_free(), camel_store_info_free() will not work. - **/ -CamelStoreInfo *camel_store_summary_info_new_from_path(CamelStoreSummary *s, const char *f) -{ - return ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> store_info_new(s, f); -} - -/** - * camel_store_summary_info_free: - * @s: - * @mi: - * - * Unref and potentially free the message info @mi, and all associated memory. - **/ -void camel_store_summary_info_free(CamelStoreSummary *s, CamelStoreInfo *mi) -{ - g_assert(mi); - g_assert(s); - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - - g_assert(mi->refcount >= 1); - - mi->refcount--; - if (mi->refcount > 0) { - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - return; - } - - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - - ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->store_info_free(s, mi); -} - -/** - * camel_store_summary_info_ref: - * @s: - * @mi: - * - * Add an extra reference to @mi. - **/ -void camel_store_summary_info_ref(CamelStoreSummary *s, CamelStoreInfo *mi) -{ - g_assert(mi); - g_assert(s); - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - g_assert(mi->refcount >= 1); - mi->refcount++; - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); -} - -/** - * camel_store_summary_touch: - * @s: - * - * Mark the summary as changed, so that a save will save it. - **/ -void -camel_store_summary_touch(CamelStoreSummary *s) -{ - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); -} - -/** - * camel_store_summary_clear: - * @s: - * - * Empty the summary contents. - **/ -void -camel_store_summary_clear(CamelStoreSummary *s) -{ - int i; - - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - if (camel_store_summary_count(s) == 0) { - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - return; - } - - for (i=0;i<s->folders->len;i++) - camel_store_summary_info_free(s, s->folders->pdata[i]); - - g_ptr_array_set_size(s->folders, 0); - g_hash_table_destroy(s->folders_path); - s->folders_path = g_hash_table_new(g_str_hash, g_str_equal); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); -} - -/** - * camel_store_summary_remove: - * @s: - * @info: - * - * Remove a specific @info record from the summary. - **/ -void camel_store_summary_remove(CamelStoreSummary *s, CamelStoreInfo *info) -{ - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - g_hash_table_remove(s->folders_path, camel_store_info_path(s, info)); - g_ptr_array_remove(s->folders, info); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - - camel_store_summary_info_free(s, info); -} - -/** - * camel_store_summary_remove_uid: - * @s: - * @path: - * - * Remove a specific info record from the summary, by @path. - **/ -void camel_store_summary_remove_path(CamelStoreSummary *s, const char *path) -{ - CamelStoreInfo *oldinfo; - char *oldpath; - - CAMEL_STORE_SUMMARY_LOCK(s, ref_lock); - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - if (g_hash_table_lookup_extended(s->folders_path, path, (void *)&oldpath, (void *)&oldinfo)) { - /* make sure it doesn't vanish while we're removing it */ - oldinfo->refcount++; - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - camel_store_summary_remove(s, oldinfo); - camel_store_summary_info_free(s, oldinfo); - } else { - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - CAMEL_STORE_SUMMARY_UNLOCK(s, ref_lock); - } -} - -/** - * camel_store_summary_remove_index: - * @s: - * @index: - * - * Remove a specific info record from the summary, by index. - **/ -void camel_store_summary_remove_index(CamelStoreSummary *s, int index) -{ - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - if (index < s->folders->len) { - CamelStoreInfo *info = s->folders->pdata[index]; - - g_hash_table_remove(s->folders_path, camel_store_info_path(s, info)); - g_ptr_array_remove_index(s->folders, index); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - camel_store_summary_info_free(s, info); - } else { - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - } -} - -static int -summary_header_load(CamelStoreSummary *s, FILE *in) -{ - gint32 version, flags, count; - time_t time; - - fseek(in, 0, SEEK_SET); - - io(printf("Loading header\n")); - - if (camel_file_util_decode_fixed_int32(in, &version) == -1 - || camel_file_util_decode_fixed_int32(in, &flags) == -1 - || camel_file_util_decode_time_t(in, &time) == -1 - || camel_file_util_decode_fixed_int32(in, &count) == -1) { - return -1; - } - - s->flags = flags; - s->time = time; - s->count = count; - s->version = version; - - if (version < CAMEL_STORE_SUMMARY_VERSION_0) { - g_warning("Store summary header version too low"); - return -1; - } - - return 0; -} - -static int -summary_header_save(CamelStoreSummary *s, FILE *out) -{ - fseek(out, 0, SEEK_SET); - - io(printf("Savining header\n")); - - /* always write latest version */ - camel_file_util_encode_fixed_int32(out, CAMEL_STORE_SUMMARY_VERSION); - camel_file_util_encode_fixed_int32(out, s->flags); - camel_file_util_encode_time_t(out, s->time); - return camel_file_util_encode_fixed_int32(out, camel_store_summary_count(s)); -} - -/** - * camel_store_summary_info_new: - * @s: - * - * Allocate a new camel message info, suitable for adding - * to this summary. - * - * Return value: - **/ -CamelStoreInfo * -camel_store_summary_info_new(CamelStoreSummary *s) -{ - CamelStoreInfo *mi; - - CAMEL_STORE_SUMMARY_LOCK(s, alloc_lock); - if (s->store_info_chunks == NULL) - s->store_info_chunks = e_memchunk_new(32, s->store_info_size); - mi = e_memchunk_alloc0(s->store_info_chunks); - CAMEL_STORE_SUMMARY_UNLOCK(s, alloc_lock); - mi->refcount = 1; - return mi; -} - -const char *camel_store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type) -{ - return ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->store_info_string(s, mi, type); -} - -void camel_store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *value) -{ - ((CamelStoreSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->store_info_set_string(s, mi, type, value); -} - -static CamelStoreInfo * -store_info_new(CamelStoreSummary *s, const char *f) -{ - CamelStoreInfo *mi; - - mi = camel_store_summary_info_new(s); - - mi->path = g_strdup(f); - mi->unread = CAMEL_STORE_INFO_FOLDER_UNKNOWN; - mi->total = CAMEL_STORE_INFO_FOLDER_UNKNOWN; - - return mi; -} - -static CamelStoreInfo * -store_info_load(CamelStoreSummary *s, FILE *in) -{ - CamelStoreInfo *mi; - - mi = camel_store_summary_info_new(s); - - io(printf("Loading folder info\n")); - - camel_file_util_decode_string(in, &mi->path); - camel_file_util_decode_uint32(in, &mi->flags); - camel_file_util_decode_uint32(in, &mi->unread); - camel_file_util_decode_uint32(in, &mi->total); - - /* Ok, brown paper bag bug - prior to version 2 of the file, flags are - stored using the bit number, not the bit. Try to recover as best we can */ - if (s->version < CAMEL_STORE_SUMMARY_VERSION_2) { - guint32 flags = 0; - - if (mi->flags & 1) - flags |= CAMEL_STORE_INFO_FOLDER_NOSELECT; - if (mi->flags & 2) - flags |= CAMEL_STORE_INFO_FOLDER_READONLY; - if (mi->flags & 3) - flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED; - if (mi->flags & 4) - flags |= CAMEL_STORE_INFO_FOLDER_FLAGGED; - - mi->flags = flags; - } - - if (!ferror(in)) - return mi; - - camel_store_summary_info_free(s, mi); - - return NULL; -} - -static int -store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi) -{ - io(printf("Saving folder info\n")); - - camel_file_util_encode_string(out, camel_store_info_path(s, mi)); - camel_file_util_encode_uint32(out, mi->flags); - camel_file_util_encode_uint32(out, mi->unread); - camel_file_util_encode_uint32(out, mi->total); - - return ferror(out); -} - -static void -store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi) -{ - g_free(mi->path); - g_free(mi->uri); - e_memchunk_free(s->store_info_chunks, mi); -} - -static const char * -store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type) -{ - const char *p; - - /* FIXME: Locks? */ - - g_assert (mi != NULL); - - switch (type) { - case CAMEL_STORE_INFO_PATH: - return mi->path; - case CAMEL_STORE_INFO_NAME: - p = strrchr(mi->path, '/'); - if (p) - return p+1; - else - return mi->path; - case CAMEL_STORE_INFO_URI: - if (mi->uri == NULL) { - CamelURL *uri; - - uri = camel_url_new_with_base(s->uri_base, mi->path); - ((CamelStoreInfo *)mi)->uri = camel_url_to_string(uri, 0); - camel_url_free(uri); - } - return mi->uri; - } - - return ""; -} - -static void -store_info_set_string (CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *str) -{ - const char *p; - char *v; - int len; - - g_assert (mi != NULL); - - switch(type) { - case CAMEL_STORE_INFO_PATH: - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - g_hash_table_remove(s->folders_path, (char *)camel_store_info_path(s, mi)); - g_free(mi->path); - g_free(mi->uri); - mi->path = g_strdup(str); - g_hash_table_insert(s->folders_path, (char *)camel_store_info_path(s, mi), mi); - s->flags |= CAMEL_STORE_SUMMARY_DIRTY; - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - break; - case CAMEL_STORE_INFO_NAME: - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - g_hash_table_remove(s->folders_path, (char *)camel_store_info_path(s, mi)); - p = strrchr(mi->path, '/'); - if (p) { - len = p-mi->path+1; - v = g_malloc(len+strlen(str)+1); - memcpy(v, mi->path, len); - strcpy(v+len, str); - } else { - v = g_strdup(str); - } - g_free(mi->path); - mi->path = v; - g_hash_table_insert(s->folders_path, (char *)camel_store_info_path(s, mi), mi); - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - break; - case CAMEL_STORE_INFO_URI: - g_warning("Cannot set store info uri, aborting"); - abort(); - break; - } -} |