void camel_gw_summary_add_offline (CamelFolderSummary *summary, const char *uid, CamelMimeMessage *message, const CamelMessageInfo *info) { CamelGroupwiseMessageInfo *mi ; const CamelFlag *flag ; const CamelTag *tag ; /* Create summary entry */ mi = (CamelGroupwiseMessageInfo *)camel_folder_summary_info_new_from_message (summary, message) ; /* Copy flags 'n' tags */ mi->info.flags = camel_message_info_flags(info) ; flag = camel_message_info_user_flags(info) ; while (flag) { camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE); flag = flag->next; } tag = camel_message_info_user_tags(info); while (tag) { camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value); tag = tag->next; } mi->info.size = camel_message_info_size(info); mi->info.uid = g_strdup (uid); camel_folder_summary_add (summary, (CamelMessageInfo *)mi); }
/* check the total/unread is what we think it should be */ void test_folder_counts (CamelFolder *folder, gint total, gint unread) { GPtrArray *s; gint i, myunread; CamelMessageInfo *info; push ("test folder counts %d total %d unread", total, unread); /* use the summary */ s = camel_folder_get_summary (folder); check (s != NULL); check (s->len == total); myunread = s->len; for (i=0;i<s->len;i++) { info = s->pdata[i]; if (camel_message_info_flags (info) & CAMEL_MESSAGE_SEEN) myunread--; } check (unread == myunread); camel_folder_free_summary (folder, s); /* use the uid list */ s = camel_folder_get_uids (folder); check (s != NULL); check (s->len == total); myunread = s->len; for (i=0;i<s->len;i++) { info = camel_folder_get_message_info (folder, s->pdata[i]); if (camel_message_info_flags (info) & CAMEL_MESSAGE_SEEN) myunread--; camel_folder_free_message_info (folder, info); } check (unread == myunread); camel_folder_free_uids (folder, s); pull (); }
static CamelSExpResult * system_flag (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms) { CamelSExpResult *r; if (argc != 1 || argv[0]->type != CAMEL_SEXP_RES_STRING) camel_sexp_fatal_error (f, _("Invalid arguments to (system-flag)")); r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL); r->value.boolean = camel_system_flag_get (camel_message_info_flags (fms->info), argv[0]->value.string); return r; }
static gboolean nntp_folder_expunge_sync (CamelFolder *folder, GCancellable *cancellable, GError **error) { CamelFolderSummary *summary; CamelFolderChangeInfo *changes; GPtrArray *known_uids; guint ii; summary = folder->summary; camel_folder_summary_prepare_fetch_all (summary, NULL); known_uids = camel_folder_summary_get_array (summary); if (known_uids == NULL) return TRUE; changes = camel_folder_change_info_new (); for (ii = 0; ii < known_uids->len; ii++) { CamelMessageInfo *info; const gchar *uid; uid = g_ptr_array_index (known_uids, ii); info = camel_folder_summary_get (summary, uid); if (camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED) { camel_folder_change_info_remove_uid (changes, uid); camel_folder_summary_remove (summary, info); } camel_message_info_unref (info); } camel_folder_summary_save_to_db (summary, NULL); camel_folder_changed (folder, changes); camel_folder_change_info_free (changes); camel_folder_summary_free_array (known_uids); return TRUE; }
static gboolean vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) { gint res = FALSE; CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary)); if (camel_debug("vfolderexp")) printf ( "Expression for vfolder '%s' is '%s'\n", camel_folder_get_full_name (CAMEL_FOLDER (vf)), g_strescape (vf->expression, "")); /* first update original message info... */ if (mi->uid) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); HANDLE_NULL_INFO (FALSE); /* ignore changes done in the folder itself, * unless it's a vTrash or vJunk folder */ if (!CAMEL_IS_VTRASH_FOLDER (vf)) camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary)); camel_folder_freeze (camel_folder_summary_get_folder (rmi->summary)); res = camel_message_info_set_flags (rmi, flags, set); ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi); camel_folder_thaw (camel_folder_summary_get_folder (rmi->summary)); camel_message_info_free (rmi); } if (res) CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags, set); return res; }
static CamelSExpResult * junk_test (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms) { CamelSExpResult *r; CamelMessageInfo *info = fms->info; CamelJunkFilter *junk_filter; CamelMessageFlags flags; CamelMimeMessage *message; CamelJunkStatus status; const GHashTable *ht; const struct _camel_header_param *node; gboolean sender_is_known; gboolean message_is_junk = FALSE; GError *error = NULL; junk_filter = camel_session_get_junk_filter (fms->session); if (junk_filter == NULL) goto exit; /* Check if the message is already classified. */ flags = camel_message_info_flags (info); if (flags & CAMEL_MESSAGE_JUNK) { if (camel_debug ("junk")) printf ( "Message has a Junk flag set already, " "skipping junk test...\n"); goto exit; } if (flags & CAMEL_MESSAGE_NOTJUNK) { if (camel_debug ("junk")) printf ( "Message has a NotJunk flag set already, " "skipping junk test...\n"); goto exit; } /* Check the headers for a junk designation. */ ht = camel_session_get_junk_headers (fms->session); node = camel_message_info_headers (info); while (node != NULL) { const gchar *value = NULL; if (node->name != NULL) value = g_hash_table_lookup ( (GHashTable *) ht, node->name); message_is_junk = (value != NULL) && (camel_strstrcase (node->value, value) != NULL); if (message_is_junk) { if (camel_debug ("junk")) printf ( "Message contains \"%s: %s\"", node->name, value); goto done; } node = node->next; } /* If the sender is known, the message is not junk. */ sender_is_known = camel_session_lookup_addressbook ( fms->session, camel_message_info_from (info)); if (camel_debug ("junk")) printf ( "Sender '%s' in book? %d\n", camel_message_info_from (info), sender_is_known); if (sender_is_known) goto done; /* Consult 3rd party junk filtering software. */ message = camel_filter_search_get_message (fms, f); status = camel_junk_filter_classify ( junk_filter, message, NULL, &error); if (error == NULL) { const gchar *status_desc; switch (status) { case CAMEL_JUNK_STATUS_INCONCLUSIVE: status_desc = "inconclusive"; message_is_junk = FALSE; break; case CAMEL_JUNK_STATUS_MESSAGE_IS_JUNK: status_desc = "junk"; message_is_junk = TRUE; break; case CAMEL_JUNK_STATUS_MESSAGE_IS_NOT_JUNK: status_desc = "not junk"; message_is_junk = FALSE; break; default: g_warn_if_reached (); status_desc = "invalid"; message_is_junk = FALSE; break; } if (camel_debug ("junk")) g_print ( "Junk filter classification: %s\n", status_desc); } else { g_warn_if_fail (status == CAMEL_JUNK_STATUS_ERROR); g_warning ("%s: %s", G_STRFUNC, error->message); g_error_free (error); message_is_junk = FALSE; } done: if (camel_debug ("junk")) printf ( "Message is determined to be %s\n", message_is_junk ? "*JUNK*" : "clean"); exit: r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL); r->value.number = message_is_junk; return r; }
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); }
static gboolean vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) { gint res = FALSE; CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder; gboolean hacked_unread_folder = FALSE; if (camel_debug("vfolderexp")) printf ( "Expression for vfolder '%s' is '%s'\n", camel_folder_get_full_name (mi->summary->folder), g_strescape (vf->expression, "")); if (camel_vee_folder_get_unread_vfolder (vf) == -1) camel_vee_summary_load_check_unread_vfolder (CAMEL_VEE_SUMMARY (mi->summary)); if (camel_vee_folder_get_unread_vfolder (vf) == 1) hacked_unread_folder = TRUE; if (mi->uid) { guint32 old_visible, visible, old_unread; CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *)mi)->summary, mi->uid+8); CamelVeeSummary *vsummary = (CamelVeeSummary *)mi->summary; HANDLE_NULL_INFO (FALSE); old_visible = rmi->summary->visible_count; old_unread = mi->summary->unread_count; camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), TRUE); if (hacked_unread_folder) camel_vee_folder_mask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder); camel_folder_freeze (rmi->summary->folder); res = camel_message_info_set_flags (rmi, flags, set); ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi); camel_folder_thaw (rmi->summary->folder); if (hacked_unread_folder) camel_vee_folder_unmask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder); visible = rmi->summary->visible_count; /* Keep the summary in sync */ camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), FALSE); if (hacked_unread_folder && !vsummary->fake_visible_count) vsummary->fake_visible_count = mi->summary->visible_count; if (vsummary->fake_visible_count || hacked_unread_folder) vsummary->fake_visible_count += visible - old_visible; d(printf("VF %d %d %d %d %d\n", mi->summary->unread_count, mi->summary->deleted_count, mi->summary->junk_count, mi->summary->junk_not_deleted_count, mi->summary->visible_count)); /* This is where the ugly-created-hack is used */ if (hacked_unread_folder && mi->summary->unread_count - old_unread != 0) { CamelFolderChangeInfo *changes = camel_folder_change_info_new (); GPtrArray *match, *array; camel_folder_change_info_change_uid (changes, mi->uid); array = g_ptr_array_new (); g_ptr_array_add (array, (gpointer)rmi->uid); match = camel_folder_search_by_uids (rmi->summary->folder, vf->expression, array, NULL); if ((match && !match->len) || !match) { vsummary->fake_visible_count--; } else { vsummary->fake_visible_count++; } g_ptr_array_free (array, TRUE); if (match) camel_folder_search_free (rmi->summary->folder, match); camel_folder_changed (mi->summary->folder, changes); camel_folder_change_info_free (changes); } camel_message_info_free (rmi); } return res; }
static gboolean maildir_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream; CamelMessageInfo *mi; CamelMaildirMessageInfo *mdi; gchar *name, *dest = NULL; gboolean success = TRUE; d(printf("Appending message\n")); /* If we can't lock, don't do anything */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return FALSE; /* add it to the summary/assign the uid, etc */ mi = camel_local_summary_add ( CAMEL_LOCAL_SUMMARY (folder->summary), message, info, lf->changes, error); if (mi == NULL) goto check_changed; if ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !camel_mime_message_has_attachment (message)) camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 0); mdi = (CamelMaildirMessageInfo *)mi; d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename)); /* write it out to tmp, use the uid we got from the summary */ name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi)); output_stream = camel_stream_fs_new_with_name ( name, O_WRONLY|O_CREAT, 0600, error); if (output_stream == NULL) goto fail_write; if (camel_data_wrapper_write_to_stream_sync ( (CamelDataWrapper *)message, output_stream, cancellable, error) == -1 || camel_stream_close (output_stream, cancellable, error) == -1) goto fail_write; /* now move from tmp to cur (bypass new, does it matter?) */ dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (name, dest) == -1) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), "%s", g_strerror (errno)); goto fail_write; } g_free (dest); g_free (name); if (appended_uid) *appended_uid = g_strdup(camel_message_info_uid(mi)); if (output_stream) g_object_unref (output_stream); goto check_changed; fail_write: /* remove the summary info so we are not out-of-sync with the mh folder */ camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary), camel_message_info_uid (mi)); g_prefix_error ( error, _("Cannot append message to maildir folder: %s: "), name); if (output_stream) { g_object_unref (CAMEL_OBJECT (output_stream)); unlink (name); } g_free (name); g_free (dest); success = FALSE; check_changed: 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 success; }
static void create_mime_message_cb (ESoapMessage *msg, gpointer user_data) { struct _create_mime_msg_data *create_data = user_data; CamelStream *mem, *filtered; CamelMimeFilter *filter; CamelContentType *content_type; GByteArray *bytes; gchar *base64; gint msgflag; guint32 message_camel_flags = 0; if (create_data->info) message_camel_flags = camel_message_info_flags (create_data->info); e_soap_message_start_element (msg, "Message", NULL, NULL); e_soap_message_start_element (msg, "MimeContent", NULL, NULL); /* This is horrid. We really need to extend ESoapMessage to allow us * to stream this directly rather than storing it in RAM. Which right * now we are doing about four times: the GByteArray in the mem stream, * then the base64 version, then the xmlDoc, then the soup request. */ camel_mime_message_set_best_encoding ( create_data->message, CAMEL_BESTENC_GET_ENCODING, CAMEL_BESTENC_8BIT); mem = camel_stream_mem_new (); filtered = camel_stream_filter_new (mem); filter = camel_mime_filter_crlf_new ( CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY); camel_stream_filter_add (CAMEL_STREAM_FILTER (filtered), filter); g_object_unref (filter); camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (create_data->message), filtered, NULL, NULL); camel_stream_flush (filtered, NULL, NULL); camel_stream_flush (mem, NULL, NULL); bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem)); base64 = g_base64_encode (bytes->data, bytes->len); g_object_unref (mem); g_object_unref (filtered); e_soap_message_write_string (msg, base64); g_free (base64); e_soap_message_end_element (msg); /* MimeContent */ content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (create_data->message)); if (content_type && camel_content_type_is (content_type, "multipart", "report") && camel_content_type_param (content_type, "report-type") && g_ascii_strcasecmp (camel_content_type_param (content_type, "report-type"), "disposition-notification") == 0) { /* it's a disposition notification reply, set ItemClass too */ e_soap_message_start_element (msg, "ItemClass", NULL, NULL); e_soap_message_write_string (msg, "REPORT.IPM.NOTE.IPNRN"); e_soap_message_end_element (msg); /* ItemClass */ } e_ews_message_write_string_parameter_with_attribute ( msg, "Importance", NULL, (message_camel_flags & CAMEL_MESSAGE_FLAGGED) != 0 ? "High" : "Normal", NULL, NULL); /* more MAPI crap. You can't just set the IsDraft property * here you have to use the MAPI MSGFLAG_UNSENT extended * property Further crap is that Exchange 2007 assumes when it * sees this property that you're setting the value to 0 * ... it never checks */ msgflag = MAPI_MSGFLAG_READ; /* draft or sent is always read */ if ((message_camel_flags & CAMEL_MESSAGE_DRAFT) != 0) msgflag |= MAPI_MSGFLAG_UNSENT; e_ews_message_add_extended_property_tag_int (msg, 0x0e07, msgflag); if ((message_camel_flags & (CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_ANSWERED)) != 0) { gint icon; icon = (message_camel_flags & CAMEL_MESSAGE_ANSWERED) != 0 ? 0x105 : 0x106; e_ews_message_add_extended_property_tag_int (msg, 0x1080, icon); } if (create_data->info) { const gchar *followup, *completed, *dueby; time_t completed_tt = (time_t) 0 , dueby_tt = (time_t) 0; /* follow-up flags */ followup = camel_message_info_user_tag (create_data->info, "follow-up"); completed = camel_message_info_user_tag (create_data->info, "completed-on"); dueby = camel_message_info_user_tag (create_data->info, "due-by"); if (followup && !*followup) followup = NULL; if (completed && *completed) completed_tt = camel_header_decode_date (completed, NULL); if (dueby && *dueby) dueby_tt = camel_header_decode_date (dueby, NULL); /* PidTagFlagStatus */ e_ews_message_add_extended_property_tag_int (msg, 0x1090, followup ? (completed_tt != (time_t) 0 ? 0x01 /* followupComplete */: 0x02 /* followupFlagged */) : 0x0); if (followup) { /* PidLidFlagRequest */ e_ews_message_add_extended_property_distinguished_tag_string (msg, "Common", 0x8530, followup); /* PidTagToDoItemFlags */ e_ews_message_add_extended_property_tag_int (msg, 0x0e2b, 1); } if (followup && completed_tt != (time_t) 0) { /* minute precision */ completed_tt = completed_tt - (completed_tt % 60); /* PidTagFlagCompleteTime */ e_ews_message_add_extended_property_tag_time (msg, 0x1091, completed_tt); /* PidLidTaskDateCompleted */ e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x810f, completed_tt); /* PidLidTaskStatus */ e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 2); /* PidLidPercentComplete */ e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 1.0); /* PidLidTaskComplete */ e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, TRUE); } if (followup && dueby_tt != (time_t) 0 && completed_tt == (time_t) 0) { /* PidLidTaskStatus */ e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 0); /* PidLidPercentComplete */ e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 0.0); /* PidLidTaskDueDate */ e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x8105, dueby_tt); /* PidLidTaskComplete */ e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, FALSE); } } if (create_data->recipients) { GHashTable *recip_to, *recip_cc, *recip_bcc; recip_to = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); recip_cc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); recip_bcc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); filter_recipients (create_data->message, create_data->recipients, recip_to, recip_cc, recip_bcc); write_recipients (msg, "ToRecipients", recip_to); write_recipients (msg, "CcRecipients", recip_cc); write_recipients (msg, "BccRecipients", recip_bcc); g_hash_table_destroy (recip_to); g_hash_table_destroy (recip_cc); g_hash_table_destroy (recip_bcc); } e_ews_message_write_string_parameter_with_attribute ( msg, "IsRead", NULL, (message_camel_flags & CAMEL_MESSAGE_SEEN) != 0 ? "true" : "false", NULL, NULL); e_soap_message_end_element (msg); /* Message */ g_free (create_data); }
static CamelSExpResult * junk_test (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms) { CamelSExpResult *r; gboolean retval = FALSE; CamelMessageInfo *info = fms->info; CamelJunkFilter *junk_filter; junk_filter = camel_session_get_junk_filter (fms->session); d(printf("doing junk test for message from '%s'\n", camel_message_info_from (fms->info))); if (junk_filter != NULL && (camel_message_info_flags (info) & (CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK)) == 0) { const GHashTable *ht = camel_session_get_junk_headers (fms->session); const struct _camel_header_param *node = camel_message_info_headers (info); while (node && !retval) { if (node->name) { gchar *value = (gchar *) g_hash_table_lookup ((GHashTable *) ht, node->name); d(printf("JunkCheckMatch: %s %s %s\n", node->name, node->value, value)); if (value) retval = camel_strstrcase (node->value, value) != NULL; } node = node->next; } if (camel_debug ("junk")) printf("filtered based on junk header ? %d\n", retval); if (!retval) { retval = camel_session_lookup_addressbook (fms->session, camel_message_info_from (info)) != TRUE; if (camel_debug ("junk")) printf("Sender '%s' in book? %d\n", camel_message_info_from (info), !retval); if (retval) /* Not in book. Could be spam. So check for it */ { CamelMimeMessage *message; CamelJunkStatus status; gboolean success; d(printf("filtering message\n")); message = camel_filter_search_get_message (fms, f); success = camel_junk_filter_classify (junk_filter, message, &status, NULL, NULL); retval = success && (status == CAMEL_JUNK_STATUS_MESSAGE_IS_JUNK); } } if (camel_debug ("junk")) printf("junk filter => %s\n", retval ? "*JUNK*" : "clean"); } else if (junk_filter != NULL && camel_debug ("junk")) { if (camel_message_info_flags (info) & CAMEL_MESSAGE_JUNK) printf ("Message has a Junk flag set already, skipping junk test...\n"); else if (camel_message_info_flags (info) & CAMEL_MESSAGE_NOTJUNK) printf ("Message has a NotJunk flag set already, skipping junk test...\n"); } r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL); r->value.number = retval; return r; }
static gboolean mh_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelStream *output_stream; CamelMessageInfo *mi; gchar *name; gboolean has_attachment; /* FIXME: probably needs additional locking (although mh doesn't appear do do it) */ d(printf("Appending message\n")); /* If we can't lock, don't do anything */ if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return FALSE; /* add it to the summary/assign the uid, etc */ mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error); if (mi == NULL) goto check_changed; has_attachment = camel_mime_message_has_attachment (message); if (((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) || ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) { camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0); } d(printf("Appending message: uid is %s\n", camel_message_info_uid(mi))); /* write it out, use the uid we got from the summary */ name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi)); output_stream = camel_stream_fs_new_with_name ( name, O_WRONLY | O_CREAT, 0600, error); if (output_stream == NULL) goto fail_write; if (camel_data_wrapper_write_to_stream_sync ( (CamelDataWrapper *) message, output_stream, cancellable, error) == -1 || camel_stream_close (output_stream, cancellable, error) == -1) goto fail_write; /* close this? */ g_object_unref (output_stream); g_free (name); if (appended_uid) *appended_uid = g_strdup(camel_message_info_uid(mi)); goto check_changed; fail_write: /* remove the summary info so we are not out-of-sync with the mh folder */ camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary), camel_message_info_uid (mi)); g_prefix_error ( error, _("Cannot append message to mh folder: %s: "), name); if (output_stream) { g_object_unref (output_stream); unlink (name); } g_free (name); check_changed: 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 TRUE; }
static gboolean mbox_folder_append_message_sync (CamelFolder *folder, CamelMimeMessage *message, CamelMessageInfo *info, gchar **appended_uid, GCancellable *cancellable, GError **error) { CamelLocalFolder *lf = (CamelLocalFolder *) folder; CamelStream *output_stream = NULL, *filter_stream = NULL; CamelMimeFilter *filter_from; CamelMboxSummary *mbs = (CamelMboxSummary *) folder->summary; CamelMessageInfo *mi; gchar *fromline = NULL; struct stat st; gint retval; gboolean has_attachment; #if 0 gchar *xev; #endif /* If we can't lock, dont do anything */ if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1) return FALSE; d (printf ("Appending message\n")); /* first, check the summary is correct (updates folder_size too) */ retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error); if (retval == -1) goto fail; /* add it to the summary/assign the uid, etc */ mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error); if (mi == NULL) goto fail; d (printf ("Appending message: uid is %s\n", camel_message_info_uid (mi))); has_attachment = camel_mime_message_has_attachment (message); if (((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) || ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) { camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0); } output_stream = camel_stream_fs_new_with_name ( lf->folder_path, O_WRONLY | O_APPEND | O_LARGEFILE, 0666, error); if (output_stream == NULL) { g_prefix_error ( error, _("Cannot open mailbox: %s: "), lf->folder_path); goto fail; } /* and we need to set the frompos/XEV explicitly */ ((CamelMboxMessageInfo *) mi)->frompos = mbs->folder_size; #if 0 xev = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) folder->summary, mi); if (xev) { /* the x-ev header should match the 'current' flags, no problem, so store as much */ camel_medium_set_header ((CamelMedium *) message, "X-Evolution", xev); mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED; g_free (xev); } #endif /* we must write this to the non-filtered stream ... */ fromline = camel_mime_message_build_mbox_from (message); if (camel_stream_write (output_stream, fromline, strlen (fromline), cancellable, error) == -1) goto fail_write; /* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */ filter_stream = camel_stream_filter_new (output_stream); filter_from = camel_mime_filter_from_new (); camel_stream_filter_add ((CamelStreamFilter *) filter_stream, filter_from); g_object_unref (filter_from); if (camel_data_wrapper_write_to_stream_sync ( (CamelDataWrapper *) message, filter_stream, cancellable, error) == -1 || camel_stream_write (filter_stream, "\n", 1, cancellable, error) == -1 || camel_stream_flush (filter_stream, cancellable, error) == -1) goto fail_write; /* filter stream ref's the output stream itself, so we need to unref it too */ g_object_unref (filter_stream); g_object_unref (output_stream); g_free (fromline); if (!((CamelMessageInfoBase *) mi)->preview && camel_folder_summary_get_need_preview (folder->summary)) { if (camel_mime_message_build_preview ((CamelMimePart *) message, mi) && ((CamelMessageInfoBase *) mi)->preview) camel_folder_summary_add_preview (folder->summary, mi); } /* now we 'fudge' the summary to tell it its uptodate, because its idea of uptodate has just changed */ /* the stat really shouldn't fail, we just wrote to it */ if (g_stat (lf->folder_path, &st) == 0) { ((CamelFolderSummary *) mbs)->time = st.st_mtime; mbs->folder_size = st.st_size; } /* unlock as soon as we can */ 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); } if (appended_uid) *appended_uid = g_strdup(camel_message_info_uid(mi)); return TRUE; fail_write: g_prefix_error ( error, _("Cannot append message to mbox file: %s: "), lf->folder_path); if (output_stream) { gint fd; fd = camel_stream_fs_get_fd (CAMEL_STREAM_FS (output_stream)); if (fd != -1) { /* reset the file to original size */ do { retval = ftruncate (fd, mbs->folder_size); } while (retval == -1 && errno == EINTR); } g_object_unref (output_stream); } if (filter_stream) g_object_unref (filter_stream); g_free (fromline); /* remove the summary info so we are not out-of-sync with the mbox */ camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (mbs), mi); /* and tell the summary it's up-to-date */ if (g_stat (lf->folder_path, &st) == 0) { ((CamelFolderSummary *) mbs)->time = st.st_mtime; mbs->folder_size = st.st_size; } fail: /* make sure we unlock the folder - before we start triggering events into appland */ camel_local_folder_unlock (lf); /* cascade the changes through, anyway, if there are any outstanding */ if (camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (folder, lf->changes); camel_folder_change_info_clear (lf->changes); } return FALSE; }