CamelMimeMessage * test_message_create_simple (void) { CamelMimeMessage *msg; CamelInternetAddress *addr; msg = camel_mime_message_new (); addr = camel_internet_address_new (); camel_internet_address_add (addr, "Michael Zucchi", "*****@*****.**"); camel_mime_message_set_from (msg, addr); camel_address_remove ((CamelAddress *) addr, -1); camel_internet_address_add (addr, "POSTMASTER", "*****@*****.**"); camel_mime_message_set_recipients (msg, CAMEL_RECIPIENT_TYPE_TO, addr); camel_address_remove ((CamelAddress *) addr, -1); camel_internet_address_add (addr, "Michael Zucchi", "*****@*****.**"); camel_mime_message_set_recipients (msg, CAMEL_RECIPIENT_TYPE_CC, addr); check_unref (addr, 1); camel_mime_message_set_subject (msg, "Simple message subject"); camel_mime_message_set_date (msg, time (0), 930); return msg; }
/** * 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); }
gint main (gint argc, gchar **argv) { struct dirent *dent; DIR *dir; gint fd; camel_test_init (argc, argv); camel_test_start ("Message Test Suite"); if (!(dir = opendir ("../data/messages"))) return 77; while ((dent = readdir (dir)) != NULL) { CamelMimeMessage *message; CamelStream *stream; gchar *filename; struct stat st; if (dent->d_name[0] == '.') continue; filename = g_strdup_printf ("../data/messages/%s", dent->d_name); if (g_stat (filename, &st) == -1 || !S_ISREG (st.st_mode)) { g_free (filename); continue; } if ((fd = open (filename, O_RDONLY)) == -1) { g_free (filename); continue; } push ("testing message '%s'", filename); g_free (filename); stream = camel_stream_fs_new_with_fd (fd); message = camel_mime_message_new (); camel_data_wrapper_construct_from_stream_sync ( CAMEL_DATA_WRAPPER (message), stream, NULL, NULL); g_seekable_seek ( G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL); /*dump_mime_struct ((CamelMimePart *) message, 0);*/ test_message_compare (message); g_object_unref (message); g_object_unref (stream); pull (); } closedir (dir); camel_test_end (); return 0; }
gint test_message_compare (CamelMimeMessage *msg) { CamelMimeMessage *msg2; CamelStream *stream1; CamelStream *stream2; GByteArray *byte_array1; GByteArray *byte_array2; byte_array1 = g_byte_array_new (); stream1 = camel_stream_mem_new_with_byte_array (byte_array1); check_msg (camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (msg), stream1, NULL, NULL) != -1, "write_to_stream 1 failed", NULL); g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL); msg2 = camel_mime_message_new (); check_msg (camel_data_wrapper_construct_from_stream_sync ( CAMEL_DATA_WRAPPER (msg2), stream1, NULL, NULL) != -1, "construct_from_stream 1 failed"); g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL); byte_array2 = g_byte_array_new (); stream2 = camel_stream_mem_new_with_byte_array (byte_array2); check_msg (camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (msg2), stream2, NULL, NULL) != -1, "write_to_stream 2 failed"); g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL); if (byte_array1->len != byte_array2->len) { CamelDataWrapper *content; printf ("stream1 stream:\n%.*s\n", byte_array1->len, byte_array1->data); printf ("stream2 stream:\n%.*s\n\n", byte_array2->len, byte_array2->data); printf ("msg1:\n"); test_message_dump_structure (msg); printf ("msg2:\n"); test_message_dump_structure (msg2); content = camel_medium_get_content ((CamelMedium *) msg); } check_unref (msg2, 1); check_msg ( byte_array1->len == byte_array2->len, "byte_array1->len = %d, byte_array2->len = %d", byte_array1->len, byte_array2->len); check_msg (memcmp (byte_array1->data, byte_array2->data, byte_array1->len) == 0, "msg/stream compare"); g_object_unref (stream1); g_object_unref (stream2); return 0; }
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 CamelMimeMessage * maildir_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *message_stream = NULL; CamelMimeMessage *message = NULL; gchar *name = NULL; d(printf("getting message: %s\n", uid)); if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return NULL; name = maildir_folder_get_filename (folder, uid, error); if (!name) goto fail; 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: "), uid, 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: "), uid, lf->folder_path); g_object_unref (message); message = NULL; } g_object_unref (message_stream); fail: g_free (name); camel_local_folder_unlock (lf); if (lf && camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return message; }
CamelMimeMessage * test_message_read_file (const gchar *name) { CamelStream *stream; CamelMimeMessage *msg2; stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0, NULL); msg2 = camel_mime_message_new (); camel_data_wrapper_construct_from_stream_sync ( CAMEL_DATA_WRAPPER (msg2), stream, NULL, NULL); /* stream's refcount may be > 1 if the message is real big */ check (G_OBJECT (stream)->ref_count >=1); g_object_unref (stream); return msg2; }
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 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 void load_snapshot_loaded_cb (GFile *snapshot_file, GAsyncResult *result, GSimpleAsyncResult *simple) { EShell *shell; GObject *object; LoadContext *context; EMsgComposer *composer; CamelMimeMessage *message; CamelStream *camel_stream; gchar *contents = NULL; gsize length; GError *local_error = NULL; context = g_simple_async_result_get_op_res_gpointer (simple); g_file_load_contents_finish ( snapshot_file, result, &contents, &length, NULL, &local_error); if (local_error != NULL) { g_warn_if_fail (contents == NULL); g_simple_async_result_take_error (simple, local_error); g_simple_async_result_complete (simple); return; } /* Create an in-memory buffer for the MIME parser to read from. * We have to do this because CamelStreams are syncrhonous-only, * and feeding the parser a direct file stream would block. */ message = camel_mime_message_new (); camel_stream = camel_stream_mem_new_with_buffer (contents, length); camel_data_wrapper_construct_from_stream_sync ( CAMEL_DATA_WRAPPER (message), camel_stream, NULL, &local_error); g_object_unref (camel_stream); g_free (contents); if (local_error != NULL) { g_simple_async_result_take_error (simple, local_error); g_simple_async_result_complete (simple); g_object_unref (message); return; } /* g_async_result_get_source_object() returns a new reference. */ object = g_async_result_get_source_object (G_ASYNC_RESULT (simple)); /* Create a new composer window from the loaded message and * restore its snapshot file so it continues auto-saving to * the same file. */ shell = E_SHELL (object); g_object_ref (snapshot_file); composer = e_msg_composer_new_with_message (shell, message, TRUE, NULL); g_object_set_data_full ( G_OBJECT (composer), SNAPSHOT_FILE_KEY, snapshot_file, (GDestroyNotify) delete_snapshot_file); context->composer = g_object_ref_sink (composer); g_object_unref (message); g_object_unref (object); g_simple_async_result_complete (simple); g_object_unref (simple); }
static void import_mbox_exec (struct _import_mbox_msg *m, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelMimeParser *mp = NULL; struct stat st; gint fd; 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 = e_mail_session_get_local_folder ( m->session, E_MAIL_LOCAL_FOLDER_INBOX); else folder = e_mail_session_uri_to_folder_sync ( m->session, m->uri, CAMEL_STORE_FOLDER_CREATE, cancellable, error); if (folder == NULL) return; if (S_ISREG (st.st_mode)) { gboolean any_read = FALSE; 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; } camel_operation_push_message ( cancellable, _("Importing '%s'"), camel_folder_get_display_name (folder)); camel_folder_freeze (folder); while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM && !g_cancellable_is_cancelled (cancellable)) { CamelMimeMessage *msg; gint pc = 0; any_read = TRUE; if (st.st_size > 0) pc = (gint) (100.0 * ((gdouble) camel_mime_parser_tell (mp) / (gdouble) st.st_size)); camel_operation_progress (cancellable, pc); msg = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) msg, mp, NULL, NULL)) { /* set exception? */ g_object_unref (msg); break; } import_mbox_add_message (folder, msg, cancellable, error); g_object_unref (msg); if (error && *error != NULL) break; camel_mime_parser_step (mp, NULL, NULL); } if (!any_read && !g_cancellable_is_cancelled (cancellable)) { CamelStream *stream; stream = camel_stream_fs_new_with_name (m->path, O_RDONLY, 0, NULL); if (stream) { CamelMimeMessage *msg; msg = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL)) import_mbox_add_message (folder, msg, cancellable, error); g_object_unref (msg); g_object_unref (stream); } } /* Not passing a GCancellable or GError here. */ camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); camel_folder_thaw (folder); camel_operation_pop_message (cancellable); fail2: g_object_unref (mp); } fail1: /* Not passing a GCancellable or GError here. */ camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); g_object_unref (folder); /* 'fd' is freed together with 'mp' */ /* coverity[leaked_handle] */ }
static CamelMimeMessage * mail_attachment_handler_get_selected_message (EAttachmentHandler *handler) { EAttachment *attachment; EAttachmentView *view; CamelMimePart *mime_part; CamelMimeMessage *message = NULL; CamelDataWrapper *outer_wrapper; CamelContentType *outer_content_type; CamelDataWrapper *inner_wrapper; CamelContentType *inner_content_type; GList *selected; gboolean inner_and_outer_content_types_match; view = e_attachment_handler_get_view (handler); selected = e_attachment_view_get_selected_attachments (view); g_return_val_if_fail (g_list_length (selected) == 1, NULL); attachment = E_ATTACHMENT (selected->data); mime_part = e_attachment_ref_mime_part (attachment); outer_wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); outer_content_type = camel_data_wrapper_get_mime_type_field (outer_wrapper); if (!camel_content_type_is (outer_content_type, "message", "rfc822")) goto exit; inner_wrapper = camel_medium_get_content (CAMEL_MEDIUM (outer_wrapper)); inner_content_type = camel_data_wrapper_get_mime_type_field (inner_wrapper); inner_and_outer_content_types_match = camel_content_type_is ( inner_content_type, outer_content_type->type, outer_content_type->subtype); if (!inner_and_outer_content_types_match) { CamelStream *mem; gboolean success; /* Create a message copy in case the inner content * type doesn't match the mime_part's content type, * which can happen for multipart/digest, where it * confuses the formatter on reply, which skips all * rfc822 subparts. */ mem = camel_stream_mem_new (); camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (outer_wrapper), mem, NULL, NULL); g_seekable_seek ( G_SEEKABLE (mem), 0, G_SEEK_SET, NULL, NULL); message = camel_mime_message_new (); success = camel_data_wrapper_construct_from_stream_sync ( CAMEL_DATA_WRAPPER (message), mem, NULL, NULL); if (!success) g_clear_object (&message); g_object_unref (mem); } exit: if (message == NULL) message = g_object_ref (outer_wrapper); g_clear_object (&mime_part); g_list_free_full (selected, (GDestroyNotify) g_object_unref); return message; }
static gboolean mbox_supported (EImport *ei, EImportTarget *target, EImportImporter *im) { gchar signature[1024]; gboolean ret = FALSE; gint fd, n; EImportTargetURI *s; gchar *filename; if (target->type != E_IMPORT_TARGET_URI) return FALSE; s = (EImportTargetURI *) target; if (s->uri_src == NULL) return TRUE; if (strncmp (s->uri_src, "file:///", strlen ("file:///")) != 0) return FALSE; filename = g_filename_from_uri (s->uri_src, NULL, NULL); fd = g_open (filename, O_RDONLY, 0); if (fd != -1) { n = read (fd, signature, 1024); ret = n >= 5 && memcmp (signature, "From ", 5) == 0; close (fd); /* An artificial number, at least 256 bytes message to be able to try to import it as an MBOX */ if (!ret && n >= 256) { gint ii; ret = (signature[0] >= 'a' && signature[0] <= 'z') || (signature[0] >= 'A' && signature[0] <= 'Z'); for (ii = 0; ii < n && ret; ii++) { ret = signature[ii] == '-' || signature[ii] == ' ' || signature[ii] == '\t' || (signature[ii] >= 'a' && signature[ii] <= 'z') || (signature[ii] >= 'A' && signature[ii] <= 'Z') || (signature[ii] >= '0' && signature[ii] <= '9'); } /* It's probably a header name which starts with ASCII letter and contains only [a..z][A..Z][\t, ,-] and the read stopped on ':'. */ if (ii > 0 && ii < n && !ret && signature[ii - 1] == ':') { CamelStream *stream; stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL); if (stream) { CamelMimeMessage *msg; msg = camel_mime_message_new (); /* Check whether the message can be parsed and whether it contains any mandatory fields. */ ret = camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL) && camel_mime_message_get_message_id (msg) && camel_mime_message_get_subject (msg) && camel_mime_message_get_from (msg) && (camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_TO) || camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_RESENT_TO)); g_object_unref (msg); g_object_unref (stream); } } } } g_free (filename); return ret; }
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); }
CamelMimeMessage * scalix_appointment_to_mime_message (ScalixObject * object) { CamelMimeMessage *message; CamelMultipart *multipart; CamelMimePart *part; CamelMedium *medium; CamelStream *stream; CamelDataWrapper *wrapper; ECalComponentDateTime dtstart, dtend; ECalComponent *comp; ECalComponentText text; icalcomponent_kind kind; icalcomponent *icalcomp, *toplevel_comp; icaltimezone *zone = NULL; GSList *attachment_list = NULL; GSList *attachment_list_new = NULL; GSList *siter = NULL; GList *part_list = NULL; GList *iter = NULL; char *msgid; char *str, *meeting_status; const char *ouid = NULL; char *file_contents = NULL; char *full_path, *filename, *mime_filename; char *cid; int size; g_object_get (SCALIX_APPOINTMENT (object), "timezone", &zone, NULL); comp = E_CAL_COMPONENT (scalix_object_clone (object)); message = camel_mime_message_new (); medium = CAMEL_MEDIUM (message); camel_medium_add_header (medium, "X-Scalix-Class", "IPM.Appointment"); /* Preserve msg id if there is already one */ if (scalix_appointment_get (SCALIX_APPOINTMENT (comp), X_SCALIX_MSG_ID, &msgid)) { scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_MSG_ID); } else { msgid = camel_header_msgid_generate (); } camel_mime_message_set_message_id (message, msgid); /* subject */ e_cal_component_get_summary (comp, &text); if (text.value != NULL) { camel_mime_message_set_subject (message, text.value); } /* start day */ e_cal_component_get_dtstart (comp, &dtstart); if (!icaltime_get_timezone (*dtstart.value)) icaltime_set_timezone (dtstart.value, icaltimezone_get_builtin_timezone_from_tzid (dtstart.tzid)); /* end day */ e_cal_component_get_dtend (comp, &dtend); if (!icaltime_get_timezone (*dtend.value)) icaltime_set_timezone (dtend.value, icaltimezone_get_builtin_timezone_from_tzid (dtend.tzid)); /* set From: and Sender: */ if (e_cal_component_has_organizer (comp)) { ECalComponentOrganizer organizer; e_cal_component_get_organizer (comp, &organizer); if (!strncasecmp (organizer.value, "MAILTO:", 7)) { camel_medium_add_header (medium, "Sender", organizer.value + 7); camel_medium_add_header (medium, "From", organizer.value + 7); } } /* set the appropriate recipient headers from the recipient table */ if (e_cal_component_has_attendees (comp) && e_cal_component_has_organizer (comp)) { GSList *iter, *attendees = NULL; CamelInternetAddress *recipients_to = NULL; CamelInternetAddress *recipients_cc = NULL; meeting_status = "1"; e_cal_component_get_attendee_list (comp, &attendees); for (iter = attendees; iter; iter = iter->next) { ECalComponentAttendee *attendee = iter->data; const char *mail = NULL; /* attendee entries must start with MAILTO: */ if (strncasecmp (attendee->value, "MAILTO:", 7)) { continue; } mail = attendee->value + 7; if (attendee->role == ICAL_ROLE_REQPARTICIPANT) { if (recipients_to == NULL) { recipients_to = camel_internet_address_new (); } camel_internet_address_add (recipients_to, attendee->cn, mail); } else if (attendee->role == ICAL_ROLE_OPTPARTICIPANT) { if (recipients_cc == NULL) { recipients_cc = camel_internet_address_new (); } camel_internet_address_add (recipients_cc, attendee->cn, mail); } else { continue; } } if (recipients_to != NULL) { camel_mime_message_set_recipients (message, "To", recipients_to); camel_object_unref (recipients_to); } if (recipients_cc != NULL) { camel_mime_message_set_recipients (message, "Cc", recipients_cc); camel_object_unref (recipients_cc); } } else { meeting_status = "0"; } /* Clear properties */ scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_IMAP_UID); /* Render the text/calendar */ e_cal_component_commit_sequence (comp); icalcomp = e_cal_component_get_icalcomponent (comp); kind = icalcomponent_isa (icalcomp); if (kind != ICAL_VCALENDAR_COMPONENT) { /* If its not a VCALENDAR, make it one to simplify below */ toplevel_comp = e_cal_util_new_top_level (); icalcomponent_add_component (toplevel_comp, icalcomp); icalcomp = toplevel_comp; } /* set METHOD to PUSBLISH */ icalcomponent_set_method (icalcomp, ICAL_METHOD_PUBLISH); /* Add the VTIMEZONE components for start- and/or end-times */ if (zone) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (zone)); } else if (dtstart.tzid) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (icaltimezone_get_builtin_timezone_from_tzid (dtstart.tzid))); } if (dtstart.tzid && dtend.tzid && strcmp (dtstart.tzid, dtend.tzid) != 0) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (icaltimezone_get_builtin_timezone_from_tzid (dtend.tzid))); } /* FIXME: do we leek icalcomponents here? */ if (e_cal_component_has_attachments (comp)) { multipart = camel_multipart_new (); camel_multipart_set_boundary (multipart, NULL); e_cal_component_get_uid (comp, &ouid); e_cal_component_get_attachment_list (comp, &attachment_list); for (siter = attachment_list; siter; siter = siter->next) { if (siter->data == NULL) continue; if (strstr (siter->data, "file://") != siter->data) continue; full_path = ((char *) siter->data) + strlen ("file://"); filename = g_strrstr (full_path, "/") + 1; mime_filename = filename + strlen (ouid) + 1; size = 0; file_contents = get_file_contents (full_path, &size); if (file_contents == NULL) continue; stream = camel_stream_mem_new_with_buffer (file_contents, size); wrapper = camel_data_wrapper_new (); camel_data_wrapper_construct_from_stream (wrapper, stream); camel_object_unref (stream); part = camel_mime_part_new (); camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); camel_mime_part_set_filename (part, mime_filename); camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64); cid = camel_header_msgid_generate (); camel_mime_part_set_content_id (part, cid); camel_mime_part_set_description (part, mime_filename); camel_mime_part_set_disposition (part, "attachment"); part_list = g_list_append (part_list, part); attachment_list_new = g_slist_append (attachment_list_new, g_strdup_printf ("CID:%s", cid)); g_free (cid); } e_cal_component_set_attachment_list (comp, attachment_list_new); str = icalcomponent_as_ical_string (icalcomp); part = camel_mime_part_new (); camel_mime_part_set_content (part, str, strlen (str), "text/calendar; method=PUBLISH; charset=UTF-8"); part_list = g_list_prepend (part_list, part); for (iter = part_list; iter; iter = iter->next) { part = (CamelMimePart *) iter->data; camel_multipart_add_part (multipart, part); camel_object_unref (part); } camel_medium_set_content_object (CAMEL_MEDIUM (message), CAMEL_DATA_WRAPPER (multipart)); camel_object_unref (multipart); g_slist_free (attachment_list); g_slist_free (attachment_list_new); g_list_free (part_list); } else { str = icalcomponent_as_ical_string (icalcomp); camel_mime_part_set_content (CAMEL_MIME_PART (message), str, strlen (str), "text/calendar; method=PUBLISH; charset=UTF-8"); } scalix_appointment_set (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID, msgid); return message; }
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 CamelMimeMessage * nntp_folder_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable, GError **error) { CamelStore *parent_store; CamelMimeMessage *message = NULL; CamelDataCache *nntp_cache; CamelNNTPStore *nntp_store; CamelFolderChangeInfo *changes; CamelNNTPFolder *nntp_folder; CamelStream *stream = NULL; GIOStream *base_stream; gchar *article, *msgid; gsize article_len; parent_store = camel_folder_get_parent_store (folder); nntp_folder = CAMEL_NNTP_FOLDER (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); article_len = strlen (uid) + 1; article = alloca (article_len); g_strlcpy (article, uid, article_len); msgid = strchr (article, ','); if (msgid == NULL) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Internal error: UID in invalid format: %s"), uid); return NULL; } *msgid++ = 0; /* Lookup in cache, NEWS is global messageid's so use a global cache path */ nntp_cache = camel_nntp_store_ref_cache (nntp_store); base_stream = camel_data_cache_get (nntp_cache, "cache", msgid, NULL); g_clear_object (&nntp_cache); if (base_stream != NULL) { stream = camel_stream_new (base_stream); g_object_unref (base_stream); } else { CamelServiceConnectionStatus connection_status; connection_status = camel_service_get_connection_status ( CAMEL_SERVICE (parent_store)); if (connection_status != CAMEL_SERVICE_CONNECTED) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, _("This message is not currently available")); goto fail; } stream = nntp_folder_download_message (nntp_folder, article, msgid, cancellable, error); if (stream == NULL) goto fail; } message = camel_mime_message_new (); if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error)) { g_prefix_error (error, _("Cannot get message %s: "), uid); g_object_unref (message); message = NULL; } g_object_unref (stream); fail: if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); } else { changes = NULL; } if (changes) { camel_folder_changed (folder, changes); camel_folder_change_info_free (changes); } return message; }
static CamelMimeMessage * nntp_folder_get_message (CamelFolder *folder, const char *uid, CamelException *ex) { CamelMimeMessage *message = NULL; CamelNNTPStore *nntp_store; CamelFolderChangeInfo *changes; CamelNNTPFolder *nntp_folder; CamelStream *stream = NULL; char *article, *msgid; nntp_store = (CamelNNTPStore *) folder->parent_store; nntp_folder = (CamelNNTPFolder *) folder; article = alloca(strlen(uid)+1); strcpy(article, uid); msgid = strchr (article, ','); if (msgid == NULL) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Internal error: UID in invalid format: %s"), uid); return NULL; } *msgid++ = 0; CAMEL_SERVICE_REC_LOCK(nntp_store, connect_lock); /* Lookup in cache, NEWS is global messageid's so use a global cache path */ stream = camel_data_cache_get (nntp_store->cache, "cache", msgid, NULL); if (stream == NULL) { if (camel_disco_store_status ((CamelDiscoStore *) nntp_store) == CAMEL_DISCO_STORE_OFFLINE) { camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("This message is not currently available")); goto fail; } stream = nntp_folder_download_message (nntp_folder, article, msgid, ex); if (stream == NULL) goto fail; } message = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) { if (errno == EINTR) camel_exception_setv (ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled")); else camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot get message %s: %s"), uid, g_strerror (errno)); camel_object_unref(message); message = NULL; } camel_object_unref (stream); fail: if (camel_folder_change_info_changed (nntp_folder->changes)) { changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); } else { changes = NULL; } CAMEL_SERVICE_REC_UNLOCK(nntp_store, connect_lock); if (changes) { camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes); camel_folder_change_info_free (changes); } return message; }
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); }
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 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; }
static GtkWidget * mbox_get_preview (EImport *ei, EImportTarget *target, EImportImporter *im) { GtkWidget *preview = NULL; EImportTargetURI *s = (EImportTargetURI *) target; gchar *filename; gint fd; CamelMimeParser *mp; GtkListStore *store = NULL; GtkTreeIter iter; GtkWidget *preview_widget = NULL; gboolean any_read = FALSE; if (!create_preview_func || !fill_preview_func) return NULL; filename = g_filename_from_uri (s->uri_src, NULL, NULL); if (!filename) { g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src); return NULL; } fd = g_open (filename, O_RDONLY | O_BINARY, 0); if (fd == -1) { g_warning ( "Cannot find source file to import '%s': %s", filename, g_strerror (errno)); g_free (filename); return NULL; } mp = camel_mime_parser_new (); camel_mime_parser_scan_from (mp, TRUE); if (camel_mime_parser_init_with_fd (mp, fd) == -1) { goto cleanup; } while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) { CamelMimeMessage *msg; any_read = TRUE; msg = camel_mime_message_new (); if (!camel_mime_part_construct_from_parser_sync ( (CamelMimePart *) msg, mp, NULL, NULL)) { g_object_unref (msg); break; } mbox_preview_add_message (msg, &store); g_object_unref (msg); camel_mime_parser_step (mp, NULL, NULL); } if (!any_read) { CamelStream *stream; stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL); if (stream) { CamelMimeMessage *msg; msg = camel_mime_message_new (); if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL)) mbox_preview_add_message (msg, &store); g_object_unref (msg); g_object_unref (stream); } } if (store) { GtkTreeView *tree_view; GtkTreeSelection *selection; preview = e_web_view_preview_new (); gtk_widget_show (preview); tree_view = e_web_view_preview_get_tree_view ( E_WEB_VIEW_PREVIEW (preview)); if (!tree_view) { g_warn_if_reached (); gtk_widget_destroy (preview); preview = NULL; goto cleanup; } gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store)); g_object_unref (store); /* Translators: Column header for a message subject */ gtk_tree_view_insert_column_with_attributes ( tree_view, -1, C_("mboxImp", "Subject"), gtk_cell_renderer_text_new (), "text", 0, NULL); /* Translators: Column header for a message From address */ gtk_tree_view_insert_column_with_attributes ( tree_view, -1, C_("mboxImp", "From"), gtk_cell_renderer_text_new (), "text", 1, NULL); if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1) e_web_view_preview_show_tree_view ( E_WEB_VIEW_PREVIEW (preview)); create_preview_func (G_OBJECT (preview), &preview_widget); if (!preview_widget) { g_warn_if_reached (); goto cleanup; } e_web_view_preview_set_preview ( E_WEB_VIEW_PREVIEW (preview), preview_widget); gtk_widget_show (preview_widget); selection = gtk_tree_view_get_selection (tree_view); if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { g_warn_if_reached (); goto cleanup; } gtk_tree_selection_select_iter (selection, &iter); g_signal_connect ( selection, "changed", G_CALLBACK (preview_selection_changed_cb), preview); preview_selection_changed_cb ( selection, E_WEB_VIEW_PREVIEW (preview)); } cleanup: g_object_unref (mp); g_free (filename); /* 'fd' is freed together with 'mp' */ /* coverity[leaked_handle] */ return preview; }
static void mail_attachment_handler_message_rfc822 (EAttachmentView *view, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, EAttachmentHandler *handler) { static GdkAtom atom = GDK_NONE; EAttachmentStore *store; EAttachment *attachment; CamelMimeMessage *message; CamelDataWrapper *wrapper; CamelStream *stream; const gchar *data; gboolean success = FALSE; gpointer parent; gint length; if (G_UNLIKELY (atom == GDK_NONE)) atom = gdk_atom_intern_static_string ("message/rfc822"); if (gtk_selection_data_get_target (selection_data) != atom) return; g_signal_stop_emission_by_name (view, "drag-data-received"); data = (const gchar *) gtk_selection_data_get_data (selection_data); length = gtk_selection_data_get_length (selection_data); stream = camel_stream_mem_new (); camel_stream_write (stream, data, length, NULL, NULL); g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL); message = camel_mime_message_new (); wrapper = CAMEL_DATA_WRAPPER (message); if (!camel_data_wrapper_construct_from_stream_sync ( wrapper, stream, NULL, NULL)) goto exit; store = e_attachment_view_get_store (view); parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); parent = gtk_widget_is_toplevel (parent) ? parent : NULL; attachment = e_attachment_new_for_message (message); e_attachment_store_add_attachment (store, attachment); e_attachment_load_async ( attachment, (GAsyncReadyCallback) call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL); g_object_unref (attachment); success = TRUE; exit: g_object_unref (message); g_object_unref (stream); gtk_drag_finish (drag_context, success, FALSE, time); }