aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog24
-rw-r--r--camel/camel-debug.c143
-rw-r--r--camel/camel-debug.h3
-rw-r--r--camel/camel-store.c28
-rw-r--r--camel/camel-url-scanner.c1
-rw-r--r--camel/providers/imap/camel-imap-store.c84
-rw-r--r--camel/providers/imapp/camel-imapp-driver.c2
7 files changed, 263 insertions, 22 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 95cf94a1e2..a6bc6dd764 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,27 @@
+2004-03-30 Not Zed <NotZed@Ximian.com>
+
+ * camel-store.c (camel_store_get_folder_info): added some debug to
+ dump the whole folderinfo tree if store:folder_info is set.
+
+ * providers/imapp/camel-imapp-driver.c: #if 0 out some code, to
+ kill warnings.
+
+ * camel-url-scanner.c: include ctype.h for isspace (wonder if it
+ should use utf8 funcs?).
+
+2004-03-29 Not Zed <NotZed@Ximian.com>
+
+ ** See #56146.
+
+ * providers/imap/camel-imap-store.c (get_folders): check the
+ top-level folders list for duplicates as well.
+ (get_folders_add_folders): split out the folder return merging
+ code from get_folders. Absolute mess of crap to deal with more
+ busted servers.
+
+ * camel-debug.c (camel_debug_start, camel_debug_end): some helpers
+ to wrap debug output for atomicicity.
+
2004-03-29 Jeffrey Stedfast <fejj@ximian.com>
* providers/imap4/camel-imap4-folder.c (camel_imap4_folder_new):
diff --git a/camel/camel-debug.c b/camel/camel-debug.c
index 7c16c9a614..77a5d1cf8b 100644
--- a/camel/camel-debug.c
+++ b/camel/camel-debug.c
@@ -21,6 +21,9 @@
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+#include <pthread.h>
#include "camel-debug.h"
@@ -113,3 +116,143 @@ gboolean camel_debug(const char *mode)
return FALSE;
}
+
+static pthread_mutex_t debug_lock = PTHREAD_MUTEX_INITIALIZER;
+/**
+ * camel_debug_start:
+ * @mode:
+ *
+ * Start debug output for a given mode, used to make sure debug output
+ * is output atomically and not interspersed with unrelated stuff.
+ *
+ * Return value: Returns true if mode is set, and in which case, you must
+ * call debug_end when finished any screen output.
+ **/
+gboolean
+camel_debug_start(const char *mode)
+{
+ if (camel_debug(mode)) {
+ pthread_mutex_lock(&debug_lock);
+ printf("Thread %lx >\n", pthread_self());
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * camel_debug_end:
+ *
+ * Call this when you're done with your debug output. If and only if
+ * you called camel_debug_start, and if it returns TRUE.
+ **/
+void
+camel_debug_end(void)
+{
+ printf("< %lx >\n", pthread_self());
+ pthread_mutex_unlock(&debug_lock);
+}
+
+#include <sys/debugreg.h>
+
+#if 0
+static unsigned
+i386_length_and_rw_bits (int len, enum target_hw_bp_type type)
+{
+ unsigned rw;
+
+ switch (type)
+ {
+ case hw_execute:
+ rw = DR_RW_EXECUTE;
+ break;
+ case hw_write:
+ rw = DR_RW_WRITE;
+ break;
+ case hw_read: /* x86 doesn't support data-read watchpoints */
+ case hw_access:
+ rw = DR_RW_READ;
+ break;
+#if 0
+ case hw_io_access: /* not yet supported */
+ rw = DR_RW_IORW;
+ break;
+#endif
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint type %d in i386_length_and_rw_bits.\n", (int)type);
+ }
+
+ switch (len)
+ {
+ case 1:
+ return (DR_LEN_1 | rw);
+ case 2:
+ return (DR_LEN_2 | rw);
+ case 4:
+ return (DR_LEN_4 | rw);
+ case 8:
+ if (TARGET_HAS_DR_LEN_8)
+ return (DR_LEN_8 | rw);
+ default:
+ internal_error (__FILE__, __LINE__, "\
+Invalid hw breakpoint length %d in i386_length_and_rw_bits.\n", len);
+ }
+}
+
+#define I386_DR_SET_RW_LEN(i,rwlen) \
+ do { \
+ dr_control_mirror &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ dr_control_mirror |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
+ } while (0)
+
+#define I386_DR_LOCAL_ENABLE(i) \
+ dr_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
+
+
+#define set_dr(regnum, val) \
+ __asm__("movl %0,%%db" #regnum \
+ : /* no output */ \
+ :"r" (val))
+
+#define get_dr(regnum, val) \
+ __asm__("movl %%db" #regnum ", %0" \
+ :"=r" (val))
+
+/* fine idea, but it doesn't work, crashes in get_dr :-/ */
+void
+camel_debug_hwatch(int wp, void *addr)
+{
+ guint32 control, rw;
+
+ g_assert(wp <= DR_LASTADDR);
+ g_assert(sizeof(addr) == 4);
+
+ get_dr(7, control);
+ /* set watch mode + size */
+ rw = DR_RW_WRITE | DR_LEN_4;
+ control &= ~(((1<<DR_CONTROL_SIZE)-1) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE * wp));
+ control |= rw << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*wp);
+ /* set watch enable */
+ control |= ( 1<< (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * wp));
+ control |= DR_LOCAL_SLOWDOWN;
+ control &= ~DR_CONTROL_RESERVED;
+
+ switch (wp) {
+ case 0:
+ set_dr(0, addr);
+ break;
+ case 1:
+ set_dr(1, addr);
+ break;
+ case 2:
+ set_dr(2, addr);
+ break;
+ case 3:
+ set_dr(3, addr);
+ break;
+ }
+ set_dr(7, control);
+}
+
+#endif
diff --git a/camel/camel-debug.h b/camel/camel-debug.h
index 7ebf1eb9c0..b09a00cb90 100644
--- a/camel/camel-debug.h
+++ b/camel/camel-debug.h
@@ -36,6 +36,9 @@ extern "C" {
void camel_debug_init(void);
gboolean camel_debug(const char *mode);
+gboolean camel_debug_start(const char *mode);
+void camel_debug_end(void);
+
/* This interface is deprecated */
extern int camel_verbose_debug;
diff --git a/camel/camel-store.c b/camel/camel-store.c
index f4b96a1959..e7d1f41651 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -31,6 +31,8 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include "camel-debug.h"
+
#include "camel-session.h"
#include "camel-store.h"
#include "camel-folder.h"
@@ -732,6 +734,24 @@ add_special_info (CamelStore *store, CamelFolderInfo *info, const char *name, co
vinfo->path = g_strdup_printf ("/%s", vinfo->name);
}
+static void
+dump_fi(CamelFolderInfo *fi, int depth)
+{
+ char *s;
+
+ s = g_alloca(depth+1);
+ memset(s, ' ', depth);
+ s[depth] = 0;
+
+ while (fi) {
+ printf("%suri: %s\n", s, fi->uri);
+ printf("%sfull_name: %s\n", s, fi->full_name);
+ printf("%sflags: %08x\n", s, fi->flags);
+ dump_fi(fi->child, depth+2);
+ fi = fi->next;
+ }
+}
+
/**
* camel_store_get_folder_info:
* @store: a CamelStore
@@ -774,6 +794,14 @@ camel_store_get_folder_info(CamelStore *store, const char *top, guint32 flags, C
if (info->uri && (store->flags & CAMEL_STORE_VJUNK))
add_special_info (store, info, CAMEL_VJUNK_NAME, _("Junk"), TRUE);
}
+
+ if (camel_debug_start("store:folder_info")) {
+ char *url = camel_url_to_string(((CamelService *)store)->url, CAMEL_URL_HIDE_ALL);
+ printf("Get folder info(%p:%s, '%s') =\n", store, url, top?top:"<null>");
+ g_free(url);
+ dump_fi(info, 2);
+ camel_debug_end();
+ }
return info;
}
diff --git a/camel/camel-url-scanner.c b/camel/camel-url-scanner.c
index 9bd46e8333..486b42c34e 100644
--- a/camel/camel-url-scanner.c
+++ b/camel/camel-url-scanner.c
@@ -26,6 +26,7 @@
#endif
#include <string.h>
+#include <ctype.h>
#include "e-util/e-trie.h"
#include "camel-url-scanner.h"
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 8544988cfa..20fcf9aa17 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -63,15 +63,14 @@
#include "camel-imap-private.h"
#include "camel-private.h"
+#include "camel-debug.h"
+
#define d(x)
/* Specified in RFC 2060 */
#define IMAP_PORT 143
#define SIMAP_PORT 993
-
-extern int camel_verbose_debug;
-
static CamelDiscoStoreClass *parent_class = NULL;
static char imap_tag_prefix = 'A';
@@ -2279,6 +2278,9 @@ get_subscribed_folders (CamelImapStore *imap_store, const char *top, CamelExcept
char *result;
int haveinbox = FALSE;
+ if (camel_debug("imap:folder_info"))
+ printf(" get_subscribed folders\n");
+
folders = g_ptr_array_new ();
names = g_ptr_array_new ();
for (i=0;(si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i));i++) {
@@ -2569,6 +2571,49 @@ static int folder_eq(const void *ap, const void *bp)
return g_str_equal(a, b);
}
+static GSList *
+get_folders_add_folders(GSList *p, int recurse, GHashTable *infos, GPtrArray *folders, GPtrArray *folders_out)
+{
+ CamelFolderInfo *oldfi, *fi;
+ int i;
+
+ /* This is a nasty mess, because some servers will return
+ broken results from LIST or LSUB if you use '%'. e.g. you
+ may get (many) duplicate names, and worse, names may have
+ conflicting flags. */
+ for (i=0; i<folders->len; i++) {
+ fi = folders->pdata[i];
+ oldfi = g_hash_table_lookup(infos, fi->full_name);
+ if (oldfi == NULL) {
+ d(printf(" new folder '%s'\n", fi->full_name));
+ g_hash_table_insert(infos, fi->full_name, fi);
+ if (recurse)
+ p = g_slist_prepend(p, fi);
+ } else {
+ d(printf(" old folder '%s', old flags %08x new flags %08x\n", fi->full_name, oldfi->flags, fi->flags));
+
+ /* need to special-case noselect, since it also affects the uri */
+ if ((oldfi->flags & CAMEL_FOLDER_NOSELECT) != 0
+ && (fi->flags & CAMEL_FOLDER_NOSELECT) == 0) {
+ g_free(oldfi->uri);
+ oldfi->uri = fi->uri;
+ fi->uri = NULL;
+ }
+
+ /* some flags are anded together, some are or'd */
+
+ oldfi->flags = (oldfi->flags & fi->flags & (CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_NOINFERIORS))
+ | ((oldfi->flags | fi->flags) & ~(CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_NOINFERIORS));
+
+ camel_folder_info_free(fi);
+ }
+ }
+
+ g_ptr_array_set_size(folders, 0);
+
+ return p;
+}
+
static GPtrArray *
get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
@@ -2586,6 +2631,9 @@ get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *e
if (!camel_imap_store_connected (imap_store, ex))
return NULL;
+ if (camel_debug("imap:folder_info"))
+ printf(" get_folders\n");
+
/* allow megalomaniacs to override the max of 10 */
if (imap_max_depth == 0) {
name = getenv("CAMEL_IMAP_MAX_DEPTH");
@@ -2637,10 +2685,7 @@ get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *e
goto fail;
}
- for (i=0; i<folders->len; i++)
- p = g_slist_prepend(p, folders->pdata[i]);
-
- g_ptr_array_set_size(folders, 0);
+ p = get_folders_add_folders(p, TRUE, infos, folders, folders_out);
/* p is a reversed list of pending folders for the next level, q is the list of folders for this */
while (p) {
@@ -2651,10 +2696,9 @@ get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *e
fi = q->data;
q = g_slist_remove_link(q, q);
- g_hash_table_insert(infos, fi->full_name, fi);
g_ptr_array_add(folders_out, fi);
- d(printf("Checking folder '%s'\n", fi->full_name));
+ d(printf("Checking parent folder '%s'\n", fi->full_name));
/* First if we're not recursive mode on the top level, and we know it has or doesn't
or can't have children, no need to go further - a bit ugly */
@@ -2662,6 +2706,7 @@ get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *e
&& (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0
&& (fi->flags & (CAMEL_FOLDER_CHILDREN|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS)) != 0) {
/* do nothing */
+ d(printf(" not interested in folder right now ...\n"));
}
/* Otherwise, if this has (or might have) children, scan it */
else if ( (fi->flags & (CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS)) == 0
@@ -2677,19 +2722,8 @@ get_folders(CamelStore *store, const char *top, guint32 flags, CamelException *e
if (folders->len > 0)
fi->flags |= CAMEL_FOLDER_CHILDREN;
- for (i=0;i<folders->len;i++) {
- fi = folders->pdata[i];
- if (g_hash_table_lookup(infos, fi->full_name) == NULL) {
- g_hash_table_insert(infos, fi->full_name, fi);
- if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && depth<imap_max_depth)
- p = g_slist_prepend(p, fi);
- else
- g_ptr_array_add(folders_out, fi);
- } else {
- camel_folder_info_free(fi);
- }
- }
- g_ptr_array_set_size(folders, 0);
+ p = get_folders_add_folders(p, (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) && depth<imap_max_depth,
+ infos, folders, folders_out);
}
}
depth++;
@@ -2719,6 +2753,9 @@ get_folder_info_online (CamelStore *store, const char *top, guint32 flags, Camel
if (top == NULL)
top = "";
+ if (camel_debug("imap:folder_info"))
+ printf("get folder info online\n");
+
CAMEL_SERVICE_LOCK(store, connect_lock);
if ((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
@@ -2801,6 +2838,9 @@ get_folder_info_offline (CamelStore *store, const char *top,
GPtrArray *folders;
char *storage_path;
+ if (camel_debug("imap:folder_info"))
+ printf("get folder info offline\n");
+
if (!imap_store->connected &&
!camel_service_connect (CAMEL_SERVICE (store), ex))
return NULL;
diff --git a/camel/providers/imapp/camel-imapp-driver.c b/camel/providers/imapp/camel-imapp-driver.c
index 54c050c675..8028b942bf 100644
--- a/camel/providers/imapp/camel-imapp-driver.c
+++ b/camel/providers/imapp/camel-imapp-driver.c
@@ -430,6 +430,7 @@ camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder
}
}
+#if 0
static void
fetch_data_free(CamelIMAPPFetch *fd)
{
@@ -440,6 +441,7 @@ fetch_data_free(CamelIMAPPFetch *fd)
g_free(fd->section);
g_free(fd);
}
+#endif
struct _CamelStream * camel_imapp_driver_fetch(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid, const char *body)
{