Remove camel_folder_{get,free}_subfolder_info, as we want to be able to

* camel-folder.[ch]: Remove
	camel_folder_{get,free}_subfolder_info, as we want to be able to
	scan the whole subfolder tree without having to open any folders,
	so this needs to be in CamelStore. Remove can_hold_folders and
	can_hold_messages flags; things that don't hold messages are no
	longer considered CamelFolders.

	* camel-folder-summary.[ch]: Remove CamelFolderInfo stuff.

	* camel-store.[ch]: Add camel_store_{get,free}_folder_info, as
	well as camel_store_free_folder_info_full and ..._nop for default
	implementations, and camel_folder_info_free and
	camel_folder_info_build as convenience functions. Turn
	CamelFolderInfo into a tree structure and also add an "url"
	member.

	* providers/*/camel-*-folder.c: Remove subfolder_info and can_hold
	stuff.
	* providers/*/camel-*-store.c: Add folder_info stuff.

	* providers/imap/camel-imap-folder.c (imap_summary_free): Free the
	summary elements with camel_message_info_free, not
	camel_folder_info_free. Oops.

	* providers/imap/camel-imap-utils.c: const poison

svn path=/trunk/; revision=5663
This commit is contained in:
Dan Winship
2000-10-02 19:08:20 +00:00
parent 46d07e9e46
commit e9dc30dbf0
20 changed files with 511 additions and 350 deletions

View File

@ -1,3 +1,31 @@
2000-10-02 Dan Winship <danw@helixcode.com>
* camel-folder.[ch]: Remove
camel_folder_{get,free}_subfolder_info, as we want to be able to
scan the whole subfolder tree without having to open any folders,
so this needs to be in CamelStore. Remove can_hold_folders and
can_hold_messages flags; things that don't hold messages are no
longer considered CamelFolders.
* camel-folder-summary.[ch]: Remove CamelFolderInfo stuff.
* camel-store.[ch]: Add camel_store_{get,free}_folder_info, as
well as camel_store_free_folder_info_full and ..._nop for default
implementations, and camel_folder_info_free and
camel_folder_info_build as convenience functions. Turn
CamelFolderInfo into a tree structure and also add an "url"
member.
* providers/*/camel-*-folder.c: Remove subfolder_info and can_hold
stuff.
* providers/*/camel-*-store.c: Add folder_info stuff.
* providers/imap/camel-imap-folder.c (imap_summary_free): Free the
summary elements with camel_message_info_free, not
camel_folder_info_free. Oops.
* providers/imap/camel-imap-utils.c: const poison
2000-09-28 Jeffrey Stedfast <fejj@helixcode.com>
* providers/smtp/camel-smtp-transport.c: Fixed some memory leaks.

View File

@ -1505,20 +1505,6 @@ camel_message_info_free(CamelMessageInfo *mi)
g_free(mi);
}
/**
* camel_folder_info_free:
* @fi: the folder info
*
* Frees a CamelFolderInfo and its contents.
**/
void
camel_folder_info_free(CamelFolderInfo *fi)
{
g_free(fi->name);
g_free(fi->full_name);
g_free(fi);
}
#if 0
static void
content_info_dump(CamelMessageContentInfo *ci, int depth)

View File

@ -35,11 +35,6 @@
/*typedef struct _CamelFolderSummary CamelFolderSummary;*/
typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
typedef struct {
char *full_name, *name;
int message_count, unread_message_count;
} CamelFolderInfo;
/* A tree of message content info structures
describe the content structure of the message (if it has any) */
typedef struct _CamelMessageContentInfo {
@ -231,7 +226,4 @@ void camel_tag_list_free(CamelTag **list);
void camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to);
void camel_message_info_free(CamelMessageInfo *mi);
/* folder info utils */
void camel_folder_info_free(CamelFolderInfo *fi);
#endif /* ! _CAMEL_FOLDER_SUMMARY_H */

View File

@ -47,8 +47,6 @@ static const gchar *get_name (CamelFolder *folder);
static const gchar *get_full_name (CamelFolder *folder);
static CamelStore *get_parent_store (CamelFolder *folder);
static gboolean can_hold_folders (CamelFolder *folder);
static gboolean can_hold_messages (CamelFolder *folder);
static guint32 get_permanent_flags (CamelFolder *folder);
static guint32 get_message_flags (CamelFolder *folder, const char *uid);
static void set_message_flags (CamelFolder *folder, const char *uid,
@ -59,10 +57,6 @@ static void set_message_user_flag (CamelFolder *folder, const char *uid,
static const char *get_message_user_tag(CamelFolder *folder, const char *uid, const char *name);
static void set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
static GPtrArray *get_subfolder_info (CamelFolder *folder);
static void free_subfolder_info (CamelFolder *folder,
GPtrArray *array);
static gint get_message_count (CamelFolder *folder);
static gint get_unread_message_count (CamelFolder *folder);
@ -126,10 +120,6 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class)
camel_folder_class->get_name = get_name;
camel_folder_class->get_full_name = get_full_name;
camel_folder_class->get_parent_store = get_parent_store;
camel_folder_class->can_hold_folders = can_hold_folders;
camel_folder_class->can_hold_messages = can_hold_messages;
camel_folder_class->get_subfolder_info = get_subfolder_info;
camel_folder_class->free_subfolder_info = free_subfolder_info;
camel_folder_class->expunge = expunge;
camel_folder_class->get_message_count = get_message_count;
camel_folder_class->get_unread_message_count = get_unread_message_count;
@ -330,67 +320,6 @@ camel_folder_get_full_name (CamelFolder *folder)
}
static gboolean
can_hold_folders (CamelFolder * folder)
{
return folder->can_hold_folders;
}
static gboolean
can_hold_messages (CamelFolder * folder)
{
return folder->can_hold_messages;
}
static GPtrArray *
get_subfolder_info (CamelFolder *folder)
{
g_warning ("CamelFolder::get_subfolder_info not implemented for `%s'",
camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
return NULL;
}
/**
* camel_folder_get_subfolder_info:
* @folder: the folder
*
* Return value: an array containing a CamelFolderInfo for each of
* @folder's subfolders. The array should not be modified and must be
* freed with camel_folder_free_subfolder_info().
**/
GPtrArray *
camel_folder_get_subfolder_info (CamelFolder *folder)
{
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
return CF_CLASS (folder)->get_subfolder_info (folder);
}
static void
free_subfolder_info (CamelFolder *folder, GPtrArray *array)
{
g_warning ("CamelFolder::free_subfolder_info not implemented "
"for `%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder)));
}
/**
* camel_folder_free_subfolder_info:
* @folder: folder object
* @array: the array of subfolder info to free
*
* Frees the array of info returned by camel_folder_get_subfolder_info().
**/
void
camel_folder_free_subfolder_info (CamelFolder *folder, GPtrArray *array)
{
g_return_if_fail (CAMEL_IS_FOLDER (folder));
CF_CLASS (folder)->free_subfolder_info (folder, array);
}
static CamelStore *
get_parent_store (CamelFolder * folder)
{
@ -1152,12 +1081,11 @@ message_changed (CamelObject *obj, /*const char *uid*/gpointer event_data)
/**
* camel_folder_free_nop:
* @folder: a folder
* @array: an array of uids, CamelFolderInfo, or CamelMessageInfo
* @array: an array of uids or CamelMessageInfo
*
* "Frees" the provided array by doing nothing. Used by CamelFolder
* subclasses as an implementation for free_uids, free_summary,
* or free_subfolder_info when the returned array is "static"
* information and should not be freed.
* subclasses as an implementation for free_uids, or free_summary when
* the returned array is "static" information and should not be freed.
**/
void
camel_folder_free_nop (CamelFolder *folder, GPtrArray *array)
@ -1168,12 +1096,12 @@ camel_folder_free_nop (CamelFolder *folder, GPtrArray *array)
/**
* camel_folder_free_shallow:
* @folder: a folder
* @array: an array of uids, CamelFolderInfo, or CamelMessageInfo
* @array: an array of uids or CamelMessageInfo
*
* Frees the provided array but not its contents. Used by CamelFolder
* subclasses as an implementation for free_uids, free_summary, or
* free_subfolder_info when the returned array needs to be freed
* but its contents come from "static" information.
* subclasses as an implementation for free_uids or free_summary when
* the returned array needs to be freed but its contents come from
* "static" information.
**/
void
camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array)

View File

@ -54,8 +54,6 @@ struct _CamelFolder
CamelStore *parent_store;
guint32 permanent_flags;
gboolean can_hold_folders:1;
gboolean can_hold_messages:1;
gboolean has_summary_capability:1;
gboolean has_search_capability:1;
};
@ -74,13 +72,6 @@ typedef struct {
CamelStore * (*get_parent_store) (CamelFolder *folder);
gboolean (*can_hold_folders) (CamelFolder *folder);
gboolean (*can_hold_messages) (CamelFolder *folder);
GPtrArray * (*get_subfolder_info)(CamelFolder *folder);
void (*free_subfolder_info) (CamelFolder *folder,
GPtrArray *subfolders);
void (*expunge) (CamelFolder *folder,
CamelException *ex);
@ -164,10 +155,6 @@ void camel_folder_construct (CamelFolder *folder,
const char *full_name,
const char *name);
GPtrArray * camel_folder_get_subfolder_info (CamelFolder *folder);
void camel_folder_free_subfolder_info (CamelFolder *folder,
GPtrArray *array);
void camel_folder_refresh_info (CamelFolder * folder,
CamelException * ex);
void camel_folder_sync (CamelFolder *folder,

View File

@ -25,6 +25,8 @@
* USA
*/
#include <config.h>
#include <string.h>
#include "camel-store.h"
#include "camel-folder.h"
#include "camel-exception.h"
@ -46,6 +48,11 @@ static char *get_folder_name (CamelStore *store, const char *folder_name,
static char *get_root_folder_name (CamelStore *store, CamelException *ex);
static char *get_default_folder_name (CamelStore *store, CamelException *ex);
static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex);
static void free_folder_info (CamelStore *store, CamelFolderInfo *tree);
static CamelFolder *lookup_folder (CamelStore *store, const char *folder_name);
static void cache_folder (CamelStore *store, const char *folder_name,
CamelFolder *folder);
@ -63,6 +70,8 @@ camel_store_class_init (CamelStoreClass *camel_store_class)
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_root_folder_name = get_root_folder_name;
camel_store_class->get_default_folder_name = get_default_folder_name;
camel_store_class->get_folder_info = get_folder_info;
camel_store_class->free_folder_info = free_folder_info;
camel_store_class->lookup_folder = lookup_folder;
camel_store_class->cache_folder = cache_folder;
camel_store_class->uncache_folder = uncache_folder;
@ -370,3 +379,182 @@ camel_store_get_default_folder (CamelStore *store, CamelException *ex)
}
return folder;
}
static CamelFolderInfo *
get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex)
{
g_warning ("CamelStore::get_folder_info not implemented for `%s'",
camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)));
return NULL;
}
/**
* camel_store_get_folder_info:
* @store: a CamelStore
* @top: the name of the folder to start from
* @fast: whether or not to do a "fast" scan.
* @recursive: whether to include information for subfolders
* @ex: a CamelException
*
* This fetches information about the folder structure of @store,
* starting with @top, and returns a tree of CamelFolderInfo
* structures. If @fast is %TRUE, the message_count or
* unread_message_count fields of some or all of the structures may be
* set to -1, if the store cannot determine that information quickly.
* If @recursive is %TRUE, the returned tree will include all levels of
* hierarchy below @top. If it is %FALSE, it will only include the
* immediate subfolders of @top.
*
* Return value: a CamelFolderInfo tree, which must be freed with
* camel_store_free_folder_info.
**/
CamelFolderInfo *
camel_store_get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex)
{
g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
return CS_CLASS (store)->get_folder_info (store, top, fast,
recursive, ex);
}
static void
free_folder_info (CamelStore *store, CamelFolderInfo *fi)
{
g_warning ("CamelStore::free_folder_info not implemented for `%s'",
camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)));
}
/**
* camel_store_free_folder_info:
* @store: a CamelStore
* @tree: the tree returned by camel_store_get_folder_info()
*
* Frees the data returned by camel_store_get_folder_info().
**/
void
camel_store_free_folder_info (CamelStore *store, CamelFolderInfo *fi)
{
g_return_if_fail (CAMEL_IS_STORE (store));
CS_CLASS (store)->free_folder_info (store, fi);
}
/**
* camel_store_free_folder_info_full:
* @store: a CamelStore
* @tree: the tree returned by camel_store_get_folder_info()
*
* An implementation for CamelStore::free_folder_info. Frees all
* of the data.
**/
void
camel_store_free_folder_info_full (CamelStore *store, CamelFolderInfo *fi)
{
camel_folder_info_free (fi);
}
/**
* camel_store_free_folder_info_nop:
* @store: a CamelStore
* @tree: the tree returned by camel_store_get_folder_info()
*
* An implementation for CamelStore::free_folder_info. Does nothing.
**/
void
camel_store_free_folder_info_nop (CamelStore *store, CamelFolderInfo *fi)
{
;
}
/**
* camel_folder_info_free:
* @fi: the CamelFolderInfo
*
* Frees @fi.
**/
void
camel_folder_info_free (CamelFolderInfo *fi)
{
if (fi) {
camel_folder_info_free (fi->sibling);
camel_folder_info_free (fi->child);
g_free (fi->name);
g_free (fi->full_name);
g_free (fi->url);
g_free (fi);
}
}
/**
* camel_folder_info_build:
* @folders: an array of CamelFolderInfo
* @top: the top of the folder tree
* @separator: the hieararchy separator character
* @short_names: %TRUE if the (short) name of a folder is the part after
* the last @separator in the full name. %FALSE if it is the full name.
*
* This takes an array of folders and attaches them together. @top points
* to the (or at least, "a") top-level element of the tree: it may or may
* not also be an element of @folders. If necessary, camel_folder_info_build
* will create additional CamelFolderInfo with %NULL urls to fill in gaps
* in the tree. The value of @short_names is used in constructing the
* names of these intermediate folders.
**/
void
camel_folder_info_build (GPtrArray *folders, CamelFolderInfo *top,
char separator, gboolean short_names)
{
CamelFolderInfo *fi, *pfi;
GHashTable *hash;
char *p, *pname;
int i;
/* Hash the folders. */
hash = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < folders->len; i++) {
fi = folders->pdata[i];
g_hash_table_insert (hash, fi->full_name, fi);
}
/* Now find parents. */
for (i = 0; i < folders->len; i++) {
fi = folders->pdata[i];
if (fi == top)
continue;
p = strrchr (fi->full_name, separator);
if (p) {
pname = g_strndup (fi->full_name, p - fi->full_name);
pfi = g_hash_table_lookup (hash, pname);
if (pfi) {
g_free (pname);
} else {
pfi = g_new0 (CamelFolderInfo, 1);
pfi->full_name = pname;
if (short_names) {
pfi->name = strrchr (pname, separator);
if (pfi->name)
pfi->name = g_strdup (pfi->name + 1);
else
pfi->name = g_strdup (pname);
} else
pfi->name = g_strdup (pname);
g_hash_table_insert (hash, pname, pfi);
g_ptr_array_add (folders, pfi);
}
fi->sibling = pfi->child;
pfi->child = fi;
} else {
fi->sibling = top->child;
top->child = fi;
}
}
}

View File

@ -37,6 +37,14 @@ extern "C" {
#include <camel/camel-object.h>
#include <camel/camel-service.h>
typedef struct _CamelFolderInfo {
struct _CamelFolderInfo *sibling, *child;
char *url, *full_name, *name;
int message_count, unread_message_count;
} CamelFolderInfo;
#define CAMEL_STORE_TYPE (camel_store_get_type ())
#define CAMEL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_STORE_TYPE, CamelStore))
#define CAMEL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_STORE_TYPE, CamelStoreClass))
@ -84,6 +92,14 @@ typedef struct {
void (*uncache_folder) (CamelStore *store,
CamelFolder *folder);
CamelFolderInfo *(*get_folder_info) (CamelStore *store,
const char *top,
gboolean fase,
gboolean recursive,
CamelException *ex);
void (*free_folder_info) (CamelStore *store,
CamelFolderInfo *fi);
} CamelStoreClass;
@ -108,6 +124,26 @@ void camel_store_rename_folder (CamelStore *store,
const char *new_name,
CamelException *ex);
CamelFolderInfo *camel_store_get_folder_info (CamelStore *store,
const char *top,
gboolean fase,
gboolean recursive,
CamelException *ex);
void camel_store_free_folder_info (CamelStore *store,
CamelFolderInfo *fi);
void camel_store_free_folder_info_full (CamelStore *store,
CamelFolderInfo *fi);
void camel_store_free_folder_info_nop (CamelStore *store,
CamelFolderInfo *fi);
void camel_folder_info_free (CamelFolderInfo *fi);
void camel_folder_info_build (GPtrArray *folders,
CamelFolderInfo *top,
char separator,
gboolean short_names);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -79,10 +79,6 @@ static void imap_copy_message_to (CamelFolder *source, const char *uid,
static void imap_move_message_to (CamelFolder *source, const char *uid,
CamelFolder *destination, CamelException *ex);
/* subfolder listing */
static GPtrArray *imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex);
static GPtrArray *imap_get_subfolder_info (CamelFolder *folder);
/* summary info */
static GPtrArray *imap_get_uids (CamelFolder *folder);
static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex);
@ -116,8 +112,6 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
camel_folder_class->get_uids = imap_get_uids;
camel_folder_class->free_uids = camel_folder_free_nop;
camel_folder_class->get_subfolder_info = imap_get_subfolder_info;
camel_folder_class->free_subfolder_info = camel_folder_free_nop;
camel_folder_class->get_message_count = imap_get_message_count;
camel_folder_class->get_unread_message_count = imap_get_unread_message_count;
@ -144,14 +138,11 @@ camel_imap_folder_init (gpointer object, gpointer klass)
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
CamelFolder *folder = CAMEL_FOLDER (object);
folder->can_hold_messages = TRUE;
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;
imap_folder->summary = NULL;
imap_folder->summary_hash = NULL;
imap_folder->lsub = NULL;
/* some IMAP daemons support user-flags *
* I would not, however, rely on this feature as *
@ -197,9 +188,6 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name)
short_name = folder_name;
camel_folder_construct (folder, parent, folder_name, short_name);
if (!*folder_name)
folder->can_hold_messages = FALSE;
return folder;
}
@ -211,7 +199,7 @@ imap_summary_free (GPtrArray **summary)
if (array) {
for (i = 0; i < array->len; i++)
camel_folder_info_free (array->pdata[i]);
camel_message_info_free (array->pdata[i]);
g_ptr_array_free (array, TRUE);
*summary = NULL;
@ -233,25 +221,14 @@ static void
imap_finalize (CamelObject *object)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
gint i;
imap_folder_summary_free (imap_folder);
if (imap_folder->lsub) {
for (i = 0; i < imap_folder->lsub->len; i++)
camel_folder_info_free (imap_folder->lsub->pdata[i]);
g_ptr_array_free (imap_folder->lsub, TRUE);
}
}
static void
imap_refresh_info (CamelFolder *folder, CamelException *ex)
{
imap_get_subfolder_info_internal (folder, ex);
if (folder->can_hold_messages)
imap_get_summary_internal (folder, ex);
imap_get_summary_internal (folder, ex);
}
static void
@ -308,8 +285,6 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
GPtrArray *response;
gint status, count = 0;
g_return_val_if_fail (folder->can_hold_messages, 0);
folder_path = camel_imap_store_folder_path (store, folder->full_name);
if (store->has_status_capability)
@ -501,92 +476,6 @@ imap_get_uids (CamelFolder *folder)
return array;
}
static GPtrArray *
imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
GPtrArray *response, *listing;
gboolean found_inbox = FALSE;
gint status, i;
gchar *namespace;
CamelFolderInfo *fi;
g_return_val_if_fail (folder != NULL, g_ptr_array_new ());
namespace = camel_imap_store_folder_path (store, folder->full_name);
status = camel_imap_command_extended (store, NULL, &response, ex,
"LIST \"\" \"%s%s*\"", namespace,
*namespace ? store->dir_sep : "");
if (status != CAMEL_IMAP_OK) {
g_free (namespace);
imap_folder->lsub = g_ptr_array_new ();
return imap_folder->lsub;
}
/* parse out the subfolders */
listing = g_ptr_array_new ();
if (response) {
for (i = 0; i < response->len; i++) {
gchar *resp, *flags, *sep, *dir;
resp = response->pdata[i];
if (!imap_parse_list_response (resp, namespace, &flags, &sep, &dir)) {
g_free (flags);
g_free (sep);
g_free (dir);
continue;
}
g_free (flags);
if (*dir) {
d(fprintf (stderr, "adding folder: %s\n", dir));
fi = g_new0 (CamelFolderInfo, 1);
fi->full_name = dir;
fi->name = strrchr (dir, *sep);
if (fi->name)
fi->name = g_strdup (fi->name + 1);
else
fi->name = g_strdup (dir);
/* FIXME: read/unread msg count */
if (!g_strcasecmp (dir, "INBOX"))
found_inbox = TRUE;
g_ptr_array_add (listing, fi);
}
g_free (sep);
}
camel_imap_response_free (response);
}
if (!*folder->name && !found_inbox) {
fi = g_new0 (CamelFolderInfo, 1);
fi->full_name = g_strdup ("INBOX");
fi->name = g_strdup ("INBOX");
/* FIXME: read/unread msg count */
g_ptr_array_add (listing, fi);
}
g_free (namespace);
imap_folder->lsub = listing;
return listing;
}
static GPtrArray *
imap_get_subfolder_info (CamelFolder *folder)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
return imap_folder->lsub;
}
static CamelMimeMessage *
imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{

View File

@ -48,8 +48,6 @@ typedef struct {
GPtrArray *summary;
GHashTable *summary_hash;
GPtrArray *lsub;
} CamelImapFolder;

View File

@ -60,6 +60,9 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboo
static char *get_folder_name (CamelStore *store, const char *folder_name,
CamelException *ex);
static char *get_root_folder_name (CamelStore *store, CamelException *ex);
static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex);
static void imap_keepalive (CamelRemoteStore *store);
/*static gboolean stream_is_alive (CamelStream *istream);*/
static int camel_imap_status (char *cmdid, char *respbuf);
@ -87,6 +90,8 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
camel_store_class->get_folder = get_folder;
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_root_folder_name = get_root_folder_name;
camel_store_class->get_folder_info = get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
camel_remote_store_class->keepalive = imap_keepalive;
}
@ -393,33 +398,35 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelEx
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
CamelFolder *new_folder;
char *folder_path;
gboolean exists = FALSE;
gboolean selectable;
new_folder = camel_imap_folder_new (store, folder_name);
/* this is the top-level dir, we already know it exists - it has to! */
if (!*folder_name) {
camel_folder_refresh_info (new_folder, ex);
return new_folder;
}
folder_path = camel_imap_store_folder_path (imap_store, folder_name);
if (imap_folder_exists (imap_store, folder_path, &selectable, ex)) {
exists = TRUE;
if (!selectable)
new_folder->can_hold_messages = FALSE;
}
if (!imap_folder_exists (imap_store, folder_path, &selectable, ex)) {
if (!create) {
g_free (folder_path);
return NULL;
}
if (!exists && create && !imap_create (imap_store, folder_path, ex)) {
if (!imap_create (imap_store, folder_path, ex)) {
g_free (folder_path);
return NULL;
}
} else if (!selectable) {
camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
"%s is not a selectable folder",
folder_name);
g_free (folder_path);
return NULL;
}
g_free (folder_path);
new_folder = camel_imap_folder_new (store, folder_name);
camel_folder_refresh_info (new_folder, ex);
if (camel_exception_is_set (ex)) {
camel_object_unref (CAMEL_OBJECT (new_folder));
return NULL;
}
/* this is where we *should refresh_info, not in imap_folder_new() */
camel_folder_refresh_info (new_folder, ex);
return new_folder;
}
@ -440,6 +447,138 @@ get_root_folder_name (CamelStore *store, CamelException *ex)
return g_strdup ("");
}
static CamelFolderInfo *
parse_list_response_as_folder_info (const char *response,
const char *namespace,
const char *base_url)
{
CamelFolderInfo *fi;
char *flags, *sep, *dir;
if (!imap_parse_list_response (response, namespace,
&flags, &sep, &dir))
return NULL;
fi = g_new0 (CamelFolderInfo, 1);
fi->full_name = dir;
fi->name = strrchr (dir, *sep);
if (fi->name)
fi->name = g_strdup (fi->name + 1);
else
fi->name = g_strdup (dir);
g_free (sep);
if (!e_strstrcase (flags, "\\NoSelect"))
fi->url = g_strdup_printf ("%s%s", base_url, dir);
g_free (flags);
/* FIXME: read/unread msg count */
return fi;
}
static CamelFolderInfo *
get_folder_info (CamelStore *store, const char *top, gboolean fast,
gboolean recursive, CamelException *ex)
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
CamelURL *url = CAMEL_SERVICE (store)->url;
gboolean found_inbox = FALSE;
int status, len, i;
GPtrArray *response;
char *dir_sep, *namespace, *base_url, *list;
CamelFolderInfo *topfi, *fi;
if (!top)
top = "";
dir_sep = imap_store->dir_sep;
namespace = camel_imap_store_folder_path (imap_store, top);
/* Yah! I am complicated! */
base_url = camel_url_to_string (url, FALSE);
len = strlen (base_url);
if (url->path && base_url[len - 1] != *dir_sep) {
base_url = g_realloc (base_url, len + 2);
base_url[len] = *dir_sep;
base_url[len + 1] = '\0';
} else if (!url->path) {
base_url = g_realloc (base_url, len + 2);
base_url[len] = '/';
base_url[len + 1] = '\0';
}
status = camel_imap_command_extended (imap_store, NULL, &response, ex,
"LIST \"\" \"%s\"", namespace);
if (status != CAMEL_IMAP_OK) {
g_free (namespace);
g_free (base_url);
return NULL;
}
list = camel_imap_response_extract (response, "LIST", ex);
if (!list) {
g_free (namespace);
g_free (base_url);
return NULL;
}
topfi = parse_list_response_as_folder_info (list, namespace, base_url);
g_free (list);
status = camel_imap_command_extended (imap_store, NULL, &response, ex,
"LIST \"\" \"%s%s%c\"",
namespace,
*namespace ? dir_sep : "",
recursive ? '*' : '%');
if (status != CAMEL_IMAP_OK) {
g_free (namespace);
g_free (base_url);
return NULL;
}
/* Turn responses into CamelFolderInfo and remove any
* extraneous responses.
*/
for (i = 0; i < response->len; i++) {
list = response->pdata[i];
response->pdata[i] = fi =
parse_list_response_as_folder_info (list, namespace,
base_url);
g_free (list);
if (!response->pdata[i]) {
g_ptr_array_remove_index_fast (response, i--);
continue;
}
if (!g_strcasecmp (fi->full_name, "INBOX"))
found_inbox = TRUE;
}
/* Add INBOX, if necessary */
if (!*top && !found_inbox) {
fi = g_new0 (CamelFolderInfo, 1);
fi->full_name = g_strdup ("INBOX");
fi->name = g_strdup ("INBOX");
fi->url = g_strdup_printf ("%sINBOX", base_url);
/* FIXME: read/unread msg count */
g_ptr_array_add (response, fi);
}
/* And assemble */
camel_folder_info_build (response, topfi, *dir_sep, TRUE);
g_ptr_array_free (response, FALSE);
/* Remove the top if it's the root of the store. */
if (!*top && !topfi->sibling) {
fi = topfi;
topfi = topfi->child;
fi->child = NULL;
camel_folder_info_free (fi);
}
g_free (namespace);
g_free (base_url);
return topfi;
}
static void
imap_keepalive (CamelRemoteStore *store)
{
@ -448,25 +587,6 @@ imap_keepalive (CamelRemoteStore *store)
camel_imap_command_extended (imap_store, NULL, NULL, NULL, "NOOP");
}
#if 0
static gboolean
stream_is_alive (CamelStream *istream)
{
CamelStreamFs *fs_stream;
char buf;
g_return_val_if_fail (istream != NULL, FALSE);
fs_stream = CAMEL_STREAM_FS (CAMEL_STREAM_BUFFER (istream)->stream);
g_return_val_if_fail (fs_stream->fd != -1, FALSE);
if (read (fs_stream->fd, (void *) &buf, 0) == 0)
return TRUE;
return FALSE;
}
#endif
static int
camel_imap_status (char *cmdid, char *respbuf)
{

View File

@ -33,12 +33,12 @@
#define d(x) x
char *
imap_next_word (char *buf)
imap_next_word (const char *buf)
{
char *word;
/* skip over current word */
for (word = buf; *word && *word != ' '; word++);
for (word = (char *)buf; *word && *word != ' '; word++);
/* skip over white space */
for ( ; *word && *word == ' '; word++);
@ -47,7 +47,7 @@ imap_next_word (char *buf)
}
gboolean
imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder)
imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder)
{
char *word, *ep, *f;
@ -96,7 +96,9 @@ imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep,
/* chop out the folder prefix */
if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) {
f = *folder + strlen (namespace) + strlen (*sep);
f = *folder + strlen (namespace);
if (!strncmp (f, *sep, strlen (*sep)))
f += strlen (*sep);
memmove (*folder, f, strlen (f) + 1);
}

View File

@ -30,9 +30,9 @@ extern "C" {
#include <glib.h>
char *imap_next_word (char *buf);
char *imap_next_word (const char *buf);
gboolean imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder);
gboolean imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder);
char *imap_translate_sexp (const char *expression);

View File

@ -64,7 +64,6 @@ static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message,
CamelException *ex);
static GPtrArray *mbox_get_uids(CamelFolder *folder);
static GPtrArray *mbox_get_subfolder_info(CamelFolder *folder);
static GPtrArray *mbox_get_summary(CamelFolder *folder);
static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
@ -102,8 +101,6 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class)
camel_folder_class->append_message = mbox_append_message;
camel_folder_class->get_uids = mbox_get_uids;
camel_folder_class->free_uids = camel_folder_free_deep;
camel_folder_class->get_subfolder_info = mbox_get_subfolder_info;
camel_folder_class->free_subfolder_info = camel_folder_free_shallow;
camel_folder_class->get_summary = mbox_get_summary;
camel_folder_class->free_summary = camel_folder_free_nop;
camel_folder_class->expunge = mbox_expunge;
@ -129,8 +126,6 @@ mbox_init(gpointer object, gpointer klass)
CamelFolder *folder = object;
CamelMboxFolder *mbox_folder = object;
folder->can_hold_messages = TRUE;
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;
@ -438,13 +433,6 @@ mbox_get_uids(CamelFolder *folder)
return array;
}
static GPtrArray *
mbox_get_subfolder_info(CamelFolder *folder)
{
/* No subfolders. */
return g_ptr_array_new();
}
static CamelMimeMessage *
mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex)
{

View File

@ -47,6 +47,9 @@ static void delete_folder (CamelStore *store, const char *folder_name,
static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
static char *get_folder_name (CamelStore *store, const char *folder_name,
CamelException *ex);
static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex);
static void
camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class)
@ -61,6 +64,8 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class)
camel_store_class->delete_folder = delete_folder;
camel_store_class->rename_folder = rename_folder;
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_folder_info = get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
}
static void
@ -117,8 +122,8 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create,
if (errno != ENOENT) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Could not open folder `%s':"
"\n%s", folder_name,
"Could not open file `%s':"
"\n%s", name,
g_strerror (errno));
g_free (name);
return NULL;
@ -135,8 +140,8 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create,
g_free (name);
if (fd == -1) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Could not create folder `%s':"
"\n%s", folder_name,
"Could not create file `%s':"
"\n%s", name,
g_strerror (errno));
return NULL;
}
@ -277,3 +282,14 @@ get_name (CamelService *service, gboolean brief)
else
return g_strdup_printf ("Local mail file %s", service->url->path);
}
static CamelFolderInfo *
get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex)
{
/* FIXME: This is broken, but it corresponds to what was
* there before.
*/
return NULL;
}

View File

@ -58,7 +58,6 @@ static gint mh_get_message_count(CamelFolder * folder);
static gint mh_get_unread_message_count(CamelFolder * folder);
static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex);
static GPtrArray *mh_get_uids(CamelFolder * folder);
static GPtrArray *mh_get_subfolder_info(CamelFolder * folder);
static GPtrArray *mh_get_summary(CamelFolder * folder);
static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex);
@ -93,8 +92,6 @@ static void camel_mh_folder_class_init(CamelObjectClass * camel_mh_folder_class)
camel_folder_class->append_message = mh_append_message;
camel_folder_class->get_uids = mh_get_uids;
camel_folder_class->free_uids = camel_folder_free_deep;
camel_folder_class->get_subfolder_info = mh_get_subfolder_info;
camel_folder_class->free_subfolder_info = camel_folder_free_deep;
camel_folder_class->get_summary = mh_get_summary;
camel_folder_class->free_summary = camel_folder_free_nop;
camel_folder_class->expunge = mh_expunge;
@ -119,8 +116,6 @@ static void mh_init(gpointer object, gpointer klass)
CamelFolder *folder = object;
CamelMhFolder *mh_folder = object;
folder->can_hold_messages = TRUE;
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;
@ -356,13 +351,6 @@ static GPtrArray *mh_get_uids(CamelFolder * folder)
return array;
}
static GPtrArray *mh_get_subfolder_info(CamelFolder * folder)
{
/* FIXME: scan for sub-folders */
/* No subfolders. */
return g_ptr_array_new();
}
static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex)
{
CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder);

View File

@ -45,6 +45,9 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo
static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex);
static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex);
static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex);
static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class)
{
@ -58,6 +61,8 @@ static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class)
camel_store_class->delete_folder = delete_folder;
camel_store_class->rename_folder = rename_folder;
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_folder_info = get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
}
static void camel_mh_store_init(CamelObject * object)
@ -207,3 +212,15 @@ static char *get_name(CamelService * service, gboolean brief)
else
return g_strdup_printf("Local mail file %s", service->url->path);
}
static CamelFolderInfo *
get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex)
{
/* FIXME: This is broken, but it corresponds to what was
* there before.
*/
return NULL;
}

View File

@ -262,37 +262,6 @@ nntp_folder_get_summary (CamelFolder *folder)
return nntp_folder->summary->messages;
}
static GPtrArray *
nntp_folder_get_subfolder_info (CamelFolder *folder)
{
CamelNNTPNewsrc *newsrc;
GPtrArray *names, *info;
CamelFolderInfo *fi;
int i;
/* Only top-level folder has subfolders. */
if (*folder->name)
return NULL;
newsrc = CAMEL_NNTP_STORE (camel_folder_get_parent_store (folder))->newsrc;
if (!newsrc)
return NULL;
info = g_ptr_array_new ();
names = camel_nntp_newsrc_get_subscribed_group_names (newsrc);
for (i = 0; i < names->len; i++) {
fi = g_new (CamelFolderInfo, 1);
fi->name = fi->full_name = names->pdata[i];
/* FIXME */
fi->message_count = 0;
fi->unread_message_count = 0;
g_ptr_array_add (info, fi);
}
camel_nntp_newsrc_free_group_names (newsrc, names);
return info;
}
static GPtrArray*
nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
{
@ -336,8 +305,6 @@ camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class)
camel_folder_class->free_uids = camel_folder_free_deep;
camel_folder_class->get_summary = nntp_folder_get_summary;
camel_folder_class->free_summary = camel_folder_free_nop;
camel_folder_class->get_subfolder_info = nntp_folder_get_subfolder_info;
camel_folder_class->free_subfolder_info = camel_folder_free_deep;
camel_folder_class->search_by_expression = nntp_folder_search_by_expression;
camel_folder_class->get_message_info = nntp_folder_get_message_info;
}
@ -366,18 +333,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti
CamelFolder *folder = CAMEL_FOLDER (camel_object_new (CAMEL_NNTP_FOLDER_TYPE));
camel_folder_construct (folder, parent, folder_name, folder_name);
/* set flags */
if (!*folder->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;
}
folder->has_summary_capability = TRUE;
camel_folder_refresh_info (folder, ex);
if (camel_exception_is_set (ex)) {

View File

@ -296,6 +296,50 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
return camel_nntp_folder_new (store, folder_name, ex);
}
static CamelFolderInfo *
nntp_store_get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
CamelException *ex)
{
CamelNNTPStore *nntp_store = (CamelNNTPStore *)store;
GPtrArray *names;
CamelFolderInfo *topfi, *last = NULL, *fi;
int i;
if (!nntp_store->newsrc)
return NULL;
topfi = g_new0 (CamelFolderInfo, 1);
topfi->name = g_strdup (top);
topfi->full_name = g_strdup (top);
if (*top)
topfi->url = g_strdup_printf ("news:%s", top);
/* FIXME: message_count if top != "" */
topfi->message_count = topfi->unread_message_count = -1;
if (!recursive || *top)
return topfi;
names = camel_nntp_newsrc_get_subscribed_group_names (nntp_store->newsrc);
for (i = 0; i < names->len; i++) {
fi = g_new0 (CamelFolderInfo, 1);
fi->name = g_strdup (names->pdata[i]);
fi->full_name = g_strdup (names->pdata[i]);
fi->url = g_strdup_printf ("news:%s", (char *)names->pdata[i]);
/* FIXME */
fi->message_count = fi->unread_message_count = -1;
if (last)
last->sibling = fi;
else
topfi->child = fi;
last = fi;
}
camel_nntp_newsrc_free_group_names (nntp_store->newsrc, names);
return topfi;
}
static char *
nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex)
{
@ -332,6 +376,8 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
camel_store_class->get_folder = nntp_store_get_folder;
camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name;
camel_store_class->get_folder_info = nntp_store_get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
}

View File

@ -78,8 +78,6 @@ camel_pop3_folder_init (gpointer object)
CamelFolder *folder = CAMEL_FOLDER (object);
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
folder->can_hold_messages = TRUE;
folder->can_hold_folders = FALSE;
folder->has_summary_capability = FALSE;
folder->has_search_capability = FALSE;

View File

@ -119,8 +119,6 @@ camel_vee_folder_init (CamelVeeFolder *obj)
p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
folder->can_hold_messages = TRUE;
folder->can_hold_folders = FALSE;
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;