diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-07-31 16:16:08 +0200 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-07-31 16:16:08 +0200 |
commit | 372042c9d042061962e0186b89b8680788eb50f4 (patch) | |
tree | cea3c2352e50970981cac389ad57cfc0329c96e2 | |
parent | 1525fa864c9dd6d3c88e3a40e135740d0b1bd23f (diff) | |
download | evolution-data-server-372042c9d042061962e0186b89b8680788eb50f4.tar.gz |
Select folder based on CamelFolder *, not its name
As threatened in commit 6900bf35807c9be0cb2498a63cef4684ff9144d6, sanify the
way that commands indicate which folder (if any) should be selected when they
run.
Until now, they've set a folder name in ic->select, which was passed as an
argument to camel_imapx_command_new(). That's been used for comparisons to
decide whether the command can run... but when it actually comes to select
a folder specifically for the benefit of the command, it wasn't used! Instead,
the folder in ic->job->folder was used instead.
Clean this up so that ic->select is now a CamelFolder * instead of a string,
and actually use it consistently for both the comparisons and the eventual
SELECT.
(cherry picked from commit 473eee75ae154e7d1bc4a83247c1a0128a0b635c)
-rw-r--r-- | camel/providers/imapx/camel-imapx-server.c | 116 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-server.h | 1 |
2 files changed, 51 insertions, 66 deletions
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c index 02887abf9..1d0018a10 100644 --- a/camel/providers/imapx/camel-imapx-server.c +++ b/camel/providers/imapx/camel-imapx-server.c @@ -139,7 +139,7 @@ struct _CamelIMAPXCommand { const gchar *name; /* command name/type (e.g. FETCH) */ - gchar *select; /* folder to select */ + CamelFolder *select; /* folder to select */ struct _status_info *status; /* status for command, indicates it is complete if != NULL */ @@ -161,7 +161,7 @@ struct _CamelIMAPXCommand { struct _CamelIMAPXJob *job; }; -CamelIMAPXCommand *camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, const gchar *select, const gchar *fmt, ...); +CamelIMAPXCommand *camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...); void camel_imapx_command_add(CamelIMAPXCommand *ic, const gchar *fmt, ...); void camel_imapx_command_free(CamelIMAPXCommand *ic); void camel_imapx_command_close(CamelIMAPXCommand *ic); @@ -717,7 +717,7 @@ imapx_command_addv(CamelIMAPXCommand *ic, const gchar *fmt, va_list ap) } CamelIMAPXCommand * -camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, const gchar *select, const gchar *fmt, ...) +camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...) { CamelIMAPXCommand *ic; static gint tag = 0; @@ -727,7 +727,7 @@ camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, const gchar *se ic->tag = tag++; ic->name = name; ic->mem = (CamelStreamMem *)camel_stream_mem_new(); - ic->select = g_strdup(select); + ic->select = select; ic->is = is; camel_dlist_init(&ic->parts); ic->ex = camel_exception_new (); @@ -766,8 +766,7 @@ camel_imapx_command_free(CamelIMAPXCommand *ic) if (ic->mem) camel_object_unref((CamelObject *)ic->mem); imapx_free_status(ic->status); - g_free(ic->select); - + while ((cp = ((CamelIMAPXCommandPart *)camel_dlist_remhead(&ic->parts)))) { g_free(cp->data); if (cp->ob) { @@ -882,7 +881,7 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex) nc = ic->next; while (nc && is->literal == NULL && count < MAX_COMMANDS && ic->pri >= pri) { c(printf("-- %3d '%s'?\n", (gint)ic->pri, ic->name)); - if (ic->select == NULL) { + if (!ic->select) { c(printf("--> starting '%s'\n", ic->name)); pri = ic->pri; camel_dlist_remove((CamelDListNode *)ic); @@ -926,8 +925,9 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex) } /* See if any queued jobs on this select first */ - if (is->select) { - c(printf("- we're selected on '%s', current jobs?\n", is->select)); + if (is->select_folder) { + c(printf("- we're selected on '%s', current jobs?\n", + camel_folder_get_full_name(is->select_folder))); for (ic = (CamelIMAPXCommand *)is->active.head;ic->next;ic=ic->next) { c(printf("- %3d '%s'\n", (gint)ic->pri, ic->name)); if (ic->pri > pri) @@ -945,7 +945,7 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex) nc = ic->next; while (nc && is->literal == NULL && count < MAX_COMMANDS && ic->pri >= pri) { c(printf("-- %3d '%s'?\n", (gint)ic->pri, ic->name)); - if (ic->select == NULL || strcmp(ic->select, is->select) == 0) { + if (!ic->select || (ic->select == is->select_folder)) { c(printf("--> starting '%s'\n", ic->name)); pri = ic->pri; camel_dlist_remove((CamelDListNode *)ic); @@ -969,14 +969,16 @@ imapx_command_start_next(CamelIMAPXServer *is, CamelException *ex) /* If we need to select a folder for the first command, do it now, once it is complete it will re-call us if it succeeded */ - if (ic->job->folder) { - imapx_select(is, ic->job->folder, FALSE, ex); + if (ic->select) { + c(printf("Selecting folder '%s' for command '%s'(%p)\n", + camel_folder_get_full_name(ic->select), ic->name, ic)); + imapx_select(is, ic->select, FALSE, ex); } else { pri = ic->pri; nc = ic->next; count = 0; while (nc && is->literal == NULL && count < MAX_COMMANDS && ic->pri >= pri) { - if (ic->select == NULL || (is->select && strcmp(ic->select, is->select))) { + if (!ic->select || ic->select == is->select_folder) { c(printf("* queueing job %3d '%s'\n", (gint)ic->pri, ic->name)); pri = ic->pri; camel_dlist_remove((CamelDListNode *)ic); @@ -1068,20 +1070,19 @@ found: } static gboolean -imapx_job_matches (const gchar *folder_name, CamelIMAPXJob *job, guint32 type, const gchar *uid) +imapx_job_matches (CamelFolder *folder, CamelIMAPXJob *job, guint32 type, const gchar *uid) { switch (job->type) { case IMAPX_JOB_GET_MESSAGE: - if (folder_name && strcmp(job->folder->full_name, folder_name) == 0 - && strcmp(job->u.get_message.uid, uid) == 0) + if (folder == job->folder && + strcmp(job->u.get_message.uid, uid) == 0) return TRUE; break; case IMAPX_JOB_FETCH_NEW_MESSAGES: case IMAPX_JOB_REFRESH_INFO: case IMAPX_JOB_SYNC_CHANGES: case IMAPX_JOB_EXPUNGE: - if (folder_name - && strcmp(job->folder->full_name, folder_name) == 0) + if (folder == job->folder) return TRUE; break; case IMAPX_JOB_LIST: @@ -1105,7 +1106,7 @@ imapx_match_active_job (CamelIMAPXServer *is, guint32 type, const gchar *uid) if (!job || !(job->type & type)) continue; - if (imapx_job_matches (is->select, job, type, uid)) + if (imapx_job_matches (is->select_folder, job, type, uid)) goto found; } job = NULL; @@ -1115,7 +1116,7 @@ found: } static CamelIMAPXJob * -imapx_is_job_in_queue (CamelIMAPXServer *is, const gchar *folder_name, guint32 type, const gchar *uid) +imapx_is_job_in_queue (CamelIMAPXServer *is, CamelFolder *folder, guint32 type, const gchar *uid) { CamelDListNode *node; CamelIMAPXJob *job = NULL; @@ -1129,7 +1130,7 @@ imapx_is_job_in_queue (CamelIMAPXServer *is, const gchar *folder_name, guint32 t if (!job || !(job->type & type)) continue; - if (imapx_job_matches (folder_name, job, type, uid)) { + if (imapx_job_matches (folder, job, type, uid)) { found = TRUE; break; } @@ -1560,11 +1561,7 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex) case IMAPX_CLOSED: c(printf("previously selected folder is now closed\n")); if (imap->select_pending && !imap->select_folder) { - const gchar *full_name; imap->select_folder = imap->select_pending; - full_name = camel_folder_get_full_name (imap->select_folder); - - imap->select = g_strdup(full_name); } break; case IMAPX_READ_WRITE: @@ -1998,7 +1995,7 @@ imapx_job_idle_start(CamelIMAPXServer *is, CamelIMAPXJob *job) CamelIMAPXCommand *ic; CamelIMAPXCommandPart *cp; - ic = camel_imapx_command_new (is, "IDLE", job->folder->full_name, "IDLE"); + ic = camel_imapx_command_new (is, "IDLE", job->folder, "IDLE"); ic->job = job; ic->pri = job->pri; ic->complete = imapx_command_idle_done; @@ -2228,7 +2225,6 @@ imapx_idle_supported (CamelIMAPXServer *is) static void imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) { - if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) { CamelDList failed; CamelIMAPXCommand *cw, *cn; @@ -2242,7 +2238,9 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (is->select_pending) { while (cn) { - if (cw->select && strcmp(cw->select, is->select_pending->full_name) == 0) { + if (cw->select && cw->select == is->select_pending) { + c(printf("Cancelling command '%s'(%p) for folder '%s'\n", + cw->name, cw, camel_folder_get_full_name(cw->select))); camel_dlist_remove((CamelDListNode *)cw); camel_dlist_addtail(&failed, (CamelDListNode *)cw); } @@ -2269,11 +2267,9 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) camel_object_unref(is->select_pending); /* A [CLOSED] status may have caused us to assume that it had happened */ - if (is->select) { - g_free(is->select); - is->select = NULL; + if (is->select_folder) is->select_folder = NULL; - } + is->state = IMAPX_INITIALISED; } else { CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) is->select_pending; @@ -2282,7 +2278,6 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (!is->select_folder) { /* This could have been done earlier by a [CLOSED] status */ is->select_folder = is->select_pending; - is->select = g_strdup(is->select_folder->full_name); } is->state = IMAPX_SELECTED; ifolder->exists_on_server = is->exists; @@ -2326,7 +2321,7 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE if (is->select_pending) return; - if (is->select && strcmp(is->select, folder->full_name) == 0 && !forced) + if (is->select_folder == folder && !forced) return; if (!camel_dlist_empty(&is->active)) @@ -2335,15 +2330,12 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE is->select_pending = folder; camel_object_ref(folder); if (is->select_folder) { - g_free(is->select); camel_object_unref(is->select_folder); - is->select = NULL; is->select_folder = NULL; } else { /* If no folder was selected, we won't get a [CLOSED] status so just point select_folder at the new folder immediately */ is->select_folder = is->select_pending; - is->select = g_strdup(is->select_folder->full_name); } is->uidvalidity = 0; @@ -2910,7 +2902,7 @@ imapx_command_fetch_message_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (job->op) camel_operation_progress (job->op, (job->u.get_message.fetch_offset *100)/job->u.get_message.size); - ic = camel_imapx_command_new(is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE); camel_imapx_command_add(ic, ")"); @@ -2976,7 +2968,7 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) if (job->u.get_message.use_multi_fetch) { for (i=0; i < 3 && job->u.get_message.fetch_offset < job->u.get_message.size;i++) { - ic = camel_imapx_command_new(is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid); camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE); camel_imapx_command_add(ic, ")"); @@ -2988,7 +2980,7 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job) imapx_command_queue(is, ic); } } else { - ic = camel_imapx_command_new(is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH %t (BODY.PEEK[])", job->u.get_message.uid); ic->complete = imapx_command_fetch_message_done; ic->job = job; @@ -3007,7 +2999,7 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job GPtrArray *uids = job->u.copy_messages.uids; gint i = index; - ic = camel_imapx_command_new (is, "COPY", job->folder->full_name, "UID COPY "); + ic = camel_imapx_command_new (is, "COPY", job->folder, "UID COPY "); ic->complete = imapx_command_copy_messages_step_done; ic->job = job; ic->pri = job->pri; @@ -3268,7 +3260,7 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic) if (i<infos->len) { camel_imapx_command_free (ic); - ic = camel_imapx_command_new(is, "FETCH", job->folder->full_name, "UID FETCH "); + ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH "); ic->complete = imapx_command_step_fetch_done; ic->job = job; ic->pri = job->pri - 1; @@ -3493,9 +3485,11 @@ imapx_job_scan_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job) { CamelIMAPXCommand *ic; - camel_operation_start (job->op, _("Scanning for changed messages in %s"), job->folder->name); + camel_operation_start ( + job->op, _("Scanning for changed messages in %s"), + job->folder->name); - ic = camel_imapx_command_new (is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new (is, "FETCH", job->folder, "UID FETCH 1:* (UID FLAGS)"); ic->job = job; ic->complete = imapx_job_scan_changes_done; @@ -3557,14 +3551,14 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job) camel_operation_start (job->op, _("Fetching summary information for new messages in %s"), folder->name); if (diff > BATCH_FETCH_COUNT) { - ic = camel_imapx_command_new (is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new (is, "FETCH", job->folder, "UID FETCH %s:* (UID FLAGS)", uid); imapx_uidset_init(&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0); job->u.refresh_info.infos = g_array_new (0, 0, sizeof(struct _refresh_info)); ic->pri = job->pri; ic->complete = imapx_command_step_fetch_done; } else { - ic = camel_imapx_command_new (is, "FETCH", job->folder->full_name, + ic = camel_imapx_command_new (is, "FETCH", job->folder, "UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid); ic->pri = job->pri; ic->complete = imapx_command_fetch_new_messages_done; @@ -3594,7 +3588,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job) #if 0 /* There are issues with this still; continue with the buggy behaviour where we issue STATUS on the current folder, for now...*/ - if (is->select && !strcmp(folder->full_name, is->select)) + if (is->select_folder == folder) is_selected = TRUE; #endif total = camel_folder_summary_count (folder->summary); @@ -3759,7 +3753,7 @@ imapx_job_expunge_start(CamelIMAPXServer *is, CamelIMAPXJob *job) imapx_server_sync_changes (is, job->folder, job->pri, job->ex); /* TODO handle UIDPLUS capability */ - ic = camel_imapx_command_new(is, "EXPUNGE", job->folder->full_name, "EXPUNGE"); + ic = camel_imapx_command_new(is, "EXPUNGE", job->folder, "EXPUNGE"); ic->job = job; ic->pri = job->pri; ic->complete = imapx_command_expunge_done; @@ -3914,7 +3908,7 @@ imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) job->folder = camel_store_get_folder(is->store, "INBOX", 0, job->ex); /* make sure to-be-deleted folder is not selected by selecting INBOX for this operation */ - ic = camel_imapx_command_new (is, "DELETE", "INBOX", "DELETE %s", encoded_fname); + ic = camel_imapx_command_new (is, "DELETE", job->folder, "DELETE %s", encoded_fname); ic->pri = job->pri; ic->job = job; ic->complete = imapx_command_delete_folder_done; @@ -3950,7 +3944,7 @@ imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job) en_ofname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.ofolder_name); en_nfname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.nfolder_name); - ic = camel_imapx_command_new (is, "RENAME", "INBOX", "RENAME %s %s", en_ofname, en_nfname); + ic = camel_imapx_command_new (is, "RENAME", job->folder, "RENAME %s %s", en_ofname, en_nfname); ic->pri = job->pri; ic->job = job; ic->complete = imapx_command_rename_folder_done; @@ -3981,10 +3975,7 @@ imapx_job_noop_start(CamelIMAPXServer *is, CamelIMAPXJob *job) { CamelIMAPXCommand *ic; - if (job->folder) - ic = camel_imapx_command_new (is, "NOOP", job->folder->full_name, "NOOP"); - else - ic = camel_imapx_command_new (is, "NOOP", NULL, "NOOP"); + ic = camel_imapx_command_new (is, "NOOP", job->folder, "NOOP"); ic->job = job; ic->complete = imapx_command_noop_done; @@ -4131,7 +4122,7 @@ imapx_job_sync_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job) if ( (on && (((flags ^ sflags) & flags) & flag)) || (!on && (((flags ^ sflags) & ~flags) & flag))) { if (ic == NULL) { - ic = camel_imapx_command_new(is, "STORE", job->folder->full_name, "UID STORE "); + ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE "); ic->complete = imapx_command_sync_changes_done; ic->job = job; ic->pri = job->pri; @@ -4159,7 +4150,7 @@ imapx_job_sync_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job) CamelIMAPXMessageInfo *info = c->infos->pdata[i]; if (ic == NULL) { - ic = camel_imapx_command_new(is, "STORE", job->folder->full_name, "UID STORE "); + ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE "); ic->complete = imapx_command_sync_changes_done; ic->job = job; ic->pri = job->pri; @@ -4469,11 +4460,6 @@ imapx_disconnect (CamelIMAPXServer *is) is->select_folder = NULL; } - if (is->select) { - g_free(is->select); - is->select = NULL; - } - if (is->select_pending) { camel_object_unref(is->select_pending); is->select_pending = NULL; @@ -4532,7 +4518,7 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperat QUEUE_LOCK (is); - if ((job = imapx_is_job_in_queue (is, folder->full_name, IMAPX_JOB_GET_MESSAGE, uid))) { + if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_GET_MESSAGE, uid))) { flag = g_hash_table_lookup (is->uid_eflags, uid); if (pri > job->pri) @@ -4741,7 +4727,7 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, Came QUEUE_LOCK (is); - if (imapx_is_job_in_queue (is, folder->full_name, IMAPX_JOB_REFRESH_INFO, NULL)) { + if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL)) { QUEUE_UNLOCK (is); return; } @@ -4913,7 +4899,7 @@ imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, gint pri, C QUEUE_LOCK (is); - if ((job = imapx_is_job_in_queue (is, folder->full_name, IMAPX_JOB_SYNC_CHANGES, NULL))) { + if ((job = imapx_is_job_in_queue (is, folder, IMAPX_JOB_SYNC_CHANGES, NULL))) { if (pri > job->pri) job->pri = pri; @@ -4965,7 +4951,7 @@ camel_imapx_server_expunge(CamelIMAPXServer *is, CamelFolder *folder, CamelExcep /* Do we really care to wait for this one to finish? */ QUEUE_LOCK (is); - if (imapx_is_job_in_queue (is, folder->full_name, IMAPX_JOB_EXPUNGE, NULL)) { + if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_EXPUNGE, NULL)) { QUEUE_UNLOCK (is); return; } diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h index e72a245b5..824e123ce 100644 --- a/camel/providers/imapx/camel-imapx-server.h +++ b/camel/providers/imapx/camel-imapx-server.h @@ -75,7 +75,6 @@ struct _CamelIMAPXServer { /* info on currently selected folder */ struct _CamelFolder *select_folder; - gchar *select; struct _CamelFolderChangeInfo *changes; struct _CamelFolder *select_pending; guint32 permanentflags; |