Merged pidgin/main into default
[pidgin-git.git] / libpurple / purple-gio.c
blob1001ed35a4cbe4e7a78be51760da8994c45d3628
1 /*
3 * purple
5 * Purple is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #include "internal.h"
25 #include "proxy.h"
26 #include "purple-gio.h"
27 #include "tls-certificate.h"
29 typedef struct {
30 GIOStream *stream;
31 GInputStream *input;
32 GOutputStream *output;
33 } GracefulCloseData;
35 static gboolean
36 graceful_close_cb(gpointer user_data)
38 GracefulCloseData *data = user_data;
39 GError *error = NULL;
41 if (g_input_stream_has_pending(data->input) ||
42 g_output_stream_has_pending(data->output)) {
43 /* Has pending operations. Not ready to close yet.
44 * Try again later.
46 return G_SOURCE_CONTINUE;
49 /* Finally can gracefully close */
51 /* Close input stream, from wrapper or GIOStream */
52 if (!g_input_stream_close(data->input, NULL, &error)) {
53 purple_debug_warning("gio",
54 "Error closing input stream: %s",
55 error->message);
56 g_clear_error(&error);
59 g_clear_object(&data->input);
61 /* Close output stream, from wrapper or GIOStream */
62 if (!g_output_stream_close(data->output, NULL, &error)) {
63 purple_debug_warning("gio",
64 "Error closing output stream: %s",
65 error->message);
66 g_clear_error(&error);
69 g_clear_object(&data->output);
71 /* Close io stream */
72 if (!g_io_stream_close(data->stream, NULL, &error)) {
73 purple_debug_warning("gio",
74 "Error closing stream: %s",
75 error->message);
76 g_clear_error(&error);
79 g_clear_object(&data->stream);
81 /* Clean up */
82 g_free(data);
83 return G_SOURCE_REMOVE;
86 void
87 purple_gio_graceful_close(GIOStream *stream,
88 GInputStream *input, GOutputStream *output)
90 GracefulCloseData *data;
92 g_return_if_fail(G_IS_IO_STREAM(stream));
93 g_return_if_fail(input == NULL || G_IS_INPUT_STREAM(input));
94 g_return_if_fail(output == NULL || G_IS_OUTPUT_STREAM(output));
96 data = g_new(GracefulCloseData, 1);
97 data->stream = g_object_ref(stream);
99 if (input == NULL)
100 input = g_io_stream_get_input_stream(stream);
101 data->input = g_object_ref(input);
103 if (output == NULL)
104 output = g_io_stream_get_output_stream(stream);
105 data->output = g_object_ref(output);
107 /* Try gracefully closing the stream synchronously */
108 if (graceful_close_cb(data) == G_SOURCE_CONTINUE) {
109 /* Has pending operations. Do so asynchronously */
110 g_idle_add(graceful_close_cb, data);
114 GSocketClient *
115 purple_gio_socket_client_new(PurpleAccount *account, GError **error)
117 GProxyResolver *resolver;
118 GSocketClient *client;
120 resolver = purple_proxy_get_proxy_resolver(account, error);
122 if (resolver == NULL) {
123 return NULL;
126 client = g_socket_client_new();
127 g_socket_client_set_proxy_resolver(client, resolver);
128 g_object_unref(resolver);
130 /* Attach purple's tls certificate handler in case tls is used */
131 purple_tls_certificate_attach_to_socket_client(client);
133 return client;