Extending test-client-custom-summary to try e_book_client_get_contacts_uids()
[platform/upstream/evolution-data-server.git] / camel / camel-tcp-stream.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  *  Authors: Jeffrey Stedfast <fejj@ximian.com>
4  *
5  *  Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2 of the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include "camel-debug.h"
30 #include "camel-tcp-stream.h"
31
32 #ifdef G_OS_WIN32
33 #include <winsock2.h>
34 #include <ws2tcpip.h>
35 #endif
36
37 #define w(x)
38
39 #define CAMEL_TCP_STREAM_GET_PRIVATE(obj) \
40         (G_TYPE_INSTANCE_GET_PRIVATE \
41         ((obj), CAMEL_TYPE_TCP_STREAM, CamelTcpStreamPrivate))
42
43 struct _CamelTcpStreamPrivate {
44         gchar *socks_host;
45         gint socks_port;
46 };
47
48 G_DEFINE_TYPE (CamelTcpStream, camel_tcp_stream, CAMEL_TYPE_STREAM)
49
50 static void
51 camel_tcp_stream_finalize (GObject *object)
52 {
53         CamelTcpStream *stream = CAMEL_TCP_STREAM (object);
54
55         g_free (stream->priv->socks_host);
56
57         /* Chain up to parent's finalize() method. */
58         G_OBJECT_CLASS (camel_tcp_stream_parent_class)->finalize (object);
59 }
60
61 static void
62 camel_tcp_stream_class_init (CamelTcpStreamClass *class)
63 {
64         GObjectClass *object_class;
65
66         g_type_class_add_private (class, sizeof (CamelTcpStreamPrivate));
67
68         object_class = G_OBJECT_CLASS (class);
69         object_class->finalize = camel_tcp_stream_finalize;
70 }
71
72 static void
73 camel_tcp_stream_init (CamelTcpStream *tcp_stream)
74 {
75         tcp_stream->priv = CAMEL_TCP_STREAM_GET_PRIVATE (tcp_stream);
76 }
77
78 /**
79  * camel_tcp_stream_connect:
80  * @stream: a #CamelTcpStream object
81  * @host: Hostname for connection
82  * @service: Service name or port number in string form
83  * @fallback_port: Port number to retry if @service is not present
84  * in the system's services database, or 0 to avoid retrying
85  * @cancellable: optional #GCancellable object, or %NULL
86  * @error: return location for a #GError, or %NULL
87  *
88  * Create a socket and connect based upon the data provided.
89  *
90  * Returns: %0 on success or %-1 on fail
91  **/
92 gint
93 camel_tcp_stream_connect (CamelTcpStream *stream,
94                           const gchar *host,
95                           const gchar *service,
96                           gint fallback_port,
97                           GCancellable *cancellable,
98                           GError **error)
99 {
100         CamelTcpStreamClass *class;
101         gint retval;
102
103         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), -1);
104         g_return_val_if_fail (host != NULL, -1);
105         g_return_val_if_fail (service != NULL, -1);
106         g_return_val_if_fail (error == NULL || *error == NULL, -1);
107
108         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
109         g_return_val_if_fail (class->connect != NULL, -1);
110
111         retval = class->connect (
112                 stream, host, service, fallback_port, cancellable, error);
113         CAMEL_CHECK_GERROR (stream, connect, retval == 0, error);
114
115         return retval;
116 }
117
118 /**
119  * camel_tcp_stream_getsockopt:
120  * @stream: a #CamelTcpStream object
121  * @data: socket option data
122  *
123  * Get the socket options set on the stream and populate @data.
124  *
125  * Returns: %0 on success or %-1 on fail
126  **/
127 gint
128 camel_tcp_stream_getsockopt (CamelTcpStream *stream,
129                              CamelSockOptData *data)
130 {
131         CamelTcpStreamClass *class;
132
133         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), -1);
134
135         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
136         g_return_val_if_fail (class->getsockopt != NULL, -1);
137
138         return class->getsockopt (stream, data);
139 }
140
141 /**
142  * camel_tcp_stream_setsockopt:
143  * @stream: a #CamelTcpStream object
144  * @data: socket option data
145  *
146  * Set the socket options contained in @data on the stream.
147  *
148  * Returns: %0 on success or %-1 on fail
149  **/
150 gint
151 camel_tcp_stream_setsockopt (CamelTcpStream *stream,
152                              const CamelSockOptData *data)
153 {
154         CamelTcpStreamClass *class;
155
156         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), -1);
157
158         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
159         g_return_val_if_fail (class->setsockopt != NULL, -1);
160
161         return class->setsockopt (stream, data);
162 }
163
164 /**
165  * camel_tcp_stream_get_local_address:
166  * @stream: a #CamelTcpStream object
167  * @len: pointer to address length which must be supplied
168  *
169  * Get the local address of @stream.
170  *
171  * Returns: the stream's local address (which must be freed with
172  * g_free()) if the stream is connected, or %NULL if not
173  *
174  * Since: 2.22
175  **/
176 struct sockaddr *
177 camel_tcp_stream_get_local_address (CamelTcpStream *stream,
178                                     socklen_t *len)
179 {
180         CamelTcpStreamClass *class;
181
182         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL);
183         g_return_val_if_fail (len != NULL, NULL);
184
185         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
186         g_return_val_if_fail (class->get_local_address != NULL, NULL);
187
188         return class->get_local_address (stream, len);
189 }
190
191 /**
192  * camel_tcp_stream_get_remote_address:
193  * @stream: a #CamelTcpStream object
194  * @len: pointer to address length, which must be supplied
195  *
196  * Get the remote address of @stream.
197  *
198  * Returns: the stream's remote address (which must be freed with
199  * g_free()) if the stream is connected, or %NULL if not.
200  *
201  * Since: 2.22
202  **/
203 struct sockaddr *
204 camel_tcp_stream_get_remote_address (CamelTcpStream *stream,
205                                      socklen_t *len)
206 {
207         CamelTcpStreamClass *class;
208
209         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL);
210         g_return_val_if_fail (len != NULL, NULL);
211
212         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
213         g_return_val_if_fail (class->get_remote_address != NULL, NULL);
214
215         return class->get_remote_address (stream, len);
216 }
217
218 /**
219  * camel_tcp_stream_get_file_desc:
220  * @stream: a #CamelTcpStream
221  *
222  * Since: 2.32
223  **/
224 PRFileDesc *
225 camel_tcp_stream_get_file_desc (CamelTcpStream *stream)
226 {
227         CamelTcpStreamClass *class;
228
229         g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL);
230
231         class = CAMEL_TCP_STREAM_GET_CLASS (stream);
232         g_return_val_if_fail (class->get_file_desc != NULL, NULL);
233
234         return class->get_file_desc (stream);
235 }
236
237 /**
238  * camel_tcp_stream_set_socks_proxy:
239  * @stream: a #CamelTcpStream object
240  * @socks_host: hostname to use for the SOCKS proxy
241  * @socks_port: port number to use for the SOCKS proxy
242  *
243  * Configures a SOCKS proxy for the specified @stream.  Instead of
244  * direct connections, this @stream will instead go through the proxy.
245  *
246  * Since: 2.32
247  */
248 void
249 camel_tcp_stream_set_socks_proxy (CamelTcpStream *stream,
250                                   const gchar *socks_host,
251                                   gint socks_port)
252 {
253         g_return_if_fail (CAMEL_IS_TCP_STREAM (stream));
254
255         g_free (stream->priv->socks_host);
256
257         if (socks_host != NULL && socks_host[0] != '\0') {
258                 stream->priv->socks_host = g_strdup (socks_host);
259                 stream->priv->socks_port = socks_port;
260         } else {
261                 stream->priv->socks_host = NULL;
262                 stream->priv->socks_port = 0;
263         }
264 }
265
266 /**
267  * camel_tcp_stream_peek_socks_proxy:
268  * @stream: a #CamelTcpStream
269  * @socks_host_ret: location to return the name of the SOCKS host
270  * @socks_port_ret: location to return the port number in the SOCKS host
271  *
272  * Queries the SOCKS proxy that is configured for a @stream.  This will
273  * return %NULL in @socks_host_ret if no proxy is configured.
274  *
275  * Since: 2.32
276  */
277 void
278 camel_tcp_stream_peek_socks_proxy (CamelTcpStream *stream,
279                                    const gchar **socks_host_ret,
280                                    gint *socks_port_ret)
281 {
282         g_return_if_fail (CAMEL_IS_TCP_STREAM (stream));
283
284         if (socks_host_ret != NULL)
285                 *socks_host_ret = stream->priv->socks_host;
286
287         if (socks_port_ret != NULL)
288                 *socks_port_ret = stream->priv->socks_port;
289 }