2 * e-source-mail-signature.c
4 * This library is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library. If not, see <http://www.gnu.org/licenses/>.
19 * SECTION: e-source-mail-signature
20 * @include: libedataserver/libedataserver.h
21 * @short_description: #ESource extension for email signatures
23 * The #ESourceMailSignature extension refers to a personalized email
26 * Access the extension as follows:
29 * #include <libedataserver/libedataserver.h>
31 * ESourceMailSignature *extension;
33 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SIGNATURE);
37 #include "evolution-data-server-config.h"
40 #include <glib/gi18n-lib.h>
42 #include <libedataserver/e-data-server-util.h>
44 #include "e-source-mail-signature.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
{
57 struct _AsyncContext
{
59 gchar
*symlink_target
;
71 e_source_mail_signature
,
72 E_TYPE_SOURCE_EXTENSION
)
75 async_context_free (AsyncContext
*async_context
)
77 g_free (async_context
->contents
);
78 g_free (async_context
->symlink_target
);
80 g_slice_free (AsyncContext
, async_context
);
84 source_mail_signature_set_property (GObject
*object
,
89 switch (property_id
) {
91 e_source_mail_signature_set_mime_type (
92 E_SOURCE_MAIL_SIGNATURE (object
),
93 g_value_get_string (value
));
97 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
101 source_mail_signature_get_property (GObject
*object
,
106 switch (property_id
) {
110 e_source_mail_signature_get_file (
111 E_SOURCE_MAIL_SIGNATURE (object
)));
115 g_value_take_string (
117 e_source_mail_signature_dup_mime_type (
118 E_SOURCE_MAIL_SIGNATURE (object
)));
122 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
126 source_mail_signature_dispose (GObject
*object
)
128 ESourceMailSignaturePrivate
*priv
;
130 priv
= E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object
);
132 if (priv
->file
!= NULL
) {
133 g_object_unref (priv
->file
);
137 /* Chain up to parent's dispose() method. */
138 G_OBJECT_CLASS (e_source_mail_signature_parent_class
)->
143 source_mail_signature_finalize (GObject
*object
)
145 ESourceMailSignaturePrivate
*priv
;
147 priv
= E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object
);
149 g_free (priv
->mime_type
);
151 /* Chain up to parent's finalize() method. */
152 G_OBJECT_CLASS (e_source_mail_signature_parent_class
)->
157 source_mail_signature_constructed (GObject
*object
)
159 ESourceMailSignaturePrivate
*priv
;
160 ESourceExtension
*extension
;
162 const gchar
*config_dir
;
167 priv
= E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (object
);
169 /* Chain up to parent's constructed() method. */
170 G_OBJECT_CLASS (e_source_mail_signature_parent_class
)->constructed (object
);
172 extension
= E_SOURCE_EXTENSION (object
);
173 source
= e_source_extension_ref_source (extension
);
174 uid
= e_source_get_uid (source
);
176 config_dir
= e_get_user_config_dir ();
177 base_dir
= g_build_filename (config_dir
, "signatures", NULL
);
178 path
= g_build_filename (base_dir
, uid
, NULL
);
179 priv
->file
= g_file_new_for_path (path
);
180 g_mkdir_with_parents (base_dir
, 0700);
184 g_object_unref (source
);
188 e_source_mail_signature_class_init (ESourceMailSignatureClass
*class)
190 GObjectClass
*object_class
;
191 ESourceExtensionClass
*extension_class
;
193 g_type_class_add_private (
194 class, sizeof (ESourceMailSignaturePrivate
));
196 object_class
= G_OBJECT_CLASS (class);
197 object_class
->set_property
= source_mail_signature_set_property
;
198 object_class
->get_property
= source_mail_signature_get_property
;
199 object_class
->dispose
= source_mail_signature_dispose
;
200 object_class
->finalize
= source_mail_signature_finalize
;
201 object_class
->constructed
= source_mail_signature_constructed
;
203 extension_class
= E_SOURCE_EXTENSION_CLASS (class);
204 extension_class
->name
= E_SOURCE_EXTENSION_MAIL_SIGNATURE
;
206 g_object_class_install_property (
209 g_param_spec_object (
212 "File containing signature content",
215 G_PARAM_STATIC_STRINGS
));
217 g_object_class_install_property (
220 g_param_spec_string (
223 "MIME type of the signature content",
227 G_PARAM_STATIC_STRINGS
|
228 E_SOURCE_PARAM_SETTING
));
232 e_source_mail_signature_init (ESourceMailSignature
*extension
)
234 extension
->priv
= E_SOURCE_MAIL_SIGNATURE_GET_PRIVATE (extension
);
238 * e_source_mail_signature_get_file:
239 * @extension: an #ESourceMailSignature
241 * Returns a #GFile instance pointing to the signature file for @extension.
242 * The signature file may be a regular file containing the static signature
243 * content, or it may be a symbolic link to an executable file that produces
244 * the signature content.
246 * e_source_mail_signature_load() uses this to load the signature content.
248 * Returns: (transfer none): a #GFile
253 e_source_mail_signature_get_file (ESourceMailSignature
*extension
)
255 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension
), NULL
);
257 return extension
->priv
->file
;
261 * e_source_mail_signature_get_mime_type:
262 * @extension: an #ESourceMailSignature
264 * Returns the MIME type of the signature content for @extension, or %NULL
265 * if it has not yet been determined.
267 * e_source_mail_signature_load() sets this automatically if the MIME type
268 * has not yet been determined.
270 * Returns: (nullable): the MIME type of the signature content, or %NULL
275 e_source_mail_signature_get_mime_type (ESourceMailSignature
*extension
)
277 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension
), NULL
);
279 return extension
->priv
->mime_type
;
283 * e_source_mail_signature_dup_mime_type:
284 * @extension: an #ESourceMailSignature
286 * Thread-safe variation of e_source_mail_signature_get_mime_type().
287 * Use this function when accessing @extension from multiple threads.
289 * The returned string should be freed with g_free() when no longer needed.
291 * Returns: (nullable): a newly-allocated copy of #ESourceMailSignature:mime-type,
297 e_source_mail_signature_dup_mime_type (ESourceMailSignature
*extension
)
299 const gchar
*protected;
302 g_return_val_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension
), NULL
);
304 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension
));
306 protected = e_source_mail_signature_get_mime_type (extension
);
307 duplicate
= g_strdup (protected);
309 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension
));
315 * e_source_mail_signature_set_mime_type:
316 * @extension: an #ESourceMailSignature
317 * @mime_type: (allow-none): a MIME type, or %NULL
319 * Sets the MIME type of the signature content for @extension.
321 * e_source_mail_signature_load() sets this automatically if the MIME type
322 * has not yet been determined.
324 * The internal copy of @mime_type is automatically stripped of leading
325 * and trailing whitespace. If the resulting string is empty, %NULL is
331 e_source_mail_signature_set_mime_type (ESourceMailSignature
*extension
,
332 const gchar
*mime_type
)
334 g_return_if_fail (E_IS_SOURCE_MAIL_SIGNATURE (extension
));
336 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension
));
338 if (g_strcmp0 (extension
->priv
->mime_type
, mime_type
) == 0) {
339 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension
));
343 g_free (extension
->priv
->mime_type
);
344 extension
->priv
->mime_type
= e_util_strdup_strip (mime_type
);
346 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension
));
348 g_object_notify (G_OBJECT (extension
), "mime-type");
351 /********************** e_source_mail_signature_load() ***********************/
353 /* Helper for e_source_mail_signature_load() */
355 source_mail_signature_load_thread (GSimpleAsyncResult
*simple
,
357 GCancellable
*cancellable
)
359 AsyncContext
*async_context
;
360 GError
*error
= NULL
;
362 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
364 e_source_mail_signature_load_sync (
366 &async_context
->contents
,
367 &async_context
->length
,
368 cancellable
, &error
);
371 g_simple_async_result_take_error (simple
, error
);
375 * e_source_mail_signature_load_sync:
376 * @source: an #ESource
377 * @contents: (out): return location for the signature content
378 * @length: (allow-none) (out): return location for the length of the signature
379 * content, or %NULL if the length is not needed
380 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
381 * @error: return location for a #GError, or %NULL
383 * Loads a signature from the signature file for @source, which is
384 * given by e_source_mail_signature_get_file(). The signature contents
385 * are placed in @contents, and @length is set to the size of the @contents
386 * string. The @contents string should be freed with g_free() when no
389 * If the signature file is executable, it will be executed and its output
390 * captured as the email signature content. If the signature file is not
391 * executable, the email signature content is read directly from the file.
393 * Returns: %TRUE on success, %FALSE on failure
398 e_source_mail_signature_load_sync (ESource
*source
,
401 GCancellable
*cancellable
,
404 ESourceMailSignature
*extension
;
405 GFileInfo
*file_info
;
407 const gchar
*content_type
;
408 const gchar
*extension_name
;
409 gchar
*local_contents
= NULL
;
410 gboolean can_execute
;
412 gchar
*guessed_content_type
;
417 g_return_val_if_fail (E_IS_SOURCE (source
), FALSE
);
418 g_return_val_if_fail (contents
!= NULL
, FALSE
);
420 extension_name
= E_SOURCE_EXTENSION_MAIL_SIGNATURE
;
421 extension
= e_source_get_extension (source
, extension_name
);
422 file
= e_source_mail_signature_get_file (extension
);
424 file_info
= g_file_query_info (
426 G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE
","
427 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
,
428 G_FILE_QUERY_INFO_NONE
,
431 if (file_info
== NULL
)
434 can_execute
= g_file_info_get_attribute_boolean (
435 file_info
, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE
);
437 content_type
= g_file_info_get_content_type (file_info
);
438 mime_type
= g_content_type_get_mime_type (content_type
);
443 /*** Load signature file contents ***/
445 success
= g_file_load_contents (
446 file
, cancellable
, &local_contents
, NULL
, NULL
, error
);
451 g_return_val_if_fail (local_contents
!= NULL
, FALSE
);
453 /* Signatures are saved as UTF-8, but we still need to check that
454 * the signature is valid UTF-8 because the user may be opening a
455 * signature file this is in his/her locale character set. If it
456 * is not UTF-8 then try converting from the current locale. */
457 if (!g_utf8_validate (local_contents
, -1, NULL
)) {
460 utf8
= g_locale_to_utf8 (
461 local_contents
, -1, NULL
, NULL
, error
);
468 g_free (local_contents
);
469 local_contents
= utf8
;
476 /*** Execute signature file and capture output ***/
478 path
= g_file_get_path (file
);
482 error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
,
483 _("Signature script must be a local file"));
488 /* Enclose the path in single-quotes for compatibility on Windows.
489 * (See g_spawn_command_line_sync() documentation for rationale.) */
490 command_line
= g_strdup_printf ("'%s'", path
);
492 success
= g_spawn_command_line_sync (
493 command_line
, &local_contents
, NULL
, NULL
, error
);
495 g_free (command_line
);
498 /* Check if we failed to spawn the script. */
502 /* Check if we were cancelled while the script was running. */
503 if (g_cancellable_set_error_if_cancelled (cancellable
, error
)) {
508 g_return_val_if_fail (local_contents
!= NULL
, FALSE
);
510 /* Signature scripts are supposed to generate UTF-8 content, but
511 * because users are known to never read the manual, we try to do
512 * our best if the content isn't valid UTF-8 by assuming that the
513 * content is in the user's locale character set. */
514 if (!g_utf8_validate (local_contents
, -1, NULL
)) {
517 utf8
= g_locale_to_utf8 (
518 local_contents
, -1, NULL
, NULL
, error
);
525 g_free (local_contents
);
526 local_contents
= utf8
;
531 /* Try and guess the content type of the script output
532 * so it can be applied correctly to the mail message. */
533 guessed_content_type
= g_content_type_guess (
534 NULL
, (guchar
*) local_contents
,
535 strlen (local_contents
), NULL
);
536 mime_type
= g_content_type_get_mime_type (guessed_content_type
);
537 g_free (guessed_content_type
);
541 const gchar
*ext_mime_type
;
544 *length
= strlen (local_contents
);
546 *contents
= local_contents
;
547 local_contents
= NULL
;
550 e_source_mail_signature_get_mime_type (extension
);
552 /* Don't override the MIME type if it's already set. */
553 if (ext_mime_type
== NULL
|| *ext_mime_type
== '\0')
554 e_source_mail_signature_set_mime_type (
555 extension
, mime_type
);
558 g_object_unref (file_info
);
559 g_free (local_contents
);
566 * e_source_mail_signature_load:
567 * @source: an #ESource
568 * @io_priority: the I/O priority of the request
569 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
570 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
572 * @user_data: (closure): data to pass to the callback function
574 * Asynchronously loads a signature from the signature file for @source,
575 * which is given by e_source_mail_signature_get_file().
577 * If the signature file is executable, it will be executed and its output
578 * captured as the email signature content. If the signature file is not
579 * executable, the email signature content is read directly from the file.
581 * When the operation is finished, @callback will be called. You can
582 * then call e_source_mail_signature_load_finish() to get the result of
588 e_source_mail_signature_load (ESource
*source
,
590 GCancellable
*cancellable
,
591 GAsyncReadyCallback callback
,
594 GSimpleAsyncResult
*simple
;
595 AsyncContext
*async_context
;
597 g_return_if_fail (E_IS_SOURCE (source
));
599 async_context
= g_slice_new0 (AsyncContext
);
601 simple
= g_simple_async_result_new (
602 G_OBJECT (source
), callback
, user_data
,
603 e_source_mail_signature_load
);
605 g_simple_async_result_set_check_cancellable (simple
, cancellable
);
607 g_simple_async_result_set_op_res_gpointer (
608 simple
, async_context
, (GDestroyNotify
) async_context_free
);
610 g_simple_async_result_run_in_thread (
611 simple
, source_mail_signature_load_thread
,
612 io_priority
, cancellable
);
614 g_object_unref (simple
);
618 * e_source_mail_signature_load_finish:
619 * @source: an #ESource
620 * @result: a #GAsyncResult
621 * @contents: (out): return location for the signature content
622 * @length: (allow-none) (out): return location for the length of the signature
623 * content, or %NULL if the length is not needed
624 * @error: return location for a #GError, or %NULL
626 * Finishes an operation started with e_source_mail_signature_load(). The
627 * signature file contents are placed in @contents, and @length is set to
628 * the size of the @contents string. The @contents string should be freed
629 * with g_free() when no longer needed.
631 * Returns: %TRUE on success, %FALSE on failure
636 e_source_mail_signature_load_finish (ESource
*source
,
637 GAsyncResult
*result
,
642 GSimpleAsyncResult
*simple
;
643 AsyncContext
*async_context
;
645 g_return_val_if_fail (
646 g_simple_async_result_is_valid (
647 result
, G_OBJECT (source
),
648 e_source_mail_signature_load
), FALSE
);
650 g_return_val_if_fail (contents
!= NULL
, FALSE
);
652 simple
= G_SIMPLE_ASYNC_RESULT (result
);
653 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
655 if (g_simple_async_result_propagate_error (simple
, error
))
658 g_return_val_if_fail (async_context
->contents
!= NULL
, FALSE
);
660 *contents
= async_context
->contents
;
661 async_context
->contents
= NULL
;
664 *length
= async_context
->length
;
669 /********************* e_source_mail_signature_replace() *********************/
671 /* Helper for e_source_mail_signature_replace() */
673 source_mail_signature_replace_thread (GSimpleAsyncResult
*simple
,
675 GCancellable
*cancellable
)
677 AsyncContext
*async_context
;
678 GError
*error
= NULL
;
680 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
682 e_source_mail_signature_replace_sync (
683 E_SOURCE (object
), async_context
->contents
,
684 async_context
->length
, cancellable
, &error
);
687 g_simple_async_result_take_error (simple
, error
);
691 * e_source_mail_signature_replace_sync:
692 * @source: an #ESource
693 * @contents: the signature contents
694 * @length: the length of @contents in bytes
695 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
696 * @error: return location for a #GError, or %NULL
698 * Replaces the signature file for @source with the given @contents
699 * of @length bytes. The signature file for @source is given by
700 * e_source_mail_signature_get_file().
702 * Returns: %TRUE on success, %FALSE on failure
707 e_source_mail_signature_replace_sync (ESource
*source
,
708 const gchar
*contents
,
710 GCancellable
*cancellable
,
713 ESourceMailSignature
*extension
;
714 const gchar
*extension_name
;
717 g_return_val_if_fail (E_IS_SOURCE (source
), FALSE
);
718 g_return_val_if_fail (contents
!= NULL
, FALSE
);
720 extension_name
= E_SOURCE_EXTENSION_MAIL_SIGNATURE
;
721 extension
= e_source_get_extension (source
, extension_name
);
722 file
= e_source_mail_signature_get_file (extension
);
724 return g_file_replace_contents (
725 file
, contents
, length
, NULL
, FALSE
,
726 G_FILE_CREATE_REPLACE_DESTINATION
,
727 NULL
, cancellable
, error
);
731 * e_source_mail_signature_replace:
732 * @source: an #ESource
733 * @contents: the signature contents
734 * @length: the length of @contents in bytes
735 * @io_priority: the I/O priority of the request
736 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
737 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
739 * @user_data: (closure): data to pass to the callback function
741 * Asynchrously replaces the signature file for @source with the given
742 * @contents of @length bytes. The signature file for @source is given
743 * by e_source_mail_signature_get_file().
745 * When the operation is finished, @callback will be called. You can
746 * then call e_source_mail_signature_replace_finish() to get the result
752 e_source_mail_signature_replace (ESource
*source
,
753 const gchar
*contents
,
756 GCancellable
*cancellable
,
757 GAsyncReadyCallback callback
,
760 GSimpleAsyncResult
*simple
;
761 AsyncContext
*async_context
;
763 g_return_if_fail (E_IS_SOURCE (source
));
764 g_return_if_fail (contents
!= NULL
);
766 async_context
= g_slice_new0 (AsyncContext
);
767 async_context
->contents
= g_strdup (contents
);
768 async_context
->length
= length
;
770 simple
= g_simple_async_result_new (
771 G_OBJECT (source
), callback
, user_data
,
772 e_source_mail_signature_replace
);
774 g_simple_async_result_set_check_cancellable (simple
, cancellable
);
776 g_simple_async_result_set_op_res_gpointer (
777 simple
, async_context
, (GDestroyNotify
) async_context_free
);
779 g_simple_async_result_run_in_thread (
780 simple
, source_mail_signature_replace_thread
,
781 io_priority
, cancellable
);
783 g_object_unref (simple
);
787 * e_source_mail_signature_replace_finish:
788 * @source: an #ESource
789 * @result: a #GAsyncResult
790 * @error: return location for a #GError, or %NULL
792 * Finishes an operation started with e_source_mail_signature_replace().
794 * Returns: %TRUE on success, %FALSE on failure
799 e_source_mail_signature_replace_finish (ESource
*source
,
800 GAsyncResult
*result
,
803 GSimpleAsyncResult
*simple
;
805 g_return_val_if_fail (
806 g_simple_async_result_is_valid (
807 result
, G_OBJECT (source
),
808 e_source_mail_signature_replace
), FALSE
);
810 simple
= G_SIMPLE_ASYNC_RESULT (result
);
812 /* Assume success unless a GError is set. */
813 return !g_simple_async_result_propagate_error (simple
, error
);
816 /********************* e_source_mail_signature_symlink() *********************/
818 /* Helper for e_source_mail_signature_symlink() */
820 source_mail_signature_symlink_thread (GSimpleAsyncResult
*simple
,
822 GCancellable
*cancellable
)
824 AsyncContext
*async_context
;
825 GError
*error
= NULL
;
827 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
829 e_source_mail_signature_symlink_sync (
831 async_context
->symlink_target
,
832 cancellable
, &error
);
835 g_simple_async_result_take_error (simple
, error
);
839 * e_source_mail_signature_symlink_sync:
840 * @source: an #ESource
841 * @symlink_target: executable filename to link to
842 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
843 * @error: return location for a #GError, or %NULL
845 * Replaces the signature file for @source with a symbolic link to
846 * @symlink_target, which should be an executable file that prints
847 * a mail signature to standard output. The signature file for
848 * @source is given by e_source_mail_signature_get_file().
850 * Returns: %TRUE on success, %FALSE on failure
855 e_source_mail_signature_symlink_sync (ESource
*source
,
856 const gchar
*symlink_target
,
857 GCancellable
*cancellable
,
860 ESourceMailSignature
*extension
;
861 const gchar
*extension_name
;
864 g_return_val_if_fail (E_IS_SOURCE (source
), FALSE
);
865 g_return_val_if_fail (symlink_target
!= NULL
, FALSE
);
867 extension_name
= E_SOURCE_EXTENSION_MAIL_SIGNATURE
;
868 extension
= e_source_get_extension (source
, extension_name
);
869 file
= e_source_mail_signature_get_file (extension
);
871 /* The file may not exist, so we don't care if this fails.
872 * If it fails for a different reason than G_IO_ERROR_NOT_FOUND
873 * then the next step will probably also fail and we'll capture
875 g_file_delete (file
, cancellable
, NULL
);
877 return g_file_make_symbolic_link (
878 file
, symlink_target
, cancellable
, error
);
882 * e_source_mail_signature_symlink:
883 * @source: an #ESource
884 * @symlink_target: executable filename to link to
885 * @io_priority: the I/O priority of the request
886 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
887 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
889 * @user_data: (closure): data to pass to the callback function
891 * Asynchronously replaces the signature file for @source with a symbolic
892 * link to @symlink_target, which should be an executable file that prints
893 * a mail signature to standard output. The signature file for @source
894 * is given by e_source_mail_signature_get_file().
896 * When the operation is finished, @callback will be called. You can
897 * then call e_source_mail_signature_symlink_finish() to get the result
903 e_source_mail_signature_symlink (ESource
*source
,
904 const gchar
*symlink_target
,
906 GCancellable
*cancellable
,
907 GAsyncReadyCallback callback
,
910 GSimpleAsyncResult
*simple
;
911 AsyncContext
*async_context
;
913 g_return_if_fail (E_IS_SOURCE (source
));
914 g_return_if_fail (symlink_target
!= NULL
);
916 async_context
= g_slice_new0 (AsyncContext
);
917 async_context
->symlink_target
= g_strdup (symlink_target
);
919 simple
= g_simple_async_result_new (
920 G_OBJECT (source
), callback
, user_data
,
921 e_source_mail_signature_symlink
);
923 g_simple_async_result_set_check_cancellable (simple
, cancellable
);
925 g_simple_async_result_set_op_res_gpointer (
926 simple
, async_context
, (GDestroyNotify
) async_context_free
);
928 g_simple_async_result_run_in_thread (
929 simple
, source_mail_signature_symlink_thread
,
930 io_priority
, cancellable
);
932 g_object_unref (simple
);
936 * e_source_mail_signature_symlink_finish:
937 * @source: an #ESource
938 * @result: a #GAsyncResult
939 * @error: return location for a #GError, or %NULL
941 * Finishes an operation started with e_source_mail_signature_symlink().
943 * Returns: %TRUE on success, %FALSE on failure
948 e_source_mail_signature_symlink_finish (ESource
*source
,
949 GAsyncResult
*result
,
952 GSimpleAsyncResult
*simple
;
954 g_return_val_if_fail (
955 g_simple_async_result_is_valid (
956 result
, G_OBJECT (source
),
957 e_source_mail_signature_symlink
), FALSE
);
959 simple
= G_SIMPLE_ASYNC_RESULT (result
);
961 /* Assume success unless a GError is set. */
962 return !g_simple_async_result_propagate_error (simple
, error
);