static void mc_quit_delete (CamelStore *store, struct _store_info *si, MailComponent *mc) { CamelFolder *folder = camel_store_get_junk (store, NULL); if (folder) { GPtrArray *uids; int i; uids = camel_folder_get_uids (folder); camel_folder_freeze(folder); for (i=0;i<uids->len;i++) camel_folder_set_message_flags(folder, uids->pdata[i], CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN); camel_folder_thaw(folder); camel_folder_free_uids (folder, uids); } }
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 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_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, GPtrArray **transferred_uids, GCancellable *cancellable, GError **error) { gboolean fallback = FALSE; if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest)) { gint i; CamelLocalFolder *lf = (CamelLocalFolder *) source; CamelLocalFolder *df = (CamelLocalFolder *) dest; camel_operation_push_message ( cancellable, _("Moving messages")); camel_folder_freeze (dest); camel_folder_freeze (source); for (i = 0; i < uids->len; i++) { gchar *uid = (gchar *) uids->pdata[i]; gchar *s_filename, *d_filename, *tmp; CamelMaildirMessageInfo *mdi; CamelMessageInfo *info; if ((info = camel_folder_summary_uid (source->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); return FALSE; } mdi = (CamelMaildirMessageInfo *) info; tmp = camel_maildir_summary_info_to_name (mdi); d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, tmp); g_free (tmp); s_filename = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (s_filename, d_filename) != 0) { if (errno == EXDEV) { i = uids->len + 1; fallback = TRUE; } else { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Cannot transfer message to destination folder: %s"), g_strerror (errno)); camel_message_info_free (info); break; } } else { camel_folder_set_message_flags ( source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); camel_folder_summary_remove (source->summary, info); } camel_message_info_free (info); g_free (s_filename); g_free (d_filename); } camel_folder_thaw (source); camel_folder_thaw (dest); camel_operation_pop_message (cancellable); } else fallback = TRUE; if (fallback) { CamelFolderClass *folder_class; /* Chain up to parent's transfer_messages_to() method. */ folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class); return folder_class->transfer_messages_to_sync ( source, uids, dest, delete_originals, transferred_uids, cancellable, error); } return TRUE; }
static gboolean maildir_folder_transfer_messages_to_sync (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, GPtrArray **transferred_uids, GCancellable *cancellable, GError **error) { gboolean fallback = FALSE; if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest) && camel_folder_get_parent_store (source) == camel_folder_get_parent_store (dest)) { gint i; CamelLocalFolder *lf = (CamelLocalFolder *) source; CamelLocalFolder *df = (CamelLocalFolder *) dest; camel_operation_push_message ( cancellable, _("Moving messages")); camel_folder_freeze (dest); camel_folder_freeze (source); for (i = 0; i < uids->len; i++) { gchar *uid = (gchar *) uids->pdata[i]; gchar *s_filename, *d_filename, *new_filename; CamelMaildirMessageInfo *mdi; CamelMessageInfo *info; if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) { set_cannot_get_message_ex ( error, CAMEL_FOLDER_ERROR_INVALID_UID, uid, lf->folder_path, _("No such message")); return FALSE; } mdi = (CamelMaildirMessageInfo *) info; new_filename = camel_maildir_summary_info_to_name (mdi); d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename); s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi)); if (g_rename (s_filename, d_filename) != 0) { if (errno == EXDEV) { i = uids->len + 1; fallback = TRUE; } else { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Cannot transfer message to destination folder: %s"), g_strerror (errno)); camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); break; } } else { CamelMessageInfo *clone; CamelMaildirMessageInfo *mclone; clone = camel_message_info_clone (info); clone->summary = dest->summary; mclone = (CamelMaildirMessageInfo *) clone; /* preserve also UID, as it matches the file name */ mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid (info)); camel_maildir_info_set_filename (clone, g_strdup (new_filename)); /* unset deleted flag when transferring from trash folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0); /* unset junk flag when transferring from junk folder */ if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0) camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0); camel_folder_summary_add (dest->summary, clone); camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid (clone)); camel_folder_set_message_flags ( source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0); camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info)); camel_folder_summary_remove (source->summary, info); } camel_message_info_unref (info); g_free (s_filename); g_free (d_filename); g_free (new_filename); } if (lf && camel_folder_change_info_changed (lf->changes)) { camel_folder_changed (source, lf->changes); camel_folder_change_info_clear (lf->changes); } if (df && camel_folder_change_info_changed (df->changes)) { camel_folder_changed (dest, df->changes); camel_folder_change_info_clear (df->changes); } camel_folder_thaw (source); camel_folder_thaw (dest); camel_operation_pop_message (cancellable); } else fallback = TRUE; if (fallback) { CamelFolderClass *folder_class; /* Chain up to parent's transfer_messages_to() method. */ folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class); return folder_class->transfer_messages_to_sync ( source, uids, dest, delete_originals, transferred_uids, cancellable, error); } return TRUE; }
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); }
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); }
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] */ }