gboolean scalix_appointment_init_from_mime_message (ScalixObject * object, CamelMimeMessage * msg) { const char *msgid; const char *attachment_store; const char *mime_type, *alternative_mime_type; const char *content_disposition; const char *mime_filename; const char *cid; const char *cuid; const char *attachment_file_url; GSList *attachments = NULL; GSList *attachments_new = NULL; GSList *siter = NULL; CamelMimePart *part, *alternative; CamelMultipart *multipart, *nested_multipart; CamelDataWrapper *content, *alternative_content; int i, j, num_parts, num_alternatives; gboolean found_ical = FALSE; attachment_store = g_object_get_data (G_OBJECT (object), "attachment-store"); part = CAMEL_MIME_PART (msg); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); if (content == NULL) { return FALSE; } mime_type = camel_content_type_simple (content->mime_type); if (CAMEL_IS_MULTIPART (content)) { multipart = (CamelMultipart *) content; num_parts = (int) camel_multipart_get_number (multipart); for (i = 0; i < num_parts; i++) { part = camel_multipart_get_part (multipart, i); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); mime_type = camel_content_type_simple (content->mime_type); mime_filename = camel_mime_part_get_filename (part); content_disposition = camel_mime_part_get_disposition (part); if (CAMEL_IS_MULTIPART (content)) { nested_multipart = (CamelMultipart *) content; num_alternatives = (int) camel_multipart_get_number (nested_multipart); for (j = 0; j < num_alternatives; j++) { alternative = camel_multipart_get_part (nested_multipart, j); alternative_content = camel_medium_get_content_object (CAMEL_MEDIUM (alternative)); alternative_mime_type = camel_content_type_simple (alternative_content-> mime_type); if (g_str_equal (alternative_mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (alternative, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } } } else if (g_str_equal (mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (part, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } else if (content_disposition && strcmp (content_disposition, "attachment") == 0) { cid = camel_mime_part_get_content_id (part); if (cid != NULL) { for (siter = attachments; siter; siter = siter->next) { if (strstr (siter->data, cid) == (char *) (siter->data) + 4) { attachment_file_url = save_attachment (part, cuid, attachment_store); if (attachment_file_url != NULL) { attachments_new = g_slist_append (attachments_new, g_strdup (attachment_file_url)); } } } } } else { g_print ("XXXXX Unhandled mime part: %s\n", mime_type); } } } else { /* just a simple ical message */ if (g_str_equal (mime_type, "text/calendar")) { set_ical_from_mime_part (part, object); } } if (attachments_new != NULL) { e_cal_component_set_attachment_list (E_CAL_COMPONENT (object), attachments_new); } msgid = camel_mime_message_get_message_id (msg); scalix_appointment_unset (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID); scalix_appointment_set (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID, msgid); return TRUE; }
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 gboolean do_mail_to_event (AsyncData *data) { EClient *client; CamelFolder *folder = data->folder; GPtrArray *uids = data->uids; GError *error = NULL; client = e_client_cache_get_client_sync (data->client_cache, data->source, data->extension_name, 30, NULL, &error); /* Sanity check. */ g_return_val_if_fail ( ((client != NULL) && (error == NULL)) || ((client == NULL) && (error != NULL)), TRUE); if (error != NULL) { report_error_idle (_("Cannot open calendar. %s"), error->message); } else if (e_client_is_readonly (E_CLIENT (client))) { switch (data->source_type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: report_error_idle (_("Selected calendar is read only, thus cannot create event there. Select other calendar, please."), NULL); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: report_error_idle (_("Selected task list is read only, thus cannot create task there. Select other task list, please."), NULL); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: report_error_idle (_("Selected memo list is read only, thus cannot create memo there. Select other memo list, please."), NULL); break; default: g_warn_if_reached (); break; } } else { gint i; ECalComponentDateTime dt, dt2; struct icaltimetype tt, tt2; struct _manage_comp *oldmc = NULL; #define cache_backend_prop(prop) { \ gchar *val = NULL; \ e_client_get_backend_property_sync (E_CLIENT (client), prop, &val, NULL, NULL); \ g_free (val); \ } /* precache backend properties, thus editor have them ready when needed */ cache_backend_prop (CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS); cache_backend_prop (CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS); cache_backend_prop (CAL_BACKEND_PROPERTY_DEFAULT_OBJECT); e_client_get_capabilities (E_CLIENT (client)); #undef cache_backend_prop /* set start day of the event as today, without time - easier than looking for a calendar's time zone */ tt = icaltime_today (); dt.value = &tt; dt.tzid = NULL; tt2 = tt; icaltime_adjust (&tt2, 1, 0, 0, 0); dt2.value = &tt2; dt2.tzid = NULL; for (i = 0; i < (uids ? uids->len : 0); i++) { CamelMimeMessage *message; ECalComponent *comp; ECalComponentText text; icalproperty *icalprop; icalcomponent *icalcomp; struct _manage_comp *mc; /* retrieve the message from the CamelFolder */ /* FIXME Not passing a GCancellable or GError. */ message = camel_folder_get_message_sync ( folder, g_ptr_array_index (uids, i), NULL, NULL); if (!message) { continue; } comp = e_cal_component_new (); switch (data->source_type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL); break; default: g_warn_if_reached (); break; } e_cal_component_set_uid (comp, camel_mime_message_get_message_id (message)); e_cal_component_set_dtstart (comp, &dt); if (data->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) { /* make it an all-day event */ e_cal_component_set_dtend (comp, &dt2); } /* set the summary */ text.value = camel_mime_message_get_subject (message); text.altrep = NULL; e_cal_component_set_summary (comp, &text); /* set all fields */ if (data->selected_text) { GSList sl; text.value = data->selected_text; text.altrep = NULL; sl.next = NULL; sl.data = &text; e_cal_component_set_description_list (comp, &sl); } else set_description (comp, message); if (data->with_attendees) { gchar *organizer; /* set actual user as organizer, to be able to change event's properties */ organizer = set_organizer (comp, data->folder); set_attendees (comp, message, organizer); g_free (organizer); } /* set attachment files */ set_attachments (E_CAL_CLIENT (client), comp, message); /* priority */ set_priority (comp, CAMEL_MIME_PART (message)); /* no need to increment a sequence number, this is a new component */ e_cal_component_abort_sequence (comp); icalcomp = e_cal_component_get_icalcomponent (comp); icalprop = icalproperty_new_x ("1"); icalproperty_set_x_name (icalprop, "X-EVOLUTION-MOVE-CALENDAR"); icalcomponent_add_property (icalcomp, icalprop); mc = g_new0 (struct _manage_comp, 1); mc->client = g_object_ref (client); mc->comp = g_object_ref (comp); g_mutex_init (&mc->mutex); g_cond_init (&mc->cond); mc->mails_count = uids->len; mc->mails_done = i + 1; /* Current task */ mc->editor_title = NULL; mc->can_continue = TRUE; if (oldmc) { /* Wait for user to quit the editor created in previous iteration * before displaying next one */ gboolean can_continue; g_mutex_lock (&oldmc->mutex); g_cond_wait (&oldmc->cond, &oldmc->mutex); g_mutex_unlock (&oldmc->mutex); can_continue = oldmc->can_continue; free_manage_comp_struct (oldmc); oldmc = NULL; if (!can_continue) break; } e_cal_client_get_object_sync ( E_CAL_CLIENT (client), icalcomponent_get_uid (icalcomp), NULL, &mc->stored_comp, NULL, NULL); /* Prioritize ahead of GTK+ redraws. */ g_idle_add_full ( G_PRIORITY_HIGH_IDLE, (GSourceFunc) do_manage_comp_idle, mc, NULL); oldmc = mc; g_object_unref (comp); g_object_unref (message); } /* Wait for the last editor and then clean up */ if (oldmc) { g_mutex_lock (&oldmc->mutex); g_cond_wait (&oldmc->cond, &oldmc->mutex); g_mutex_unlock (&oldmc->mutex); free_manage_comp_struct (oldmc); } } /* free memory */ if (client != NULL) g_object_unref (client); g_ptr_array_unref (uids); g_object_unref (folder); g_object_unref (data->client_cache); g_object_unref (data->source); g_free (data->selected_text); g_free (data); data = NULL; if (error != NULL) g_error_free (error); return TRUE; }