static int untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex) { struct imap4_fetch_all_t *fetch = ic->user_data; CamelFolderSummary *summary = fetch->summary; struct imap4_envelope_t *envelope = NULL; GPtrArray *added = fetch->added; CamelIMAP4MessageInfo *iinfo; CamelMessageInfo *info; guint32 changed = 0; const char *iuid; char uid[12]; if (index < fetch->first) { /* we already have this message envelope cached - * server is probably notifying us of a FLAGS change * by another client? */ g_assert (index < summary->messages->len); iinfo = (CamelIMAP4MessageInfo *)(info = summary->messages->pdata[index - 1]); g_assert (info != NULL); } else { if (index > (added->len + fetch->first - 1)) g_ptr_array_set_size (added, index - fetch->first + 1); if (!(envelope = added->pdata[index - fetch->first])) { iinfo = (CamelIMAP4MessageInfo *) (info = camel_message_info_new (summary)); envelope = g_new (struct imap4_envelope_t, 1); added->pdata[index - fetch->first] = envelope; envelope->info = info; envelope->changed = 0; } else {
static void import_mbox_add_message (CamelFolder *folder, CamelMimeMessage *msg, GCancellable *cancellable, GError **error) { CamelMessageInfo *info; CamelMedium *medium; guint32 flags = 0; const gchar *tmp; g_return_if_fail (CAMEL_IS_FOLDER (folder)); g_return_if_fail (CAMEL_IS_MIME_MESSAGE (msg)); medium = CAMEL_MEDIUM (msg); tmp = camel_medium_get_header (medium, "X-Mozilla-Status"); if (tmp) flags |= decode_mozilla_status (tmp); tmp = camel_medium_get_header (medium, "Status"); if (tmp) flags |= decode_status (tmp); tmp = camel_medium_get_header (medium, "X-Status"); if (tmp) flags |= decode_status (tmp); info = camel_message_info_new (NULL); camel_message_info_set_flags (info, flags, ~0); camel_folder_append_message_sync ( folder, msg, info, NULL, cancellable, error); camel_message_info_unref (info); }
/** * mail_importer_add_line: * importer: A MailImporter structure. * str: Next line of the mbox. * finished: TRUE if @str is the last line of the message. * * Adds lines to the message until it is finished, and then adds * the complete message to the folder. */ void mail_importer_add_line (MailImporter *importer, const char *str, gboolean finished) { CamelMimeMessage *msg; CamelMessageInfo *info; CamelException *ex; if (importer->mstream == NULL) importer->mstream = CAMEL_STREAM_MEM (camel_stream_mem_new ()); camel_stream_write (CAMEL_STREAM (importer->mstream), str, strlen (str)); if (finished == FALSE) return; camel_stream_reset (CAMEL_STREAM (importer->mstream)); info = camel_message_info_new(NULL); camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0); msg = camel_mime_message_new (); camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), CAMEL_STREAM (importer->mstream)); camel_object_unref (importer->mstream); importer->mstream = NULL; ex = camel_exception_new (); camel_folder_append_message (importer->folder, msg, info, NULL, ex); camel_object_unref (msg); camel_exception_free (ex); camel_message_info_free(info); }
static int groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, CamelException *ex) { CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder; CamelFolder *folder = journal->folder; CamelGroupwiseMessageInfo *real; CamelMessageInfoBase *info; GPtrArray *xuids, *uids; CamelException lex; CamelFolder *src; const char *name; if (!(info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, entry->uid))) { /* Note: this should never happen, but rather than crash lets make a new info */ info = camel_message_info_new (NULL); } name = camel_groupwise_store_folder_lookup ((CamelGroupwiseStore *) folder->parent_store, entry->source_container); if (name && (src = camel_store_get_folder (folder->parent_store, name, 0, ex))) { uids = g_ptr_array_sized_new (1); g_ptr_array_add (uids, entry->original_uid); camel_exception_init (&lex); camel_folder_transfer_messages_to (src, uids, folder, &xuids, FALSE, &lex); if (!camel_exception_is_set (&lex)) { real = (CamelGroupwiseMessageInfo *) camel_folder_summary_uid (folder->summary, xuids->pdata[0]); /* transfer all the system flags, user flags/tags, etc */ gw_message_info_dup_to ((CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info); camel_message_info_free (real); } else { camel_exception_xfer (ex, &lex); goto exception; } g_ptr_array_free (xuids, TRUE); g_ptr_array_free (uids, TRUE); camel_object_unref (src); } else if (!name) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get folder container %s"), entry->source_container); goto exception; } /* message was successfully transferred, remove the fake item from the cache/summary */ camel_folder_summary_remove_uid (folder->summary, entry->uid); camel_data_cache_remove (gw_folder->cache, "cache", entry->uid, NULL); camel_message_info_free (info); return 0; exception: camel_message_info_free (info); return -1; }
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 CamelMessageInfo * vee_message_info_clone (CamelFolderSummary *s, const CamelMessageInfo *mi) { CamelVeeMessageInfo *to; const CamelVeeMessageInfo *from = (const CamelVeeMessageInfo *)mi; to = (CamelVeeMessageInfo *)camel_message_info_new (s); to->summary = g_object_ref (from->summary); to->info.summary = s; to->info.uid = camel_pstring_strdup (from->info.uid); return (CamelMessageInfo *)to; }
static int groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, CamelException *ex) { CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder; CamelFolder *folder = journal->folder; CamelMimeMessage *message; CamelMessageInfo *info; CamelStream *stream; CamelException lex; /* if the message isn't in the cache, the user went behind our backs so "not our problem" */ if (!gw_folder->cache || !(stream = camel_data_cache_get (gw_folder->cache, "cache", entry->uid, ex))) goto done; message = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) { camel_object_unref (message); camel_object_unref (stream); goto done; } camel_object_unref (stream); if (!(info = camel_folder_summary_uid (folder->summary, entry->uid))) { /* Note: this should never happen, but rather than crash lets make a new info */ info = camel_message_info_new (NULL); } camel_exception_init (&lex); camel_folder_append_message (folder, message, info, NULL, &lex); camel_message_info_free (info); camel_object_unref (message); if (camel_exception_is_set (&lex)) { camel_exception_xfer (ex, &lex); return -1; } done: camel_folder_summary_remove_uid (folder->summary, entry->uid); camel_data_cache_remove (gw_folder->cache, "cache", entry->uid, NULL); return 0; }
static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *s, const gchar *uid) { CamelMessageInfo *info; /* FIXME[disk-summary] too bad design. Need to peek it from cfs * instead of hacking ugly like this */ camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK); info = g_hash_table_lookup (s->loaded_infos, uid); if (info) camel_message_info_ref (info); camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK); if (!info) { CamelVeeMessageInfo *vinfo; gchar tmphash[9]; /* This function isn't really nice. But no great way * But in vfolder case, this may not be so bad, as vuid has the hash in first 8 bytes. * So this just compares the entire string only if it belongs to the same folder. * Otherwise, the first byte itself would return in strcmp, saving the CPU. */ if (!camel_folder_summary_check_uid (s, uid)) { d(g_message ("Unable to find %s in the summary of %s", uid, s->folder->full_name)); return NULL; } /* Create the info and load it, its so easy. */ info = camel_message_info_new (s); camel_message_info_ref (info); info->dirty = FALSE; vinfo = (CamelVeeMessageInfo *) info; info->uid = camel_pstring_strdup (uid); strncpy (tmphash, uid, 8); tmphash[8] = 0; vinfo->summary = g_hash_table_lookup (((CamelVeeFolder *) s->folder)->hashes, tmphash); g_object_ref (vinfo->summary); camel_folder_summary_insert (s, info, FALSE); } return info; }
static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *s, const gchar *uid) { CamelMessageInfo *info; info = camel_folder_summary_peek_loaded (s, uid); if (!info) { CamelVeeMessageInfo *vinfo; gchar tmphash[9]; /* This function isn't really nice. But no great way * But in vfolder case, this may not be so bad, as vuid has the hash in first 8 bytes. * So this just compares the entire string only if it belongs to the same folder. * Otherwise, the first byte itself would return in strcmp, saving the CPU. */ if (!camel_folder_summary_check_uid (s, uid)) { d(g_message ("Unable to find %s in the summary of %s", uid, camel_folder_get_full_name (camel_folder_summary_get_folder (s->folder)))); return NULL; } /* Create the info and load it, its so easy. */ info = camel_message_info_new (s); camel_message_info_ref (info); info->dirty = FALSE; vinfo = (CamelVeeMessageInfo *) info; info->uid = camel_pstring_strdup (uid); strncpy (tmphash, uid, 8); tmphash[8] = 0; vinfo->orig_summary = g_hash_table_lookup (((CamelVeeFolder *) camel_folder_summary_get_folder (s))->hashes, tmphash); g_object_ref (vinfo->orig_summary); camel_folder_summary_insert (s, info, FALSE); } return info; }
gboolean mail_send_short_message (EGdbusSession *object, GDBusMethodInvocation *invocation, const char *account_uid, const char *text, const char **to, EMailDataSession *msession, GError **ret_error) { EAccount *account; CamelMimeMessage *message; CamelService *service; gchar *transport_uid; CamelInternetAddress *recipients; CamelMessageInfo *info; GSimpleAsyncResult *simple; SendAsyncContext *context; CamelInternetAddress *from; GCancellable *ops; EMailDataOperation *mops; char *mops_path; gchar subject[MAX_SUBJECT_LENGTH + 4]; GError *error = NULL; /* Check params. */ if (account_uid == NULL || *account_uid == 0) { error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, _("Invalid account")); goto on_error; } if (text == NULL || *text == 0) { error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, _("Text is empty")); goto on_error; } if (to == NULL || *to == 0 || **to == 0) { error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, _("No recipient")); goto on_error; } /* Get transport. */ account = e_get_account_by_uid (account_uid); if (!account) { error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, _("Invalid account %s"), account_uid); goto on_error; } transport_uid = g_strconcat (account->uid, "-transport", NULL); service = camel_session_ref_service (CAMEL_SESSION (session), transport_uid); if (!CAMEL_IS_TRANSPORT (service)) { error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, _("Invalid account %s"), account_uid); g_object_unref (account); g_free (transport_uid); goto on_error; } /* Prepare message. */ message = camel_mime_message_new (); strncpy (subject, text, MAX_SUBJECT_LENGTH + 1); if (strlen(text) > MAX_SUBJECT_LENGTH) strcpy (subject + MAX_SUBJECT_LENGTH, "..."); camel_mime_message_set_subject (message, subject); from = camel_internet_address_new (); camel_internet_address_add (from, NULL, "sms"); recipients = camel_internet_address_new (); while (*to) { camel_internet_address_add (recipients, NULL, *to); to++; } camel_mime_message_set_from (message, from); camel_mime_message_set_recipients (message, CAMEL_RECIPIENT_TYPE_TO, recipients); camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); camel_mime_part_set_content_type (CAMEL_MIME_PART(message), "text/plain"); camel_mime_part_set_content (CAMEL_MIME_PART(message), text, strlen(text), "text/plain"); info = camel_message_info_new (NULL); camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); /* Return the new operation */ ops = camel_operation_new (); mops = e_mail_data_operation_new ((CamelOperation *) ops); mops_path = e_mail_data_operation_register_gdbus_object (mops, g_dbus_method_invocation_get_connection(invocation), NULL); egdbus_session_complete_send_short_message (object, invocation, mops_path); /* The rest of the processing happens in a thread. */ context = g_slice_new0 (SendAsyncContext); context->message = message; context->io_priority = G_PRIORITY_DEFAULT; context->from = CAMEL_ADDRESS (from); context->recipients = CAMEL_ADDRESS (recipients); context->info = info; context->transport = service; context->sent_folder_uri = g_strdup (account->sent_folder_uri); context->cancellable = ops; context->ops_path = mops_path; context->result = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); /* Failure here emits a runtime warning but is non-fatal. */ context->driver = camel_session_get_filter_driver ( CAMEL_SESSION (session), "outgoing", &error); if (error != NULL) { g_warn_if_fail (context->driver == NULL); g_warning ("%s", error->message); g_error_free (error); } /* This gets popped in async_context_free(). */ camel_operation_push_message (context->cancellable, _("Sending message")); simple = g_simple_async_result_new ( G_OBJECT (session), mail_send_short_message_completed, context, mail_send_short_message); g_simple_async_result_set_op_res_gpointer ( simple, context, (GDestroyNotify) async_context_free); g_simple_async_result_run_in_thread ( simple, (GSimpleAsyncThreadFunc) mail_send_short_to_thread, context->io_priority, context->cancellable); g_object_unref (simple); return TRUE; on_error: *ret_error = error; return FALSE; }
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; }
void e_mail_session_send_to (EMailSession *session, CamelMimeMessage *message, gint io_priority, GCancellable *cancellable, CamelFilterGetFolderFunc get_folder_func, gpointer get_folder_data, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *simple; AsyncContext *context; CamelAddress *from; CamelAddress *recipients; CamelMedium *medium; CamelMessageInfo *info; EAccount *account = NULL; GPtrArray *post_to_uris; struct _camel_header_raw *xev; struct _camel_header_raw *header; const gchar *string; const gchar *resent_from; gchar *transport_uid = NULL; gchar *sent_folder_uri = NULL; GError *error = NULL; g_return_if_fail (E_IS_MAIL_SESSION (session)); g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); medium = CAMEL_MEDIUM (message); camel_medium_set_header (medium, "X-Mailer", X_MAILER); xev = mail_tool_remove_xevolution_headers (message); /* Extract directives from X-Evolution headers. */ string = camel_header_raw_find (&xev, "X-Evolution-Account", NULL); if (string != NULL) { gchar *account_uid; account_uid = g_strstrip (g_strdup (string)); account = e_get_account_by_uid (account_uid); g_free (account_uid); } if (account != NULL) { if (account->transport != NULL) { /* XXX Transport UIDs are kludgy right now. We * use the EAccount's regular UID and tack on * "-transport". Will be better soon. */ transport_uid = g_strconcat ( account->uid, "-transport", NULL); /* to reprompt password on sending if needed */ account->transport->get_password_canceled = FALSE; } sent_folder_uri = g_strdup (account->sent_folder_uri); } string = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL); if (sent_folder_uri == NULL && string != NULL) sent_folder_uri = g_strstrip (g_strdup (string)); string = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL); if (transport_uid == NULL && string != NULL) transport_uid = g_strstrip (g_strdup (string)); post_to_uris = g_ptr_array_new (); for (header = xev; header != NULL; header = header->next) { gchar *folder_uri; if (g_strcmp0 (header->name, "X-Evolution-PostTo") != 0) continue; folder_uri = g_strstrip (g_strdup (header->value)); g_ptr_array_add (post_to_uris, folder_uri); } /* Collect sender and recipients from headers. */ from = (CamelAddress *) camel_internet_address_new (); recipients = (CamelAddress *) camel_internet_address_new (); resent_from = camel_medium_get_header (medium, "Resent-From"); if (resent_from != NULL) { const CamelInternetAddress *addr; const gchar *type; camel_address_decode (from, resent_from); type = CAMEL_RECIPIENT_TYPE_RESENT_TO; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); type = CAMEL_RECIPIENT_TYPE_RESENT_CC; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); type = CAMEL_RECIPIENT_TYPE_RESENT_BCC; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); } else { const CamelInternetAddress *addr; const gchar *type; addr = camel_mime_message_get_from (message); camel_address_copy (from, CAMEL_ADDRESS (addr)); type = CAMEL_RECIPIENT_TYPE_TO; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); type = CAMEL_RECIPIENT_TYPE_CC; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); type = CAMEL_RECIPIENT_TYPE_BCC; addr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (addr)); } /* Miscellaneous preparations. */ info = camel_message_info_new (NULL); camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); /* The rest of the processing happens in a thread. */ context = g_slice_new0 (AsyncContext); context->message = g_object_ref (message); context->io_priority = io_priority; context->from = from; context->recipients = recipients; context->message = g_object_ref (message); context->info = info; context->xev = xev; context->post_to_uris = post_to_uris; context->transport_uid = transport_uid; context->sent_folder_uri = sent_folder_uri; if (G_IS_CANCELLABLE (cancellable)) context->cancellable = g_object_ref (cancellable); /* Failure here emits a runtime warning but is non-fatal. */ context->driver = camel_session_get_filter_driver ( CAMEL_SESSION (session), E_FILTER_SOURCE_OUTGOING, &error); if (context->driver != NULL && get_folder_func) camel_filter_driver_set_folder_func ( context->driver, get_folder_func, get_folder_data); if (error != NULL) { g_warn_if_fail (context->driver == NULL); g_warning ("%s", error->message); g_error_free (error); } /* This gets popped in async_context_free(). */ camel_operation_push_message ( context->cancellable, _("Sending message")); simple = g_simple_async_result_new ( G_OBJECT (session), callback, user_data, e_mail_session_send_to); g_simple_async_result_set_op_res_gpointer ( simple, context, (GDestroyNotify) async_context_free); g_simple_async_result_run_in_thread ( simple, (GSimpleAsyncThreadFunc) mail_session_send_to_thread, context->io_priority, context->cancellable); g_object_unref (simple); }
static void import_mbox_exec (struct _import_mbox_msg *m) { CamelFolder *folder; CamelMimeParser *mp = NULL; struct stat st; int fd; CamelMessageInfo *info; if (g_stat(m->path, &st) == -1) { g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno)); return; } if (m->uri == NULL || m->uri[0] == 0) folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX); else folder = mail_tool_uri_to_folder(m->uri, CAMEL_STORE_FOLDER_CREATE, &m->base.ex); if (folder == NULL) return; if (S_ISREG(st.st_mode)) { CamelOperation *oldcancel = NULL; fd = g_open(m->path, O_RDONLY|O_BINARY, 0); if (fd == -1) { g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno)); goto fail1; } mp = camel_mime_parser_new(); camel_mime_parser_scan_from(mp, TRUE); if (camel_mime_parser_init_with_fd(mp, fd) == -1) { /* will never happen - 0 is unconditionally returned */ goto fail2; } if (m->cancel) oldcancel = camel_operation_register(m->cancel); camel_operation_start(NULL, _("Importing `%s'"), folder->full_name); camel_folder_freeze(folder); while (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) { CamelMimeMessage *msg; const char *tmp; int pc = 0; guint32 flags = 0; if (st.st_size > 0) pc = (int)(100.0 * ((double)camel_mime_parser_tell(mp) / (double)st.st_size)); camel_operation_progress(NULL, pc); msg = camel_mime_message_new(); if (camel_mime_part_construct_from_parser((CamelMimePart *)msg, mp) == -1) { /* set exception? */ camel_object_unref(msg); break; } info = camel_message_info_new(NULL); tmp = camel_medium_get_header((CamelMedium *)msg, "X-Mozilla-Status"); if (tmp) flags |= decode_mozilla_status(tmp); tmp = camel_medium_get_header((CamelMedium *)msg, "Status"); if (tmp) flags |= decode_status(tmp); tmp = camel_medium_get_header((CamelMedium *)msg, "X-Status"); if (tmp) flags |= decode_status(tmp); camel_message_info_set_flags(info, flags, ~0); camel_folder_append_message(folder, msg, info, NULL, &m->base.ex); camel_message_info_free(info); camel_object_unref(msg); if (camel_exception_is_set(&m->base.ex)) break; camel_mime_parser_step(mp, NULL, NULL); } camel_folder_sync(folder, FALSE, NULL); camel_folder_thaw(folder); camel_operation_end(NULL); /* TODO: these api's are a bit weird, registering the old is the same as deregistering */ if (m->cancel) camel_operation_register(oldcancel); fail2: camel_object_unref(mp); } fail1: camel_folder_sync(folder, FALSE, NULL); camel_object_unref(folder); }
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); }
static void dbx_import_file (DbxImporter *m) { EShell *shell; EShellBackend *shell_backend; EMailSession *session; GCancellable *cancellable; gchar *filename; CamelFolder *folder; gint tmpfile; gint i; gint missing = 0; m->status_what = NULL; filename = g_filename_from_uri ( ((EImportTargetURI *) m->target)->uri_src, NULL, NULL); /* Destination folder, was set in our widget */ m->parent_uri = g_strdup (((EImportTargetURI *) m->target)->uri_dest); cancellable = m->base.cancellable; /* XXX Dig up the EMailSession from the default EShell. * Since the EImport framework doesn't allow for user * data, I don't see how else to get to it. */ shell = e_shell_get_default (); shell_backend = e_shell_get_backend_by_name (shell, "mail"); session = e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend)); camel_operation_push_message (NULL, _("Importing “%s”"), filename); folder = e_mail_session_uri_to_folder_sync ( session, m->parent_uri, CAMEL_STORE_FOLDER_CREATE, cancellable, &m->base.error); if (!folder) return; d (printf ("importing to %s\n", camel_folder_get_full_name (folder))); camel_folder_freeze (folder); filename = g_filename_from_uri ( ((EImportTargetURI *) m->target)->uri_src, NULL, NULL); m->dbx_fd = g_open (filename, O_RDONLY, 0); g_free (filename); if (m->dbx_fd == -1) { g_set_error ( &m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, "Failed to open import file"); goto out; } if (!dbx_load_indices (m)) goto out; tmpfile = e_mkstemp ("dbx-import-XXXXXX"); if (tmpfile == -1) { g_set_error ( &m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, "Failed to create temporary file for import"); goto out; } for (i = 0; i < m->index_count; i++) { CamelMessageInfo *info; CamelMimeMessage *msg; CamelMimeParser *mp; gint dbx_flags = 0; gint flags = 0; gboolean success; camel_operation_progress (NULL, 100 * i / m->index_count); camel_operation_progress (cancellable, 100 * i / m->index_count); if (!dbx_read_email (m, m->indices[i], tmpfile, &dbx_flags)) { d ( printf ("Cannot read email index %d at %x\n", i, m->indices[i])); if (m->base.error != NULL) goto out; missing++; continue; } if (dbx_flags & 0x40) flags |= CAMEL_MESSAGE_DELETED; if (dbx_flags & 0x80) flags |= CAMEL_MESSAGE_SEEN; if (dbx_flags & 0x80000) flags |= CAMEL_MESSAGE_ANSWERED; mp = camel_mime_parser_new (); lseek (tmpfile, 0, SEEK_SET); camel_mime_parser_init_with_fd (mp, tmpfile); msg = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) msg, mp, NULL, NULL)) { /* set exception? */ g_object_unref (msg); g_object_unref (mp); break; } info = camel_message_info_new (NULL); camel_message_info_set_flags (info, flags, ~0); success = camel_folder_append_message_sync ( folder, msg, info, NULL, cancellable, &m->base.error); g_clear_object (&info); g_object_unref (msg); if (!success) { g_object_unref (mp); break; } } out: if (m->dbx_fd != -1) close (m->dbx_fd); if (m->indices) g_free (m->indices); /* FIXME Not passing GCancellable or GError here. */ camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); camel_folder_thaw (folder); g_object_unref (folder); if (missing && m->base.error == NULL) { g_set_error ( &m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, "%d messages imported correctly; %d message " "bodies were not present in the DBX file", m->index_count - missing, missing); } camel_operation_pop_message (NULL); }
static void import_kmail_folder (struct _import_mbox_msg *m, gchar *k_path_in, GCancellable *cancellable, GError **error) { const gchar *special_folders []= {"cur", "tmp", "new", NULL}; gchar *special_path; const CamelStore *store; CamelFolder *folder; CamelMimeParser *mp = NULL; CamelMessageInfo *info; CamelMimeMessage *msg; guint32 flags = 0; gchar *e_uri, *e_path; gchar *k_path; const gchar *d; gchar *mail_url; GDir *dir; struct stat st; gint fd, i; e_uri = kuri_to_euri (k_path_in); /* we need to drop some folders, like: Trash */ if (!e_uri) return; /* In case we using async way in the future */ k_path = g_strdup (k_path_in); store = evolution_get_local_store (); e_path = e_uri + strlen (EVOLUTION_LOCAL_BASE) + 1; e_mail_store_create_folder_sync ((CamelStore *)store, e_path, NULL, NULL); folder = e_mail_session_uri_to_folder_sync ( m->session, e_uri, CAMEL_STORE_FOLDER_CREATE, cancellable, NULL); if (folder == NULL) { g_free (k_path); g_warning ("evolution error: cannot get the folder\n"); return; } camel_operation_push_message ( cancellable, _("Importing '%s'"), camel_folder_get_display_name (folder)); camel_folder_freeze (folder); for (i = 0; special_folders [i]; i++) { camel_operation_progress (cancellable, 100*i/3); special_path = g_build_filename (k_path, special_folders[i], NULL); dir = g_dir_open (special_path, 0, NULL); while ((d = g_dir_read_name (dir))) { if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) { continue; } mail_url = g_build_filename (special_path, d, NULL); if (g_stat (mail_url, &st) == -1) { g_free (mail_url); continue; } if (S_ISREG (st.st_mode)) { fd = g_open (mail_url, O_RDONLY | O_BINARY, 0); g_free (mail_url); if (fd == -1) { continue; } mp = camel_mime_parser_new (); camel_mime_parser_scan_from (mp, FALSE); if (camel_mime_parser_init_with_fd (mp, fd) == -1) { /* will never happen - 0 is unconditionally returned */ g_object_unref (mp); continue; } msg = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) msg, mp, NULL, NULL)) { /* set exception? */ g_object_unref (mp); g_object_unref (msg); continue; } info = camel_message_info_new (NULL); if (strcmp (special_folders[i], "cur") == 0) { flags |= CAMEL_MESSAGE_SEEN; } else if (strcmp (special_folders[i], "tmp") == 0) { flags |= CAMEL_MESSAGE_DELETED; /* Mark the 'tmp' mails as 'deleted' */ } camel_message_info_set_flags (info, flags, ~0); camel_folder_append_message_sync ( folder, msg, info, NULL, cancellable, error); camel_message_info_unref (info); g_object_unref (msg); g_object_unref (mp); } else { g_free (mail_url); } } } camel_operation_progress (cancellable, 100); camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); camel_folder_thaw (folder); camel_operation_pop_message (cancellable); g_free (k_path); }