/* 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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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] */
}