/* Well, since Solaris is a tad broken wrt its 'mbox' folder format, * we must convert it to a real mbox format. Thankfully this is * mostly pretty easy */ static gint camel_movemail_solaris (gint oldsfd, gint dfd, GError **error) { CamelMimeParser *mp; gchar *buffer; gint len; gint sfd; CamelMimeFilter *ffrom; gint ret = 1; gchar *from = NULL; /* need to dup as the mime parser will close on finish */ sfd = dup (oldsfd); if (sfd == -1) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Error copying mail temp file: %s"), g_strerror (errno)); return -1; } mp = camel_mime_parser_new (); camel_mime_parser_scan_from (mp, TRUE); camel_mime_parser_init_with_fd (mp, sfd); ffrom = camel_mime_filter_from_new (); while (camel_mime_parser_step (mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM) { g_return_val_if_fail (camel_mime_parser_from_line (mp), -1); from = g_strdup (camel_mime_parser_from_line (mp)); if (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM_END) { CamelNameValueArray *headers; const gchar *cl; gint length; gint start, body; goffset newpos; ret = 0; start = camel_mime_parser_tell_start_from (mp); body = camel_mime_parser_tell (mp); if (write (dfd, from, strlen (from)) != strlen (from)) goto fail; /* write out headers, but NOT content-length header */ headers = camel_mime_parser_dup_headers (mp); if (solaris_header_write (dfd, headers) == -1) { camel_name_value_array_free (headers); goto fail; } camel_name_value_array_free (headers); cl = camel_mime_parser_header (mp, "content-length", NULL); if (cl == NULL) { g_warning ("Required Content-Length header is missing from solaris mail box @ %d", (gint) camel_mime_parser_tell (mp)); camel_mime_parser_drop_step (mp); camel_mime_parser_drop_step (mp); camel_mime_parser_step (mp, &buffer, &len); camel_mime_parser_unstep (mp); length = camel_mime_parser_tell_start_from (mp) - body; newpos = -1; } else { length = atoi (cl); camel_mime_parser_drop_step (mp); camel_mime_parser_drop_step (mp); newpos = length + body; } /* copy body->length converting From lines */ if (camel_movemail_copy_filter (sfd, dfd, body, length, ffrom) == -1) goto fail; if (newpos != -1) camel_mime_parser_seek (mp, newpos, SEEK_SET); } else { g_error ("Inalid parser state: %d", camel_mime_parser_state (mp)); } g_free (from); } g_object_unref (mp); g_object_unref (ffrom); return ret; fail: g_free (from); g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Error copying mail temp file: %s"), g_strerror (errno)); g_object_unref (mp); g_object_unref (ffrom); return -1; }
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 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] */ }