static gint mbox_folder_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2) { CamelMboxMessageInfo *a, *b; gint res; g_return_val_if_fail (folder != NULL, 0); g_return_val_if_fail (folder->summary != NULL, 0); a = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid1); b = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid2); if (!a || !b) { /* It's not a problem when one of the messages is not in the summary */ if (a) camel_message_info_unref (a); if (b) camel_message_info_unref (b); if (a == b) return 0; if (!a) return -1; return 1; } res = a->frompos < b->frompos ? -1 : a->frompos == b->frompos ? 0 : 1; camel_message_info_unref (a); camel_message_info_unref (b); return res; }
static gboolean vee_info_set_user_flag (CamelMessageInfo *mi, const gchar *name, gboolean value) { gint res = FALSE; CamelVeeFolder *vf = (CamelVeeFolder *) camel_folder_summary_get_folder (mi->summary); if (camel_debug("vfolderexp")) printf ( "Expression for vfolder '%s' is '%s'\n", camel_folder_get_full_name (camel_folder_summary_get_folder (mi->summary)), g_strescape (vf->expression, "")); if (mi->uid) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); HANDLE_NULL_INFO (FALSE); /* ignore changes done in the folder itself, * unless it's a vTrash or vJunk folder */ if (!CAMEL_IS_VTRASH_FOLDER (vf)) camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary)); res = camel_message_info_set_user_flag (rmi, name, value); camel_message_info_free (rmi); } return res; }
static gint exchange_entry_play_append (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, GCancellable *cancellable, GError **error) { CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder; CamelFolder *folder = journal->folder; CamelMimeMessage *message; CamelMessageInfo *info, *real; CamelStream *stream; gchar *uid = NULL; /* if the message isn't in the cache, the user went behind our backs so "not our problem" */ if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, NULL))) goto done; message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ( (CamelDataWrapper *) message, stream, cancellable, NULL)) { g_object_unref (message); g_object_unref (stream); goto done; } g_object_unref (stream); if (!(info = camel_folder_summary_get (folder->summary, entry->uid))) { /* Should have never happened, but create a new info to avoid further crashes */ info = camel_message_info_new (NULL); } if (!camel_folder_append_message_sync ( folder, message, info, &uid, cancellable, error)) return -1; real = camel_folder_summary_info_new_from_message (folder->summary, message, NULL); g_object_unref (message); if (uid != NULL && real) { real->uid = camel_pstring_strdup (uid); exchange_message_info_dup_to ((CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info); camel_folder_summary_add (folder->summary, real); /* FIXME: should a folder_changed event be triggered? */ } camel_message_info_free (info); g_free (uid); done: camel_exchange_folder_remove_message (exchange_folder, entry->uid); return 0; }
static time_t vee_info_time (const CamelMessageInfo *mi, gint id) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); time_t ret; HANDLE_NULL_INFO (0); ret = camel_message_info_time (rmi, id); camel_message_info_free (rmi); return ret; }
static gint mbox_folder_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2) { CamelMboxMessageInfo *a, *b; goffset aoffset, boffset; gint res; g_return_val_if_fail (folder != NULL, 0); g_return_val_if_fail (camel_folder_get_folder_summary (folder) != NULL, 0); a = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid1); b = (CamelMboxMessageInfo *) camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid2); if (!a || !b) { /* It's not a problem when one of the messages is not in the summary */ if (a) g_object_unref (a); if (b) g_object_unref (b); if (a == b) return 0; if (!a) return -1; return 1; } aoffset = camel_mbox_message_info_get_offset (a); boffset = camel_mbox_message_info_get_offset (b); res = aoffset < boffset ? -1 : aoffset == boffset ? 0 : 1; g_clear_object (&a); g_clear_object (&b); return res; }
static const gchar * vee_info_user_tag (const CamelMessageInfo *mi, const gchar *id) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); const gchar *ret; HANDLE_NULL_INFO(""); ret = camel_message_info_user_tag (rmi, id); camel_message_info_free (rmi); return ret; }
static gint maildir_folder_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2) { CamelMessageInfo *a, *b; time_t tma, tmb; g_return_val_if_fail (folder != NULL, 0); g_return_val_if_fail (folder->summary != NULL, 0); a = camel_folder_summary_get (folder->summary, uid1); b = camel_folder_summary_get (folder->summary, uid2); if (!a || !b) { /* It's not a problem when one of the messages is not in the summary */ if (a) camel_message_info_unref (a); if (b) camel_message_info_unref (b); if (a == b) return 0; if (!a) return -1; return 1; } tma = camel_message_info_get_date_received (a); tmb = camel_message_info_get_date_received (b); camel_message_info_unref (a); camel_message_info_unref (b); return tma < tmb ? -1 : tma == tmb ? 0 : 1; }
static gconstpointer vee_info_ptr (const CamelMessageInfo *mi, gint id) { CamelVeeMessageInfo *vmi = (CamelVeeMessageInfo *) mi; CamelMessageInfo *rmi; gpointer p; rmi = camel_folder_summary_get (vmi->orig_summary, mi->uid + 8); HANDLE_NULL_INFO (NULL); p = (gpointer) camel_message_info_ptr (rmi, id); camel_message_info_free (rmi); return p; }
static gchar * mbox_folder_get_filename (CamelFolder *folder, const gchar *uid, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelMboxMessageInfo *info; goffset frompos; gchar *filename = NULL; d (printf ("Getting message %s\n", uid)); /* lock the folder first, burn if we can't, need write lock for summary check */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; /* check for new messages always */ if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, NULL, error) == -1) { camel_local_folder_unlock (lf); return NULL; } /* get the message summary info */ info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid); if (info == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); goto fail; } if (info->frompos == -1) { camel_message_info_unref (info); goto fail; } frompos = info->frompos; camel_message_info_unref (info); filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos); fail: /* and unlock now we're finished with it */ camel_local_folder_unlock (lf); return filename; }
static void unset_flagged_flag (const gchar *uid, CamelFolderSummary *summary) { CamelMessageInfo *info; info = camel_folder_summary_get (summary, uid); if (info) { CamelMessageInfoBase *base = (CamelMessageInfoBase *) info; if ((base->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) { base->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; base->dirty = TRUE; } camel_message_info_unref (info); } }
static gboolean nntp_folder_expunge_sync (CamelFolder *folder, GCancellable *cancellable, GError **error) { CamelFolderSummary *summary; CamelFolderChangeInfo *changes; GPtrArray *known_uids; guint ii; summary = folder->summary; camel_folder_summary_prepare_fetch_all (summary, NULL); known_uids = camel_folder_summary_get_array (summary); if (known_uids == NULL) return TRUE; changes = camel_folder_change_info_new (); for (ii = 0; ii < known_uids->len; ii++) { CamelMessageInfo *info; const gchar *uid; uid = g_ptr_array_index (known_uids, ii); info = camel_folder_summary_get (summary, uid); if (camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED) { camel_folder_change_info_remove_uid (changes, uid); camel_folder_summary_remove (summary, info); } camel_message_info_unref (info); } camel_folder_summary_save_to_db (summary, NULL); camel_folder_changed (folder, changes); camel_folder_change_info_free (changes); camel_folder_summary_free_array (known_uids); return TRUE; }
static gboolean vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) { gint res = FALSE; CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary)); if (camel_debug("vfolderexp")) printf ( "Expression for vfolder '%s' is '%s'\n", camel_folder_get_full_name (CAMEL_FOLDER (vf)), g_strescape (vf->expression, "")); /* first update original message info... */ if (mi->uid) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); HANDLE_NULL_INFO (FALSE); /* ignore changes done in the folder itself, * unless it's a vTrash or vJunk folder */ if (!CAMEL_IS_VTRASH_FOLDER (vf)) camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary)); camel_folder_freeze (camel_folder_summary_get_folder (rmi->summary)); res = camel_message_info_set_flags (rmi, flags, set); ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi); camel_folder_thaw (camel_folder_summary_get_folder (rmi->summary)); camel_message_info_free (rmi); } if (res) CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags, set); return res; }
static gboolean vee_info_set_user_tag (CamelMessageInfo *mi, const gchar *name, const gchar *value) { gint res = FALSE; if (mi->uid) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); CamelFolder *folder = camel_folder_summary_get_folder (mi->summary); HANDLE_NULL_INFO (FALSE); /* ignore changes done in the folder itself, * unless it's a vTrash or vJunk folder */ if (!CAMEL_IS_VTRASH_FOLDER (folder)) camel_vee_folder_ignore_next_changed_event ((CamelVeeFolder *) folder, camel_folder_summary_get_folder (rmi->summary)); res = camel_message_info_set_user_tag (rmi, name, value); camel_message_info_free (rmi); } return res; }
static CamelMimeMessage * mh_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelStream *message_stream = NULL; CamelMimeMessage *message = NULL; CamelMessageInfo *info; gchar *name = NULL; d(printf("getting message: %s\n", uid)); if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; /* get the message summary info */ if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); goto fail; } /* we only need it to check the message exists */ camel_message_info_free (info); name = g_strdup_printf("%s/%s", lf->folder_path, uid); message_stream = camel_stream_fs_new_with_name ( name, O_RDONLY, 0, error); if (message_stream == NULL) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), name, lf->folder_path); goto fail; } message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ( (CamelDataWrapper *) message, message_stream, cancellable, error)) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), name, lf->folder_path); g_object_unref (message); message = NULL; } g_object_unref (message_stream); fail: g_free (name); camel_local_folder_unlock (lf); if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return message; }
static gint exchange_entry_play_transfer (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, GCancellable *cancellable, GError **error) { CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder; CamelFolder *folder = journal->folder; CamelMessageInfo *info, *real; GPtrArray *xuids, *uids; CamelFolder *src; CamelExchangeStore *store; CamelStream *stream; CamelMimeMessage *message; CamelStore *parent_store; if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, NULL))) goto done; message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ( (CamelDataWrapper *) message, stream, cancellable, NULL)) { g_object_unref (message); g_object_unref (stream); goto done; } g_object_unref (stream); if (!(info = camel_folder_summary_get (folder->summary, entry->uid))) { /* Note: this should never happen, but rather than crash lets make a new info */ info = camel_message_info_new (NULL); } if (!entry->folder_name) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("No folder name found")); goto exception; } parent_store = camel_folder_get_parent_store (folder); store = CAMEL_EXCHANGE_STORE (parent_store); g_mutex_lock (store->folders_lock); src = (CamelFolder *) g_hash_table_lookup (store->folders, entry->folder_name); g_mutex_unlock (store->folders_lock); if (src) { gboolean success; uids = g_ptr_array_sized_new (1); g_ptr_array_add (uids, entry->original_uid); success = camel_folder_transfer_messages_to_sync ( src, uids, folder, entry->delete_original, &xuids, cancellable, error); if (!success) goto exception; real = camel_folder_summary_info_new_from_message ( folder->summary, message, NULL); g_object_unref (message); real->uid = camel_pstring_strdup ( (gchar *) xuids->pdata[0]); /* Transfer flags */ exchange_message_info_dup_to ( (CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info); camel_folder_summary_add (folder->summary, real); /* FIXME: should a folder_changed event be triggered? */ g_ptr_array_free (xuids, TRUE); g_ptr_array_free (uids, TRUE); /* g_object_unref (src); FIXME: should we? */ } else { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Folder doesn't exist")); goto exception; } camel_message_info_free (info); done: camel_exchange_folder_remove_message (exchange_folder, entry->uid); return 0; exception: camel_message_info_free (info); return -1; }
static gchar * maildir_folder_get_filename (CamelFolder *folder, const gchar *uid, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelMaildirMessageInfo *mdi; CamelMessageInfo *info; gchar *res; /* get the message summary info */ if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); return NULL; } mdi = (CamelMaildirMessageInfo *) info; /* If filename is NULL, it means folder_summary_check is not yet executed. * Try to find the file in the folder and use it, otherwise construct its * name based on actual flags. */ if (!camel_maildir_info_filename (mdi)) { const gchar *uid = camel_message_info_get_uid (info); if (uid) { GDir *dir; gchar *dirname; dirname = g_strdup_printf ("%s/cur", lf->folder_path); dir = g_dir_open (dirname, 0, NULL); g_free (dirname); if (dir) { const gchar *filename; gint uid_len = strlen (uid); while (filename = g_dir_read_name (dir), filename) { if (g_str_has_prefix (filename, uid) && (filename[uid_len] == '\0' || filename[uid_len] == CAMEL_MAILDIR_FLAG_SEP)) { camel_maildir_info_set_filename (mdi, g_strdup (filename)); break; } } g_dir_close (dir); } } if (!camel_maildir_info_filename (mdi)) { camel_maildir_info_set_filename (mdi, camel_maildir_summary_info_to_name (mdi)); } } res = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); camel_message_info_unref (info); return res; }
static gboolean maildir_folder_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, GPtrArray **transferred_uids, GCancellable *cancellable, GError **error) { gboolean fallback = FALSE; if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest) && camel_folder_get_parent_store (source) == camel_folder_get_parent_store (dest)) { gint i; CamelLocalFolder *lf = (CamelLocalFolder *) source; CamelLocalFolder *df = (CamelLocalFolder *) dest; camel_operation_push_message ( cancellable, _("Moving messages")); camel_folder_freeze (dest); camel_folder_freeze (source); for (i = 0; i < uids->len; i++) { gchar *uid = (gchar *) uids->pdata[i]; gchar *s_filename, *d_filename, *new_filename; CamelMaildirMessageInfo *mdi; CamelMessageInfo *info; if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); return FALSE; } mdi = (CamelMaildirMessageInfo *) info; new_filename = camel_maildir_summary_info_to_name (mdi); d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename); s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (s_filename, d_filename) != 0) { if (errno == EXDEV) { i = uids->len + 1; fallback = TRUE; } else { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Cannot transfer message to destination folder: %s"), g_strerror (errno)); camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); break; } } else { CamelMessageInfo *clone; CamelMaildirMessageInfo *mclone; clone = camel_message_info_clone (info); clone->summary = dest->summary; mclone = (CamelMaildirMessageInfo *) clone; /* preserve also UID, as it matches the file name */ mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid (info)); camel_maildir_info_set_filename (clone, g_strdup (new_filename)); /* unset deleted flag when transferring from trash folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0); /* unset junk flag when transferring from junk folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0); camel_folder_summary_add (dest->summary, clone); camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid (clone)); camel_folder_set_message_flags ( source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info)); camel_folder_summary_remove (source->summary, info); } camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); } if (lf && camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (source, lf->changes); camel_folder_change_info_clear (lf->changes); } if (df && camel_folder_change_info_changed (df->changes)) { camel_folder_changed (dest, df->changes); camel_folder_change_info_clear (df->changes); } camel_folder_thaw (source); camel_folder_thaw (dest); camel_operation_pop_message (cancellable); } else fallback = TRUE; if (fallback) { CamelFolderClass *folder_class; /* Chain up to parent's transfer_messages_to() method. */ folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class); return folder_class->transfer_messages_to_sync ( source, uids, dest, delete_originals, transferred_uids, cancellable, error); } return TRUE; }
static CamelMimeMessage * mbox_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelMimeMessage *message = NULL; CamelMboxMessageInfo *info; CamelMimeParser *parser = NULL; gint fd, retval; gint retried = FALSE; goffset frompos; d (printf ("Getting message %s\n", uid)); /* lock the folder first, burn if we can't, need write lock for summary check */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; /* check for new messages always */ if (camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error) == -1) { camel_local_folder_unlock (lf); return NULL; } retry: /* get the message summary info */ info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid); if (info == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); goto fail; } if (info->frompos == -1) { camel_message_info_unref (info); goto fail; } frompos = info->frompos; camel_message_info_unref (info); /* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache * the whole message in memory if the stream is non-seekable (which it is when built from a parser * with no stream). This means we dont have to lock the mbox for the life of the message, but only * while it is being created. */ fd = g_open (lf->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0); if (fd == -1) { set_cannot_get_message_ex ( error, CAMEL_ERROR_GENERIC, uid, lf->folder_path, g_strerror (errno)); goto fail; } /* we use a parser to verify the message is correct, and in the correct position */ parser = camel_mime_parser_new (); camel_mime_parser_init_with_fd (parser, fd); camel_mime_parser_scan_from (parser, TRUE); camel_mime_parser_seek (parser, frompos, SEEK_SET); if (camel_mime_parser_step (parser, NULL, NULL) != CAMEL_MIME_PARSER_STATE_FROM || camel_mime_parser_tell_start_from (parser) != frompos) { g_warning ("Summary doesn't match the folder contents! eek!\n" " expecting offset %ld got %ld, state = %d", (glong) frompos, (glong) camel_mime_parser_tell_start_from (parser), camel_mime_parser_state (parser)); g_object_unref (parser); parser = NULL; if (!retried) { retried = TRUE; camel_local_summary_check_force ((CamelLocalSummary *) folder->summary); retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error); if (retval != -1) goto retry; } set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID, uid, lf->folder_path, _("The folder appears to be irrecoverably corrupted.")); goto fail; } message = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) message, parser, cancellable, error)) { g_prefix_error ( error, _("Cannot get message %s from folder %s: "), uid, lf->folder_path); g_object_unref (message); message = NULL; goto fail; } camel_medium_remove_header ((CamelMedium *) message, "X-Evolution"); fail: /* and unlock now we're finished with it */ camel_local_folder_unlock (lf); if (parser) g_object_unref (parser); /* use the opportunity to notify of changes (particularly if we had a rebuild) */ if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return message; }
void camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder, EEwsConnection *cnc, GSList *items_created, CamelFolderChangeInfo *change_info, GCancellable *cancellable) { CamelFolder *folder; CamelFolderSummary *folder_summary; GSList *l; if (!items_created) return; folder = CAMEL_FOLDER (ews_folder); folder_summary = camel_folder_get_folder_summary (folder); for (l = items_created; l != NULL; l = g_slist_next (l)) { EEwsItem *item = (EEwsItem *) l->data; CamelMessageInfo *mi; const EwsId *id; const EwsMailbox *from; gchar *tmp; EEwsItemType item_type; const gchar *msg_headers; gboolean has_attachments, found_property, message_requests_read_receipt = FALSE; guint32 server_flags; if (!item) continue; if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) { g_object_unref (item); continue; } id = e_ews_item_get_id (item); if (!id) { g_warning ("%s: Missing ItemId for item type %d (subject:%s)", G_STRFUNC, e_ews_item_get_item_type (item), e_ews_item_get_subject (item) ? e_ews_item_get_subject (item) : "???"); g_object_unref (item); continue; } mi = camel_folder_summary_get (folder_summary, id->id); if (mi) { g_clear_object (&mi); g_object_unref (item); continue; } /* PidTagTransportMessageHeaders */ found_property = FALSE; msg_headers = e_ews_item_get_extended_property_as_string (item, NULL, 0x007D, &found_property); if (!found_property) msg_headers = NULL; if (msg_headers && *msg_headers) { CamelMimePart *part = camel_mime_part_new (); CamelStream *stream; CamelMimeParser *parser; stream = camel_stream_mem_new_with_buffer (msg_headers, strlen (msg_headers)); parser = camel_mime_parser_new (); camel_mime_parser_init_with_stream (parser, stream, NULL); camel_mime_parser_scan_from (parser, FALSE); g_object_unref (stream); if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) { mi = camel_folder_summary_info_new_from_headers (folder_summary, camel_medium_get_headers (CAMEL_MEDIUM (part))); if (camel_medium_get_header (CAMEL_MEDIUM (part), "Disposition-Notification-To")) message_requests_read_receipt = TRUE; } g_object_unref (parser); g_object_unref (part); } if (!mi) mi = camel_message_info_new (folder_summary); camel_message_info_set_abort_notifications (mi, TRUE); item_type = e_ews_item_get_item_type (item); if (item_type == E_EWS_ITEM_TYPE_EVENT || item_type == E_EWS_ITEM_TYPE_MEETING_MESSAGE || item_type == E_EWS_ITEM_TYPE_MEETING_REQUEST || item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE || item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE) camel_message_info_set_user_flag (mi, "$has_cal", TRUE); camel_message_info_set_uid (mi, id->id); camel_message_info_set_size (mi, e_ews_item_get_size (item)); camel_message_info_set_subject (mi, e_ews_item_get_subject (item)); camel_ews_message_info_set_item_type (CAMEL_EWS_MESSAGE_INFO (mi), item_type); camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key); camel_message_info_set_date_sent (mi, e_ews_item_get_date_sent (item)); camel_message_info_set_date_received (mi, e_ews_item_get_date_received (item)); from = e_ews_item_get_from (item); if (!from) from = e_ews_item_get_sender (item); tmp = form_email_string_from_mb (cnc, from, cancellable); camel_message_info_set_from (mi, tmp); g_free (tmp); tmp = form_recipient_list (cnc, e_ews_item_get_to_recipients (item), cancellable); camel_message_info_set_to (mi, tmp); g_free (tmp); tmp = form_recipient_list (cnc, e_ews_item_get_cc_recipients (item), cancellable); camel_message_info_set_cc (mi, tmp); g_free (tmp); e_ews_item_has_attachments (item, &has_attachments); if (has_attachments) camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS); ews_set_threading_data (mi, item); server_flags = ews_utils_get_server_flags (item); ews_utils_merge_server_user_flags (item, mi); camel_message_info_set_flags (mi, server_flags, server_flags); camel_ews_message_info_set_server_flags (CAMEL_EWS_MESSAGE_INFO (mi), server_flags); camel_ews_utils_update_follow_up_flags (item, mi); camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, message_requests_read_receipt); camel_message_info_set_abort_notifications (mi, FALSE); camel_folder_summary_add (folder_summary, mi, FALSE); /* camel_folder_summary_add() sets folder_flagged flag * on the message info, but this is a fresh item downloaded * from the server, thus unset it, to avoid resync up to the server * on folder leave/store */ camel_message_info_set_folder_flagged (mi, FALSE); camel_folder_change_info_add_uid (change_info, id->id); camel_folder_change_info_recent_uid (change_info, id->id); g_object_unref (mi); g_object_unref (item); } g_slist_free (items_created); }
void camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder, GSList *items_updated, CamelFolderChangeInfo *change_info) { CamelFolder *folder; CamelFolderSummary *folder_summary; GSList *l; folder = CAMEL_FOLDER (ews_folder); folder_summary = camel_folder_get_folder_summary (folder); for (l = items_updated; l != NULL; l = g_slist_next (l)) { EEwsItem *item = (EEwsItem *) l->data; const EwsId *id; CamelMessageInfo *mi; if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) { g_object_unref (item); continue; } id = e_ews_item_get_id (item); if (!id) { g_warning ("%s: Missing ItemId for item type %d (subject:%s)", G_STRFUNC, e_ews_item_get_item_type (item), e_ews_item_get_subject (item) ? e_ews_item_get_subject (item) : "???"); g_object_unref (item); continue; } mi = camel_folder_summary_get (folder_summary, id->id); if (mi) { guint32 server_flags; gboolean changed, was_changed; camel_message_info_freeze_notifications (mi); was_changed = camel_message_info_get_folder_flagged (mi); server_flags = ews_utils_get_server_flags (item); ews_utils_merge_server_user_flags (item, mi); changed = camel_ews_update_message_info_flags (folder_summary, mi, server_flags, NULL); changed = camel_ews_utils_update_follow_up_flags (item, mi) || changed; changed = camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, FALSE) || changed; if (changed) camel_folder_change_info_change_uid (change_info, id->id); camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key); if (!was_changed) { /* do not save to the server what was just read, when did not change locally before */ camel_message_info_set_folder_flagged (mi, FALSE); } camel_message_info_thaw_notifications (mi); g_clear_object (&mi); g_object_unref (item); continue; } g_object_unref (item); } g_slist_free (items_updated); }