2 * e-source-mail-signature.c
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
20 * SECTION: e-source-mail-signature
21 * @include: libedataserver/e-source-mail-signature.h
22 * @short_description: #ESource extension for email signatures
24 * The #ESourceMailSignature extension refers to a personalized email
27 * Access the extension as follows:
30 * #include <libedataserver/e-source-mail-signature.h>
32 * ESourceMailSignature *extension;
34 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE);
38 #include "e-source-mail-signature.h"
42 #include <glib/gi18n-lib.h>
44 #include <libedataserver/e-data-server-util.h>
46 #define E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE(obj) \
47 (G_TYPE_INSTANCE_GET_PRIVATE \
48 ((obj), E_TYPE_SOURCE_MAIL_SIGNATURE, ESourceMailSignaturePrivate))
50 typedef struct _AsyncContext AsyncContext;
52 struct _ESourceMailSignaturePrivate {
53 GMutex *property_lock;
58 struct _AsyncContext {
60 gchar *symlink_target;
72 e_source_mail_signature,
73 E_TYPE_SOURCE_EXTENSION)
76 async_context_free (AsyncContext *async_context)
78 g_free (async_context->contents);
79 g_free (async_context->symlink_target);
81 g_slice_free (AsyncContext, async_context);
85 source_mail_signature_set_property (GObject *object,
90 switch (property_id) {
92 e_source_mail_signature_set_mime_type (
93 E_SOURCE_MAIL_SIGNATURE (object),
94 g_value_get_string (value));
98 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
102 source_mail_signature_get_property (GObject *object,
107 switch (property_id) {
111 e_source_mail_signature_get_file (
112 E_SOURCE_MAIL_SIGNATURE (object)));
116 g_value_take_string (
118 e_source_mail_signature_dup_mime_type (
119 E_SOURCE_MAIL_SIGNATURE (object)));
123 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
127 source_mail_signature_dispose (GObject *object)
129 ESourceMailSignaturePrivate *priv;
131 priv = E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object);
133 if (priv->file != NULL) {
134 g_object_unref (priv->file);
138 /* Chain up to parent's dispose() method. */
139 G_OBJECT_CLASS (e_source_mail_signature_parent_class)->
144 source_mail_signature_finalize (GObject *object)
146 ESourceMailSignaturePrivate *priv;
148 priv = E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object);
150 g_mutex_free (priv->property_lock);
152 g_free (priv->mime_type);
154 /* Chain up to parent's finalize() method. */
155 G_OBJECT_CLASS (e_source_mail_signature_parent_class)->
160 source_mail_signature_constructed (GObject *object)
162 ESourceMailSignaturePrivate *priv;
163 ESourceExtension *extension;
165 const gchar *config_dir;
170 priv = E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object);
172 /* Chain up to parent's constructed() method. */
173 G_OBJECT_CLASS (e_source_mail_signature_parent_class)->
174 constructed (object);
176 extension = E_SOURCE_EXTENSION (object);
177 source = e_source_extension_get_source (extension);
178 uid = e_source_get_uid (source);
180 config_dir = e_get_user_config_dir ();
181 base_dir = g_build_filename (config_dir, "signatures", NULL);
182 path = g_build_filename (base_dir, uid, NULL);
183 priv->file = g_file_new_for_path (path);
184 g_mkdir_with_parents (base_dir, 0700);
190 e_source_mail_signature_class_init (ESourceMailSignatureClass *class)
192 GObjectClass *object_class;
193 ESourceExtensionClass *extension_class;
195 g_type_class_add_private (
196 class, sizeof (ESourceMailSignaturePrivate));
198 object_class = G_OBJECT_CLASS (class);
199 object_class->set_property = source_mail_signature_set_property;
200 object_class->get_property = source_mail_signature_get_property;
201 object_class->dispose = source_mail_signature_dispose;
202 object_class->finalize = source_mail_signature_finalize;
203 object_class->constructed = source_mail_signature_constructed;
205 extension_class = E_SOURCE_EXTENSION_CLASS (class);
206 extension_class->name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
208 g_object_class_install_property (
211 g_param_spec_object (
214 "File containing signature content",
217 G_PARAM_STATIC_STRINGS));
219 g_object_class_install_property (
222 g_param_spec_string (
225 "MIME type of the signature content",
229 G_PARAM_STATIC_STRINGS |
230 E_SOURCE_PARAM_SETTING));
234 e_source_mail_signature_init (ESourceMailSignature *extension)
236 extension->priv = E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (extension);
237 extension->priv->property_lock = g_mutex_new ();
241 * e_source_mail_signature_get_file:
242 * @extension: an #ESourceMailSignature
244 * Returns a #GFile instance pointing to the signature file for @extension.
245 * The signature file may be a regular file containing the static signature
246 * content, or it may be a symbolic link to an executable file that produces
247 * the signature content.
249 * e_source_mail_signature_load() uses this to load the signature content.
256 e_source_mail_signature_get_file (ESourceMailSignature *extension)
258 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension), NULL);
260 return extension->priv->file;
264 * e_source_mail_signature_get_mime_type:
265 * @extension: an #ESourceMailSignature
267 * Returns the MIME type of the signature content for @extension, or %NULL
268 * if it has not yet been determined.
270 * e_source_mail_signature_load() sets this automatically if the MIME type
271 * has not yet been determined.
273 * Returns: the MIME type of the signature content, or %NULL
278 e_source_mail_signature_get_mime_type (ESourceMailSignature *extension)
280 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension), NULL);
282 return extension->priv->mime_type;
286 * e_source_mail_signature_dup_mime_type:
287 * @extension: an #ESourceMailSignature
289 * Thread-safe variation of e_source_mail_signature_get_mime_type().
290 * Use this function when accessing @extension from multiple threads.
292 * The returned string should be freed with g_free() when no longer needed.
294 * Returns: a newly-allocated copy of #ESourceMailSignature:mime-type
299 e_source_mail_signature_dup_mime_type (ESourceMailSignature *extension)
301 const gchar *protected;
304 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension), NULL);
306 g_mutex_lock (extension->priv->property_lock);
308 protected = e_source_mail_signature_get_mime_type (extension);
309 duplicate = g_strdup (protected);
311 g_mutex_unlock (extension->priv->property_lock);
317 * e_source_mail_signature_set_mime_type:
318 * @extension: an #ESourceMailSignature
319 * @mime_type: (allow-none): a MIME type, or %NULL
321 * Sets the MIME type of the signature content for @extension.
323 * e_source_mail_signature_load() sets this automatically if the MIME type
324 * has not yet been determined.
326 * The internal copy of @mime_type is automatically stripped of leading
327 * and trailing whitespace. If the resulting string is empty, %NULL is
333 e_source_mail_signature_set_mime_type (ESourceMailSignature *extension,
334 const gchar *mime_type)
336 g_return_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension));
338 g_mutex_lock (extension->priv->property_lock);
340 g_free (extension->priv->mime_type);
341 extension->priv->mime_type = e_util_strdup_strip (mime_type);
343 g_mutex_unlock (extension->priv->property_lock);
345 g_object_notify (G_OBJECT (extension), "mime-type");
348 /********************** e_source_mail_signature_load() ***********************/
350 /* Helper for e_source_mail_signature_load() */
352 source_mail_signature_load_thread (GSimpleAsyncResult *simple,
354 GCancellable *cancellable)
356 AsyncContext *async_context;
357 GError *error = NULL;
359 async_context = g_simple_async_result_get_op_res_gpointer (simple);
361 e_source_mail_signature_load_sync (
363 &async_context->contents,
364 &async_context->length,
365 cancellable, &error);
368 g_simple_async_result_take_error (simple, error);
372 * e_source_mail_signature_load_sync:
373 * @source: an #ESource
374 * @contents: return location for the signature content
375 * @length: (allow-none): return location for the length of the signature
376 * content, or %NULL if the length is not needed
377 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
378 * @error: return location for a #GError, or %NULL
380 * Loads a signature from the signature file for @source, which is
381 * given by e_source_mail_signature_get_file(). The signature contents
382 * are placed in @contents, and @length is set to the size of the @contents
383 * string. The @contents string should be freed with g_free() when no
386 * If the signature file is executable, it will be executed and its output
387 * captured as the email signature content. If the signature file is not
388 * executable, the email signature content is read directly from the file.
390 * Returns; %TRUE on success, %FALSE on failure
395 e_source_mail_signature_load_sync (ESource *source,
398 GCancellable *cancellable,
401 ESourceMailSignature *extension;
402 GFileInfo *file_info;
404 const gchar *content_type;
405 const gchar *extension_name;
406 gchar *local_contents = NULL;
407 gboolean can_execute;
409 gchar *guessed_content_type;
414 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
415 g_return_val_if_fail (contents != NULL, FALSE);
417 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
418 extension = e_source_get_extension (source, extension_name);
419 file = e_source_mail_signature_get_file (extension);
421 file_info = g_file_query_info (
423 G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE ","
424 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
425 G_FILE_QUERY_INFO_NONE,
428 if (file_info == NULL)
431 can_execute = g_file_info_get_attribute_boolean (
432 file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
434 content_type = g_file_info_get_content_type (file_info);
435 mime_type = g_content_type_get_mime_type (content_type);
440 /*** Load signature file contents ***/
442 success = g_file_load_contents (
443 file, cancellable, &local_contents, NULL, NULL, error);
448 g_return_val_if_fail (local_contents != NULL, FALSE);
450 /* Signatures are saved as UTF-8, but we still need to check that
451 * the signature is valid UTF-8 because the user may be opening a
452 * signature file this is in his/her locale character set. If it
453 * is not UTF-8 then try converting from the current locale. */
454 if (!g_utf8_validate (local_contents, -1, NULL)) {
457 utf8 = g_locale_to_utf8 (
458 local_contents, -1, NULL, NULL, error);
465 g_free (local_contents);
466 local_contents = utf8;
473 /*** Execute signature file and capture output ***/
475 path = g_file_get_path (file);
479 error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
480 _("Signature script must be a local file"));
485 /* Enclose the path in single-quotes for compatibility on Windows.
486 * (See g_spawn_command_line_sync() documentation for rationale.) */
487 command_line = g_strdup_printf ("'%s'", path);
489 success = g_spawn_command_line_sync (
490 command_line, &local_contents, NULL, NULL, error);
492 g_free (command_line);
495 /* Check if we failed to spawn the script. */
499 /* Check if we were cancelled while the script was running. */
500 if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
505 g_return_val_if_fail (local_contents != NULL, FALSE);
507 /* Signature scripts are supposed to generate UTF-8 content, but
508 * because users are known to never read the manual, we try to do
509 * our best if the content isn't valid UTF-8 by assuming that the
510 * content is in the user's locale character set. */
511 if (!g_utf8_validate (local_contents, -1, NULL)) {
514 utf8 = g_locale_to_utf8 (
515 local_contents, -1, NULL, NULL, error);
522 g_free (local_contents);
523 local_contents = utf8;
528 /* Try and guess the content type of the script output
529 * so it can be applied correctly to the mail message. */
530 guessed_content_type = g_content_type_guess (
531 NULL, (guchar *) local_contents,
532 strlen (local_contents), NULL);
533 mime_type = g_content_type_get_mime_type (guessed_content_type);
534 g_free (guessed_content_type);
538 const gchar *ext_mime_type;
541 *length = strlen (local_contents);
543 *contents = local_contents;
544 local_contents = NULL;
547 e_source_mail_signature_get_mime_type (extension);
549 /* Don't override the MIME type if it's already set. */
550 if (ext_mime_type == NULL || *ext_mime_type == '\0')
551 e_source_mail_signature_set_mime_type (
552 extension, mime_type);
555 g_object_unref (file_info);
556 g_free (local_contents);
563 * e_source_mail_signature_load:
564 * @source: an #ESource
565 * @io_priority: the I/O priority of the request
566 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
567 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
569 * @user_data: (closure): data to pass to the callback function
571 * Asynchronously loads a signature from the signature file for @source,
572 * which is given by e_source_mail_signature_get_file().
574 * If the signature file is executable, it will be executed and its output
575 * captured as the email signature content. If the signature file is not
576 * executable, the email signature content is read directly from the file.
578 * When the operation is finished, @callback will be called. You can
579 * then call e_source_mail_signature_load_finish() to get the result of
585 e_source_mail_signature_load (ESource *source,
587 GCancellable *cancellable,
588 GAsyncReadyCallback callback,
591 GSimpleAsyncResult *simple;
592 AsyncContext *async_context;
594 g_return_if_fail (E_IS_SOURCE (source));
596 async_context = g_slice_new0 (AsyncContext);
598 simple = g_simple_async_result_new (
599 G_OBJECT (source), callback, user_data,
600 e_source_mail_signature_load);
602 g_simple_async_result_set_check_cancellable (simple, cancellable);
604 g_simple_async_result_set_op_res_gpointer (
605 simple, async_context, (GDestroyNotify) async_context_free);
607 g_simple_async_result_run_in_thread (
608 simple, source_mail_signature_load_thread,
609 io_priority, cancellable);
611 g_object_unref (simple);
615 * e_source_mail_signature_load_finish:
616 * @source: an #ESource
617 * @result: a #GAsyncResult
618 * @contents: return location for the signature content
619 * @length: (allow-none): return location for the length of the signature
620 * content, or %NULL if the length is not needed
621 * @error: return location for a #GError, or %NULL
623 * Finishes an operation started with e_source_mail_signature_load(). The
624 * signature file contents are placed in @contents, and @length is set to
625 * the size of the @contents string. The @contents string should be freed
626 * with g_free() when no longer needed.
628 * Returns: %TRUE on success, %FALSE on failure
633 e_source_mail_signature_load_finish (ESource *source,
634 GAsyncResult *result,
639 GSimpleAsyncResult *simple;
640 AsyncContext *async_context;
642 g_return_val_if_fail (
643 g_simple_async_result_is_valid (
644 result, G_OBJECT (source),
645 e_source_mail_signature_load), FALSE);
647 g_return_val_if_fail (contents != NULL, FALSE);
649 simple = G_SIMPLE_ASYNC_RESULT (result);
650 async_context = g_simple_async_result_get_op_res_gpointer (simple);
652 if (g_simple_async_result_propagate_error (simple, error))
655 g_return_val_if_fail (async_context->contents != NULL, FALSE);
657 *contents = async_context->contents;
658 async_context->contents = NULL;
661 *length = async_context->length;
666 /********************* e_source_mail_signature_replace() *********************/
668 /* Helper for e_source_mail_signature_replace() */
670 source_mail_signature_replace_thread (GSimpleAsyncResult *simple,
672 GCancellable *cancellable)
674 AsyncContext *async_context;
675 GError *error = NULL;
677 async_context = g_simple_async_result_get_op_res_gpointer (simple);
679 e_source_mail_signature_replace_sync (
680 E_SOURCE (object), async_context->contents,
681 async_context->length, cancellable, &error);
684 g_simple_async_result_take_error (simple, error);
688 * e_source_mail_signature_replace_sync:
689 * @source: an #ESource
690 * @contents: the signature contents
691 * @length: the length of @contents in bytes
692 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
693 * @error: return location for a #GError, or %NULL
695 * Replaces the signature file for @source with the given @contents
696 * of @length bytes. The signature file for @source is given by
697 * e_source_mail_signature_get_file().
699 * Returns: %TRUE on success, %FALSE on failure
704 e_source_mail_signature_replace_sync (ESource *source,
705 const gchar *contents,
707 GCancellable *cancellable,
710 ESourceMailSignature *extension;
711 const gchar *extension_name;
714 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
715 g_return_val_if_fail (contents != NULL, FALSE);
717 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
718 extension = e_source_get_extension (source, extension_name);
719 file = e_source_mail_signature_get_file (extension);
721 return g_file_replace_contents (
722 file, contents, length, NULL, FALSE,
723 G_FILE_CREATE_REPLACE_DESTINATION,
724 NULL, cancellable, error);
728 * e_source_mail_signature_replace:
729 * @source: an #ESource
730 * @contents: the signature contents
731 * @length: the length of @contents in bytes
732 * @io_priority: the I/O priority of the request
733 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
734 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
736 * @user_data: (closure): data to pass to the callback function
738 * Asynchrously replaces the signature file for @source with the given
739 * @contents of @length bytes. The signature file for @source is given
740 * by e_source_mail_signature_get_file().
742 * When the operation is finished, @callback will be called. You can
743 * then call e_source_mail_signature_replace_finish() to get the result
749 e_source_mail_signature_replace (ESource *source,
750 const gchar *contents,
753 GCancellable *cancellable,
754 GAsyncReadyCallback callback,
757 GSimpleAsyncResult *simple;
758 AsyncContext *async_context;
760 g_return_if_fail (E_IS_SOURCE (source));
761 g_return_if_fail (contents != NULL);
763 async_context = g_slice_new0 (AsyncContext);
764 async_context->contents = g_strdup (contents);
765 async_context->length = length;
767 simple = g_simple_async_result_new (
768 G_OBJECT (source), callback, user_data,
769 e_source_mail_signature_replace);
771 g_simple_async_result_set_check_cancellable (simple, cancellable);
773 g_simple_async_result_set_op_res_gpointer (
774 simple, async_context, (GDestroyNotify) async_context_free);
776 g_simple_async_result_run_in_thread (
777 simple, source_mail_signature_replace_thread,
778 io_priority, cancellable);
780 g_object_unref (simple);
784 * e_source_mail_signature_replace_finish:
785 * @source: an #ESource
786 * @result: a #GAsyncResult
787 * @error: return location for a #GError, or %NULL
789 * Finishes an operation started with e_source_mail_signature_replace().
791 * Returns: %TRUE on success, %FALSE on failure
796 e_source_mail_signature_replace_finish (ESource *source,
797 GAsyncResult *result,
800 GSimpleAsyncResult *simple;
802 g_return_val_if_fail (
803 g_simple_async_result_is_valid (
804 result, G_OBJECT (source),
805 e_source_mail_signature_replace), FALSE);
807 simple = G_SIMPLE_ASYNC_RESULT (result);
809 /* Assume success unless a GError is set. */
810 return !g_simple_async_result_propagate_error (simple, error);
813 /********************* e_source_mail_signature_symlink() *********************/
815 /* Helper for e_source_mail_signature_symlink() */
817 source_mail_signature_symlink_thread (GSimpleAsyncResult *simple,
819 GCancellable *cancellable)
821 AsyncContext *async_context;
822 GError *error = NULL;
824 async_context = g_simple_async_result_get_op_res_gpointer (simple);
826 e_source_mail_signature_symlink_sync (
828 async_context->symlink_target,
829 cancellable, &error);
832 g_simple_async_result_take_error (simple, error);
836 * e_source_mail_signature_symlink_sync:
837 * @source: an #ESource
838 * @symlink_target: executable filename to link to
839 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
840 * @error: return location for a #GError, or %NULL
842 * Replaces the signature file for @source with a symbolic link to
843 * @symlink_target, which should be an executable file that prints
844 * a mail signature to standard output. The signature file for
845 * @source is given by e_source_mail_signature_get_file().
847 * Returns: %TRUE on success, %FALSE on failure
852 e_source_mail_signature_symlink_sync (ESource *source,
853 const gchar *symlink_target,
854 GCancellable *cancellable,
857 ESourceMailSignature *extension;
858 const gchar *extension_name;
861 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
862 g_return_val_if_fail (symlink_target != NULL, FALSE);
864 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
865 extension = e_source_get_extension (source, extension_name);
866 file = e_source_mail_signature_get_file (extension);
868 /* The file may not exist, so we don't care if this fails.
869 * If it fails for a different reason than G_IO_ERROR_NOT_FOUND
870 * then the next step will probably also fail and we'll capture
872 g_file_delete (file, cancellable, NULL);
874 return g_file_make_symbolic_link (
875 file, symlink_target, cancellable, error);
879 * e_source_mail_signature_symlink:
880 * @source: an #ESource
881 * @symlink_target: executable filename to link to
882 * @io_priority: the I/O priority of the request
883 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
884 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
886 * @user_data: (closure): data to pass to the callback function
888 * Asynchronously replaces the signature file for @source with a symbolic
889 * link to @symlink_target, which should be an executable file that prints
890 * a mail signature to standard output. The signature file for @source
891 * is given by e_source_mail_signature_get_file().
893 * When the operation is finished, @callback will be called. You can
894 * then call e_source_mail_signature_symlink_finish() to get the result
900 e_source_mail_signature_symlink (ESource *source,
901 const gchar *symlink_target,
903 GCancellable *cancellable,
904 GAsyncReadyCallback callback,
907 GSimpleAsyncResult *simple;
908 AsyncContext *async_context;
910 g_return_if_fail (E_IS_SOURCE (source));
911 g_return_if_fail (symlink_target != NULL);
913 async_context = g_slice_new0 (AsyncContext);
914 async_context->symlink_target = g_strdup (symlink_target);
916 simple = g_simple_async_result_new (
917 G_OBJECT (source), callback, user_data,
918 e_source_mail_signature_symlink);
920 g_simple_async_result_set_check_cancellable (simple, cancellable);
922 g_simple_async_result_set_op_res_gpointer (
923 simple, async_context, (GDestroyNotify) async_context_free);
925 g_simple_async_result_run_in_thread (
926 simple, source_mail_signature_symlink_thread,
927 io_priority, cancellable);
929 g_object_unref (simple);
933 * e_source_mail_signature_symlink_finish:
934 * @source: an #ESource
935 * @result: a #GAsyncResult
936 * @error: return location for a #GError, or %NULL
938 * Finishes an operation started with e_source_mail_signature_symlink().
940 * Returns: %TRUE on success, %FALSE on failure
945 e_source_mail_signature_symlink_finish (ESource *source,
946 GAsyncResult *result,
949 GSimpleAsyncResult *simple;
951 g_return_val_if_fail (
952 g_simple_async_result_is_valid (
953 result, G_OBJECT (source),
954 e_source_mail_signature_symlink), FALSE);
956 simple = G_SIMPLE_ASYNC_RESULT (result);
958 /* Assume success unless a GError is set. */
959 return !g_simple_async_result_propagate_error (simple, error);