/** * em_utils_folder_is_drafts: * @registry: an #ESourceRegistry * @folder: a #CamelFolder * * Decides if @folder is a Drafts folder. * * Returns %TRUE if this is a Drafts folder or %FALSE otherwise. **/ gboolean em_utils_folder_is_drafts (ESourceRegistry *registry, CamelFolder *folder) { CamelFolder *local_drafts_folder; CamelSession *session; CamelStore *store; GList *list, *iter; gchar *folder_uri; gboolean is_drafts = FALSE; const gchar *extension_name; g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); store = camel_folder_get_parent_store (folder); session = camel_service_ref_session (CAMEL_SERVICE (store)); local_drafts_folder = e_mail_session_get_local_folder ( E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS); if (folder == local_drafts_folder) { is_drafts = TRUE; goto exit; } folder_uri = e_mail_folder_uri_from_folder (folder); store = camel_folder_get_parent_store (folder); extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION; list = e_source_registry_list_sources (registry, extension_name); for (iter = list; iter != NULL; iter = g_list_next (iter)) { ESource *source = E_SOURCE (iter->data); ESourceExtension *extension; const gchar *drafts_folder_uri; extension = e_source_get_extension (source, extension_name); drafts_folder_uri = e_source_mail_composition_get_drafts_folder ( E_SOURCE_MAIL_COMPOSITION (extension)); if (drafts_folder_uri != NULL) is_drafts = e_mail_folder_uri_equal ( session, folder_uri, drafts_folder_uri); if (is_drafts) break; } g_list_free_full (list, (GDestroyNotify) g_object_unref); g_free (folder_uri); exit: g_object_unref (session); return is_drafts; }
/* when receive/send is complete */ static void receive_done (gint still_more, gpointer data) { struct _send_info *info = data; const gchar *uid; uid = camel_service_get_uid (info->service); g_return_if_fail (uid != NULL); /* if we've been called to run again - run again */ if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) { EMailSession *session; CamelFolder *local_outbox; session = info->session; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); g_return_if_fail (CAMEL_IS_TRANSPORT (info->service)); info->again = 0; mail_send_queue ( info->session, local_outbox, CAMEL_TRANSPORT (info->service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); return; } //FIXME Set SEND completed here /* if (info->state == SEND_CANCELLED) text = _("Canceled."); else { text = _("Complete."); info->state = SEND_COMPLETE; } */ /* remove/free this active download */ d(printf("%s: freeing info %p\n", G_STRFUNC, info)); if (info->type == SEND_SEND) g_hash_table_steal (info->data->active, SEND_URI_KEY); else g_hash_table_steal (info->data->active, uid); info->data->infos = g_list_remove (info->data->infos, info); if (g_hash_table_size (info->data->active) == 0) { //FIXME: THIS MEANS SEND RECEIVE IS COMPLETED free_send_data (); } free_send_info (info); }
static void send_receive (EMailSession *session, gboolean allow_send) { CamelFolder *local_outbox; struct _send_data *data; GList *scan; if (send_data) /* Send Receive is already in progress */ return; if (!camel_session_get_online (CAMEL_SESSION (session))) return; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); data = build_infra (session, allow_send); for (scan = data->infos; scan != NULL; scan = scan->next) { struct _send_info *info = scan->data; if (!CAMEL_IS_SERVICE (info->service)) continue; switch (info->type) { case SEND_RECEIVE: mail_fetch_mail ( CAMEL_STORE (info->service), CAMEL_FETCH_OLD_MESSAGES, -1, E_FILTER_SOURCE_INCOMING, mail_provider_fetch_lock, mail_provider_fetch_unlock, mail_provider_fetch_inbox_folder, info->cancellable, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_SEND: /* todo, store the folder in info? */ mail_send_queue ( session, local_outbox, CAMEL_TRANSPORT (info->service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); break; case SEND_UPDATE: receive_update_got_store ( CAMEL_STORE (info->service), info); break; default: break; } } return ; }
/** * em_utils_folder_is_outbox: * @registry: an #ESourceRegistry * @folder: a #CamelFolder * * Decides if @folder is an Outbox folder. * * Returns %TRUE if this is an Outbox folder or %FALSE otherwise. **/ gboolean em_utils_folder_is_outbox (ESourceRegistry *registry, CamelFolder *folder) { CamelStore *store; CamelSession *session; CamelFolder *local_outbox_folder; gboolean is_outbox; g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); store = camel_folder_get_parent_store (folder); session = camel_service_ref_session (CAMEL_SERVICE (store)); local_outbox_folder = e_mail_session_get_local_folder ( E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX); is_outbox = (folder == local_outbox_folder); g_object_unref (session); return is_outbox; }
static struct _send_data * setup_send_data (EMailSession *session) { struct _send_data *data; if (send_data == NULL) { send_data = data = g_malloc0 (sizeof (*data)); data->lock = g_mutex_new (); data->folders = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) free_folder_info); data->inbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_LOCAL_INBOX); g_object_ref (data->inbox); data->active = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) free_send_info); } return send_data; }
static void mail_send_short_to_thread (GSimpleAsyncResult *simple, EMailSession *session, GCancellable *cancellable) { SendAsyncContext *context; CamelFolder *local_sent_folder; CamelProvider *provider; CamelService *service; CamelInternetAddress *cia; const gchar *addr; gint i, len; gboolean copy_to_sent = TRUE; GError *error = NULL; gboolean success = FALSE; gboolean did_connect = FALSE; gboolean cancelled = FALSE; context = g_simple_async_result_get_op_res_gpointer (simple); /* Connect transport service */ service = context->transport; if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED) { did_connect = TRUE; if (!camel_service_connect_sync (service, &error)) { mail_send_short_connection_fail (context); g_simple_async_result_take_error (simple, error); return; } } provider = camel_service_get_provider (service); if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) copy_to_sent = FALSE; /* Send the message to each individual recipient. */ len = camel_address_length (context->recipients); for (i = 0; i < len; i++) { if (!cancelled) { if (!camel_internet_address_get( CAMEL_INTERNET_ADDRESS(context->recipients), i, NULL, &addr)) continue; cia = camel_internet_address_new (); camel_internet_address_add (cia, NULL, addr); camel_transport_send_to_sync ( CAMEL_TRANSPORT (service), context->message, context->from, CAMEL_ADDRESS(cia), cancellable, &error); g_object_unref(cia); } if (error) { g_variant_builder_add (context->result, "(sssi)", addr, error->message, g_quark_to_string(error->domain), error->code); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) cancelled = TRUE; else g_clear_error (&error); } else { g_variant_builder_add (context->result, "(sssi)", addr, "", "", 0); success = TRUE; } camel_operation_progress (cancellable, (i+1)*100/len); } g_clear_error (&error); if (did_connect) camel_service_disconnect_sync (service, FALSE, NULL); /*** Post Processing ***/ if (!success) { g_simple_async_result_set_error ( simple, E_MAIL_ERROR, E_MAIL_ERROR_POST_PROCESSING, _("All recipients failed")); return; } /* Run filters on the outgoing message. */ if (context->driver != NULL) { camel_filter_driver_filter_message ( context->driver, context->message, context->info, NULL, NULL, NULL, "", cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; g_clear_error (&error); } if (!copy_to_sent) goto cleanup; /* Append the sent message to a Sent folder. */ local_sent_folder = e_mail_session_get_local_folder (session, E_MAIL_LOCAL_FOLDER_SENT); /* Try to extract a CamelFolder from the Sent folder URI. */ if (context->sent_folder_uri != NULL) { context->sent_folder = e_mail_session_uri_to_folder_sync ( session, context->sent_folder_uri, 0, cancellable, &error); if (error != NULL) { g_warn_if_fail (context->sent_folder == NULL); g_clear_error (&error); } } /* Fall back to the local Sent folder. */ if (context->sent_folder == NULL) context->sent_folder = g_object_ref (local_sent_folder); /* Append the message. */ camel_folder_append_message_sync ( context->sent_folder, context->message, context->info, NULL, cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; if (error == NULL) goto cleanup; /* If appending to a remote Sent folder failed, * try appending to the local Sent folder. */ if (context->sent_folder != local_sent_folder) { g_clear_error (&error); camel_folder_append_message_sync (local_sent_folder, context->message, context->info, NULL, cancellable, &error); } if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; /* We can't even append to the local Sent folder? * In that case just leave the message in Outbox. */ if (error != NULL) { g_clear_error (&error); goto exit; } cleanup: /* The send operation was successful; ignore cleanup errors. */ /* Mark the draft message for deletion, if present. */ e_mail_session_handle_draft_headers_sync (session, context->message, cancellable, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } /* Set flags on the original source message, if present. * Source message refers to the message being forwarded * or replied to. */ e_mail_session_handle_source_headers_sync (session, context->message, cancellable, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } exit: /* If we were cancelled, disregard any other errors. */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_simple_async_result_take_error (simple, error); /* Stuff the accumulated error messages in a GError. */ } else if (error != NULL) { g_simple_async_result_set_error (simple, E_MAIL_ERROR, E_MAIL_ERROR_POST_PROCESSING, "%s", error->message); } /* Synchronize the Sent folder. */ if (context->sent_folder != NULL) camel_folder_synchronize_sync (context->sent_folder, FALSE, cancellable, NULL); }
static void mail_session_send_to_thread (GSimpleAsyncResult *simple, EMailSession *session, GCancellable *cancellable) { AsyncContext *context; CamelProvider *provider; CamelFolder *folder = NULL; CamelFolder *local_sent_folder; CamelServiceConnectionStatus status; GString *error_messages; gboolean copy_to_sent = TRUE; gboolean did_connect = FALSE; guint ii; GError *error = NULL; context = g_simple_async_result_get_op_res_gpointer (simple); if (camel_address_length (context->recipients) == 0) goto skip_send; /* Send the message to all recipients. */ /* XXX Leave this untranslated in gnome-3-8. * It was added during the string freeze, * but should rarely ever be seen by users. */ if (context->transport == NULL) { g_simple_async_result_set_error ( simple, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, "No mail transport service available"); return; } status = camel_service_get_connection_status (context->transport); if (status != CAMEL_SERVICE_CONNECTED) { did_connect = TRUE; camel_service_connect_sync ( context->transport, cancellable, &error); if (error != NULL) { g_simple_async_result_take_error (simple, error); return; } } provider = camel_service_get_provider (context->transport); if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) copy_to_sent = FALSE; camel_transport_send_to_sync ( CAMEL_TRANSPORT (context->transport), context->message, context->from, context->recipients, cancellable, &error); if (did_connect) { /* Disconnect regardless of error or cancellation, * but be mindful of these conditions when calling * camel_service_disconnect_sync(). */ if (g_cancellable_is_cancelled (cancellable)) { camel_service_disconnect_sync ( context->transport, FALSE, NULL, NULL); } else if (error != NULL) { camel_service_disconnect_sync ( context->transport, FALSE, cancellable, NULL); } else { camel_service_disconnect_sync ( context->transport, TRUE, cancellable, &error); } if (error != NULL) { g_simple_async_result_take_error (simple, error); return; } } skip_send: /* Post the message to requested folders. */ for (ii = 0; ii < context->post_to_uris->len; ii++) { CamelFolder *folder; const gchar *folder_uri; folder_uri = g_ptr_array_index (context->post_to_uris, ii); folder = e_mail_session_uri_to_folder_sync ( session, folder_uri, 0, cancellable, &error); if (error != NULL) { g_warn_if_fail (folder == NULL); g_simple_async_result_take_error (simple, error); return; } g_return_if_fail (CAMEL_IS_FOLDER (folder)); camel_folder_append_message_sync ( folder, context->message, context->info, NULL, cancellable, &error); g_object_unref (folder); if (error != NULL) { g_simple_async_result_take_error (simple, error); return; } } /*** Post Processing ***/ /* This accumulates error messages during post-processing. */ error_messages = g_string_sized_new (256); mail_tool_restore_xevolution_headers (context->message, context->xev); /* Run filters on the outgoing message. */ if (context->driver != NULL) { camel_filter_driver_filter_message ( context->driver, context->message, context->info, NULL, NULL, NULL, "", cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; if (error != NULL) { g_string_append_printf ( error_messages, _("Failed to apply outgoing filters: %s"), error->message); g_clear_error (&error); } if ((camel_message_info_flags (context->info) & CAMEL_MESSAGE_DELETED) != 0) copy_to_sent = FALSE; } if (!copy_to_sent) goto cleanup; /* Append the sent message to a Sent folder. */ local_sent_folder = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_SENT); folder = e_mail_session_get_fcc_for_message_sync ( session, context->message, cancellable, &error); /* Sanity check. */ g_return_if_fail ( ((folder != NULL) && (error == NULL)) || ((folder == NULL) && (error != NULL))); /* Append the message. */ if (folder != NULL) camel_folder_append_message_sync ( folder, context->message, context->info, NULL, cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; if (error == NULL) goto cleanup; if (folder != NULL && folder != local_sent_folder) { const gchar *description; description = camel_folder_get_description (folder); if (error_messages->len > 0) g_string_append (error_messages, "\n\n"); g_string_append_printf ( error_messages, _("Failed to append to %s: %s\n" "Appending to local 'Sent' folder instead."), description, error->message); } /* If appending to a remote Sent folder failed, * try appending to the local Sent folder. */ if (folder != local_sent_folder) { g_clear_error (&error); camel_folder_append_message_sync ( local_sent_folder, context->message, context->info, NULL, cancellable, &error); } if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; /* We can't even append to the local Sent folder? * In that case just leave the message in Outbox. */ if (error != NULL) { if (error_messages->len > 0) g_string_append (error_messages, "\n\n"); g_string_append_printf ( error_messages, _("Failed to append to local 'Sent' folder: %s"), error->message); g_clear_error (&error); goto exit; } cleanup: /* The send operation was successful; ignore cleanup errors. */ /* Mark the draft message for deletion, if present. */ e_mail_session_handle_draft_headers_sync ( session, context->message, cancellable, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } /* Set flags on the original source message, if present. * Source message refers to the message being forwarded * or replied to. */ e_mail_session_handle_source_headers_sync ( session, context->message, cancellable, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); } exit: /* If we were cancelled, disregard any other errors. */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_simple_async_result_take_error (simple, error); /* Stuff the accumulated error messages in a GError. */ } else if (error_messages->len > 0) { g_simple_async_result_set_error ( simple, E_MAIL_ERROR, E_MAIL_ERROR_POST_PROCESSING, "%s", error_messages->str); } /* Synchronize the Sent folder. */ if (folder != NULL) { camel_folder_synchronize_sync ( folder, FALSE, cancellable, NULL); g_object_unref (folder); } g_string_free (error_messages, TRUE); }
/** * e_mail_session_get_fcc_for_message_sync: * @session: an #EMailSession * @message: a #CamelMimeMessage * @cancellable: optional #GCancellable object, or %NULL * @error: return location for a #GError, or %NULL * * Obtains the preferred "carbon-copy" folder (a.k.a Fcc) for @message * by first checking @message for an "X-Evolution-Identity" header, and * then an "X-Evolution-Fcc" header. Failing that, the function checks * the default mail identity (if available), and failing even that, the * function falls back to the Sent folder from the built-in mail store. * * Where applicable, the function attempts to honor the * #ESourceMailSubmission:replies-to-origin-folder preference. * * The returned #CamelFolder is referenced for thread-safety and must be * unreferenced with g_object_unref() when finished with it. * * If a non-recoverable error occurs, the function sets @error and returns * %NULL. * * Returns: a #CamelFolder, or %NULL **/ CamelFolder * e_mail_session_get_fcc_for_message_sync (EMailSession *session, CamelMimeMessage *message, GCancellable *cancellable, GError **error) { CamelFolder *folder = NULL; g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); /* Check for "X-Evolution-Identity" header. */ if (folder == NULL) { GError *local_error = NULL; /* This may return NULL without setting a GError. */ folder = mail_session_ref_fcc_from_x_identity ( session, message, cancellable, &local_error); if (local_error != NULL) { g_warn_if_fail (folder == NULL); g_propagate_error (error, local_error); return NULL; } } /* Check for "X-Evolution-Fcc" header. */ if (folder == NULL) { GError *local_error = NULL; /* This may return NULL without setting a GError. */ folder = mail_session_ref_fcc_from_x_fcc ( session, message, cancellable, &local_error); if (local_error != NULL) { g_warn_if_fail (folder == NULL); g_propagate_error (error, local_error); return NULL; } } /* Check the default mail identity. */ if (folder == NULL) { GError *local_error = NULL; /* This may return NULL without setting a GError. */ folder = mail_session_ref_fcc_from_default_identity ( session, message, cancellable, &local_error); if (local_error != NULL) { g_warn_if_fail (folder == NULL); g_propagate_error (error, local_error); return NULL; } } /* Last resort - local Sent folder. */ if (folder == NULL) { folder = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_SENT); g_object_ref (folder); } return folder; }
static struct _send_data * build_infra (EMailSession *session, gboolean allow_send) { struct _send_data *data; struct _send_info *info; CamelService *transport = NULL; GList *link; GList *list = NULL; GList *accounts=NULL; transport = ref_default_transport (session); accounts = mail_get_all_accounts(); data = setup_send_data (session); link = accounts; while (link) { ESource *source; CamelService *service; const gchar *uid; source = (ESource *)link->data; if (!e_source_get_enabled(source)) { link = link->next; continue; } uid = e_source_get_uid (source); service = camel_session_ref_service ( CAMEL_SESSION (session), uid); /* see if we have an outstanding download active */ info = g_hash_table_lookup (data->active, uid); if (info == NULL) { send_info_t type = SEND_INVALID; type = get_receive_type (service); if (type == SEND_INVALID || type == SEND_SEND) { link = link->next; continue; } info = g_malloc0 (sizeof (*info)); info->type = type; info->session = g_object_ref (session); d(printf("adding source %s\n", source->url)); info->service = g_object_ref (service); info->keep_on_server = mail_get_keep_on_server (service); info->cancellable = camel_operation_new (); info->state = allow_send ? SEND_ACTIVE : SEND_COMPLETE; info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); g_hash_table_insert ( data->active, g_strdup(uid), info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); info->data = data; link = link->next; } g_list_free_full (accounts, (GDestroyNotify) g_object_unref); /* Skip displaying the SMTP row if we've got no outbox, * outgoing account or unsent mails. */ CamelFolder *local_outbox; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); if (allow_send && local_outbox && CAMEL_IS_TRANSPORT (transport) && (camel_folder_get_message_count (local_outbox) - camel_folder_get_deleted_message_count (local_outbox)) != 0) { info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info == NULL) { info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; info->service = g_object_ref (transport); info->keep_on_server = FALSE; info->cancellable = camel_operation_new (); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); g_hash_table_insert (data->active, g_strdup(SEND_URI_KEY), info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); info->data = data; } data->infos = list; return data; }
GCancellable * mail_send (EMailSession *session) { CamelFolder *local_outbox; CamelService *service; struct _send_info *info; struct _send_data *data; send_info_t type = SEND_INVALID; const gchar *transport_uid; ESource *account; const gchar *extension_name; account = e_source_registry_ref_default_mail_identity (source_registry); if (account == NULL) return NULL; extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION; if (e_source_has_extension (account, extension_name)) { ESourceMailSubmission *extension; gchar *uid; extension = e_source_get_extension (account, extension_name); uid = e_source_mail_submission_dup_transport_uid (extension); g_object_unref (account); account = e_source_registry_ref_source (source_registry, uid); g_free (uid); } else { g_object_unref (account); account = NULL; } if (account == NULL) return NULL; transport_uid = e_source_get_uid (account); data = setup_send_data (session); info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info != NULL) { info->again++; d(printf("send of %s still in progress\n", transport_uid)); return info->cancellable; } service = camel_session_ref_service ( CAMEL_SESSION (session), transport_uid); if (!CAMEL_IS_TRANSPORT (service)) { return NULL; } d(printf("starting non-interactive send of '%s'\n", account->transport->url)); type = get_receive_type (service); if (type == SEND_INVALID) { return NULL; } info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; info->session = g_object_ref (session); info->service = g_object_ref (service); info->keep_on_server = FALSE; info->cancellable = camel_operation_new(); info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, g_strdup(SEND_URI_KEY), info); /* todo, store the folder in info? */ local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); mail_send_queue ( session, local_outbox, CAMEL_TRANSPORT (service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); return info->cancellable; }
/* We setup the download info's in a hashtable, if we later * need to build the gui, we insert them in to add them. */ GCancellable * mail_receive_service (CamelService *service) { struct _send_info *info; struct _send_data *data; CamelFolder *local_outbox; const gchar *uid; EMailSession *session; send_info_t type = SEND_INVALID; g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); session = (EMailSession *)camel_service_get_session (service); uid = camel_service_get_uid (service); data = setup_send_data (session); info = g_hash_table_lookup (data->active, uid); if (info != NULL) return info->cancellable; type = get_receive_type (service); if (type == SEND_INVALID || type == SEND_SEND) return NULL; info = g_malloc0 (sizeof (*info)); info->type = type; info->session = g_object_ref (session); info->service = g_object_ref (service); info->keep_on_server = mail_get_keep_on_server (service); info->cancellable = camel_operation_new (); info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, g_strdup(uid), info); switch (info->type) { case SEND_RECEIVE: mail_fetch_mail ( CAMEL_STORE (service), CAMEL_FETCH_OLD_MESSAGES, -1, E_FILTER_SOURCE_INCOMING, mail_provider_fetch_lock, mail_provider_fetch_unlock, mail_provider_fetch_inbox_folder, info->cancellable, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_SEND: /* todo, store the folder in info? */ local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); mail_send_queue ( info->session, local_outbox, CAMEL_TRANSPORT (service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); break; case SEND_UPDATE: receive_update_got_store (CAMEL_STORE (service), info); break; default: g_return_val_if_reached (NULL); } return info->cancellable; }
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] */ }